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