~ubuntu-branches/ubuntu/quantal/mysql-workbench/quantal

« back to all changes in this revision

Viewing changes to ext/scintilla/lexers/LexSpice.cxx

  • Committer: Package Import Robot
  • Author(s): Dmitry Smirnov
  • Date: 2012-03-01 21:57:30 UTC
  • Revision ID: package-import@ubuntu.com-20120301215730-o7y8av8y38n162ro
Tags: upstream-5.2.38+dfsg
ImportĀ upstreamĀ versionĀ 5.2.38+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Scintilla source code edit control
 
2
/** @file LexSpice.cxx
 
3
 ** Lexer for Spice
 
4
 **/
 
5
// Copyright 2006 by Fabien Proriol
 
6
// The License.txt file describes the conditions under which this software may be distributed.
 
7
 
 
8
#include <stdlib.h>
 
9
#include <string.h>
 
10
#include <stdio.h>
 
11
#include <stdarg.h>
 
12
#include <assert.h>
 
13
 
 
14
#include <string>
 
15
 
 
16
#include "ILexer.h"
 
17
#include "Scintilla.h"
 
18
#include "SciLexer.h"
 
19
 
 
20
#include "WordList.h"
 
21
#include "LexAccessor.h"
 
22
#include "Accessor.h"
 
23
#include "StyleContext.h"
 
24
#include "CharacterSet.h"
 
25
#include "LexerModule.h"
 
26
 
 
27
#ifdef SCI_NAMESPACE
 
28
using namespace Scintilla;
 
29
#endif
 
30
 
 
31
/*
 
32
 * Interface
 
33
 */
 
34
 
 
35
static void ColouriseDocument(
 
36
    unsigned int startPos,
 
37
    int length,
 
38
    int initStyle,
 
39
    WordList *keywordlists[],
 
40
    Accessor &styler);
 
41
 
 
42
static const char * const spiceWordListDesc[] = {
 
43
    "Keywords",        // SPICE command
 
44
    "Keywords2",    // SPICE functions
 
45
    "Keywords3",    // SPICE params
 
46
    0
 
47
};
 
48
 
 
49
LexerModule lmSpice(SCLEX_SPICE, ColouriseDocument, "spice", NULL, spiceWordListDesc);
 
50
 
 
51
/*
 
52
 * Implementation
 
53
 */
 
54
 
 
55
static void ColouriseComment(StyleContext& sc, bool& apostropheStartsAttribute);
 
56
static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute);
 
57
static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute);
 
58
static void ColouriseWhiteSpace(StyleContext& sc, bool& apostropheStartsAttribute);
 
59
static void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute);
 
60
 
 
61
static inline bool IsDelimiterCharacter(int ch);
 
62
static inline bool IsNumberStartCharacter(int ch);
 
63
static inline bool IsNumberCharacter(int ch);
 
64
static inline bool IsSeparatorOrDelimiterCharacter(int ch);
 
65
static inline bool IsWordStartCharacter(int ch);
 
66
static inline bool IsWordCharacter(int ch);
 
67
 
 
68
static void ColouriseComment(StyleContext& sc, bool&) {
 
69
    sc.SetState(SCE_SPICE_COMMENTLINE);
 
70
    while (!sc.atLineEnd) {
 
71
        sc.Forward();
 
72
    }
 
73
}
 
74
 
 
75
static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute) {
 
76
    apostropheStartsAttribute = sc.Match (')');
 
77
    sc.SetState(SCE_SPICE_DELIMITER);
 
78
    sc.ForwardSetState(SCE_SPICE_DEFAULT);
 
79
}
 
80
 
 
81
static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) {
 
82
    apostropheStartsAttribute = true;
 
83
    std::string number;
 
84
    sc.SetState(SCE_SPICE_NUMBER);
 
85
    // Get all characters up to a delimiter or a separator, including points, but excluding
 
86
    // double points (ranges).
 
87
    while (!IsSeparatorOrDelimiterCharacter(sc.ch) || (sc.ch == '.' && sc.chNext != '.')) {
 
88
        number += static_cast<char>(sc.ch);
 
89
        sc.Forward();
 
90
    }
 
91
    // Special case: exponent with sign
 
92
    if ((sc.chPrev == 'e' || sc.chPrev == 'E') &&
 
93
            (sc.ch == '+' || sc.ch == '-')) {
 
94
        number += static_cast<char>(sc.ch);
 
95
        sc.Forward ();
 
96
        while (!IsSeparatorOrDelimiterCharacter(sc.ch)) {
 
97
            number += static_cast<char>(sc.ch);
 
98
            sc.Forward();
 
99
        }
 
100
    }
 
101
    sc.SetState(SCE_SPICE_DEFAULT);
 
102
}
 
103
 
 
104
static void ColouriseWhiteSpace(StyleContext& sc, bool& ) {
 
105
    sc.SetState(SCE_SPICE_DEFAULT);
 
106
    sc.ForwardSetState(SCE_SPICE_DEFAULT);
 
107
}
 
108
 
 
109
static void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute) {
 
110
    apostropheStartsAttribute = true;
 
111
    sc.SetState(SCE_SPICE_IDENTIFIER);
 
112
    std::string word;
 
113
    while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
 
114
        word += static_cast<char>(tolower(sc.ch));
 
115
        sc.Forward();
 
116
    }
 
117
    if (keywords.InList(word.c_str())) {
 
118
        sc.ChangeState(SCE_SPICE_KEYWORD);
 
119
        if (word != "all") {
 
120
            apostropheStartsAttribute = false;
 
121
        }
 
122
    }
 
123
    else if (keywords2.InList(word.c_str())) {
 
124
        sc.ChangeState(SCE_SPICE_KEYWORD2);
 
125
        if (word != "all") {
 
126
            apostropheStartsAttribute = false;
 
127
        }
 
128
    }
 
129
    else if (keywords3.InList(word.c_str())) {
 
130
        sc.ChangeState(SCE_SPICE_KEYWORD3);
 
131
        if (word != "all") {
 
132
            apostropheStartsAttribute = false;
 
133
        }
 
134
    }
 
135
    sc.SetState(SCE_SPICE_DEFAULT);
 
136
}
 
137
 
 
138
//
 
139
// ColouriseDocument
 
140
//
 
141
static void ColouriseDocument(
 
142
    unsigned int startPos,
 
143
    int length,
 
144
    int initStyle,
 
145
    WordList *keywordlists[],
 
146
    Accessor &styler) {
 
147
    WordList &keywords = *keywordlists[0];
 
148
    WordList &keywords2 = *keywordlists[1];
 
149
    WordList &keywords3 = *keywordlists[2];
 
150
    StyleContext sc(startPos, length, initStyle, styler);
 
151
    int lineCurrent = styler.GetLine(startPos);
 
152
    bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0;
 
153
    while (sc.More()) {
 
154
        if (sc.atLineEnd) {
 
155
            // Go to the next line
 
156
            sc.Forward();
 
157
            lineCurrent++;
 
158
            // Remember the line state for future incremental lexing
 
159
            styler.SetLineState(lineCurrent, apostropheStartsAttribute);
 
160
            // Don't continue any styles on the next line
 
161
            sc.SetState(SCE_SPICE_DEFAULT);
 
162
        }
 
163
        // Comments
 
164
        if ((sc.Match('*') && sc.atLineStart) || sc.Match('*','~')) {
 
165
            ColouriseComment(sc, apostropheStartsAttribute);
 
166
        // Whitespace
 
167
        } else if (IsASpace(sc.ch)) {
 
168
            ColouriseWhiteSpace(sc, apostropheStartsAttribute);
 
169
        // Delimiters
 
170
        } else if (IsDelimiterCharacter(sc.ch)) {
 
171
            ColouriseDelimiter(sc, apostropheStartsAttribute);
 
172
        // Numbers
 
173
        } else if (IsADigit(sc.ch) || sc.ch == '#') {
 
174
            ColouriseNumber(sc, apostropheStartsAttribute);
 
175
        // Keywords or identifiers
 
176
        } else {
 
177
            ColouriseWord(sc, keywords, keywords2, keywords3, apostropheStartsAttribute);
 
178
        }
 
179
    }
 
180
    sc.Complete();
 
181
}
 
182
 
 
183
static inline bool IsDelimiterCharacter(int ch) {
 
184
    switch (ch) {
 
185
    case '&':
 
186
    case '\'':
 
187
    case '(':
 
188
    case ')':
 
189
    case '*':
 
190
    case '+':
 
191
    case ',':
 
192
    case '-':
 
193
    case '.':
 
194
    case '/':
 
195
    case ':':
 
196
    case ';':
 
197
    case '<':
 
198
    case '=':
 
199
    case '>':
 
200
    case '|':
 
201
        return true;
 
202
    default:
 
203
        return false;
 
204
    }
 
205
}
 
206
 
 
207
static inline bool IsNumberCharacter(int ch) {
 
208
    return IsNumberStartCharacter(ch) ||
 
209
           ch == '_' ||
 
210
           ch == '.' ||
 
211
           ch == '#' ||
 
212
           (ch >= 'a' && ch <= 'f') ||
 
213
           (ch >= 'A' && ch <= 'F');
 
214
}
 
215
 
 
216
static inline bool IsNumberStartCharacter(int ch) {
 
217
    return IsADigit(ch);
 
218
}
 
219
 
 
220
static inline bool IsSeparatorOrDelimiterCharacter(int ch) {
 
221
    return IsASpace(ch) || IsDelimiterCharacter(ch);
 
222
}
 
223
 
 
224
static inline bool IsWordCharacter(int ch) {
 
225
    return IsWordStartCharacter(ch) || IsADigit(ch);
 
226
}
 
227
 
 
228
static inline bool IsWordStartCharacter(int ch) {
 
229
    return (isascii(ch) && isalpha(ch)) || ch == '_';
 
230
}