1 // Scintilla source code edit control
5 // Copyright 2006 by Fabien Proriol
6 // The License.txt file describes the conditions under which this software may be distributed.
16 #include "StyleContext.h"
26 static void ColouriseDocument(
27 unsigned int startPos
,
30 WordList
*keywordlists
[],
33 static const char * const spiceWordListDesc
[] = {
34 "Keywords", // SPICE command
35 "Keywords2", // SPICE functions
36 "Keywords3", // SPICE params
40 LexerModule
lmSpice(SCLEX_SPICE
, ColouriseDocument
, "spice", NULL
, spiceWordListDesc
);
46 static void ColouriseComment(StyleContext
& sc
, bool& apostropheStartsAttribute
);
47 static void ColouriseDelimiter(StyleContext
& sc
, bool& apostropheStartsAttribute
);
48 static void ColouriseNumber(StyleContext
& sc
, bool& apostropheStartsAttribute
);
49 static void ColouriseWhiteSpace(StyleContext
& sc
, bool& apostropheStartsAttribute
);
50 static void ColouriseWord(StyleContext
& sc
, WordList
& keywords
, WordList
& keywords2
, WordList
& keywords3
, bool& apostropheStartsAttribute
);
52 static inline bool IsDelimiterCharacter(int ch
);
53 static inline bool IsNumberStartCharacter(int ch
);
54 static inline bool IsNumberCharacter(int ch
);
55 static inline bool IsSeparatorOrDelimiterCharacter(int ch
);
56 static inline bool IsWordStartCharacter(int ch
);
57 static inline bool IsWordCharacter(int ch
);
59 static void ColouriseComment(StyleContext
& sc
, bool&) {
60 sc
.SetState(SCE_SPICE_COMMENTLINE
);
61 while (!sc
.atLineEnd
) {
66 static void ColouriseDelimiter(StyleContext
& sc
, bool& apostropheStartsAttribute
) {
67 apostropheStartsAttribute
= sc
.Match (')');
68 sc
.SetState(SCE_SPICE_DELIMITER
);
69 sc
.ForwardSetState(SCE_SPICE_DEFAULT
);
72 static void ColouriseNumber(StyleContext
& sc
, bool& apostropheStartsAttribute
) {
73 apostropheStartsAttribute
= true;
75 sc
.SetState(SCE_SPICE_NUMBER
);
76 // Get all characters up to a delimiter or a separator, including points, but excluding
77 // double points (ranges).
78 while (!IsSeparatorOrDelimiterCharacter(sc
.ch
) || (sc
.ch
== '.' && sc
.chNext
!= '.')) {
79 number
+= static_cast<char>(sc
.ch
);
82 // Special case: exponent with sign
83 if ((sc
.chPrev
== 'e' || sc
.chPrev
== 'E') &&
84 (sc
.ch
== '+' || sc
.ch
== '-')) {
85 number
+= static_cast<char>(sc
.ch
);
87 while (!IsSeparatorOrDelimiterCharacter(sc
.ch
)) {
88 number
+= static_cast<char>(sc
.ch
);
92 sc
.SetState(SCE_SPICE_DEFAULT
);
95 static void ColouriseWhiteSpace(StyleContext
& sc
, bool& ) {
96 sc
.SetState(SCE_SPICE_DEFAULT
);
97 sc
.ForwardSetState(SCE_SPICE_DEFAULT
);
100 static void ColouriseWord(StyleContext
& sc
, WordList
& keywords
, WordList
& keywords2
, WordList
& keywords3
, bool& apostropheStartsAttribute
) {
101 apostropheStartsAttribute
= true;
102 sc
.SetState(SCE_SPICE_IDENTIFIER
);
104 while (!sc
.atLineEnd
&& !IsSeparatorOrDelimiterCharacter(sc
.ch
)) {
105 word
+= static_cast<char>(tolower(sc
.ch
));
108 if (keywords
.InList(word
.c_str())) {
109 sc
.ChangeState(SCE_SPICE_KEYWORD
);
111 apostropheStartsAttribute
= false;
114 else if (keywords2
.InList(word
.c_str())) {
115 sc
.ChangeState(SCE_SPICE_KEYWORD2
);
117 apostropheStartsAttribute
= false;
120 else if (keywords3
.InList(word
.c_str())) {
121 sc
.ChangeState(SCE_SPICE_KEYWORD3
);
123 apostropheStartsAttribute
= false;
126 sc
.SetState(SCE_SPICE_DEFAULT
);
132 static void ColouriseDocument(
133 unsigned int startPos
,
136 WordList
*keywordlists
[],
138 WordList
&keywords
= *keywordlists
[0];
139 WordList
&keywords2
= *keywordlists
[1];
140 WordList
&keywords3
= *keywordlists
[2];
141 StyleContext
sc(startPos
, length
, initStyle
, styler
);
142 int lineCurrent
= styler
.GetLine(startPos
);
143 bool apostropheStartsAttribute
= (styler
.GetLineState(lineCurrent
) & 1) != 0;
146 // Go to the next line
149 // Remember the line state for future incremental lexing
150 styler
.SetLineState(lineCurrent
, apostropheStartsAttribute
);
151 // Don't continue any styles on the next line
152 sc
.SetState(SCE_SPICE_DEFAULT
);
155 if ((sc
.Match('*') && sc
.atLineStart
) || sc
.Match('*','~')) {
156 ColouriseComment(sc
, apostropheStartsAttribute
);
158 } else if (IsASpace(sc
.ch
)) {
159 ColouriseWhiteSpace(sc
, apostropheStartsAttribute
);
161 } else if (IsDelimiterCharacter(sc
.ch
)) {
162 ColouriseDelimiter(sc
, apostropheStartsAttribute
);
164 } else if (IsADigit(sc
.ch
) || sc
.ch
== '#') {
165 ColouriseNumber(sc
, apostropheStartsAttribute
);
166 // Keywords or identifiers
168 ColouriseWord(sc
, keywords
, keywords2
, keywords3
, apostropheStartsAttribute
);
174 static inline bool IsDelimiterCharacter(int ch
) {
198 static inline bool IsNumberCharacter(int ch
) {
199 return IsNumberStartCharacter(ch
) ||
203 (ch
>= 'a' && ch
<= 'f') ||
204 (ch
>= 'A' && ch
<= 'F');
207 static inline bool IsNumberStartCharacter(int ch
) {
211 static inline bool IsSeparatorOrDelimiterCharacter(int ch
) {
212 return IsASpace(ch
) || IsDelimiterCharacter(ch
);
215 static inline bool IsWordCharacter(int ch
) {
216 return IsWordStartCharacter(ch
) || IsADigit(ch
);
219 static inline bool IsWordStartCharacter(int ch
) {
220 return (isascii(ch
) && isalpha(ch
)) || ch
== '_';