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"
23 using namespace Scintilla
;
30 static void ColouriseDocument(
31 unsigned int startPos
,
34 WordList
*keywordlists
[],
37 static const char * const spiceWordListDesc
[] = {
38 "Keywords", // SPICE command
39 "Keywords2", // SPICE functions
40 "Keywords3", // SPICE params
44 LexerModule
lmSpice(SCLEX_SPICE
, ColouriseDocument
, "spice", NULL
, spiceWordListDesc
);
50 static void ColouriseComment(StyleContext
& sc
, bool& apostropheStartsAttribute
);
51 static void ColouriseDelimiter(StyleContext
& sc
, bool& apostropheStartsAttribute
);
52 static void ColouriseNumber(StyleContext
& sc
, bool& apostropheStartsAttribute
);
53 static void ColouriseWhiteSpace(StyleContext
& sc
, bool& apostropheStartsAttribute
);
54 static void ColouriseWord(StyleContext
& sc
, WordList
& keywords
, WordList
& keywords2
, WordList
& keywords3
, bool& apostropheStartsAttribute
);
56 static inline bool IsDelimiterCharacter(int ch
);
57 static inline bool IsNumberStartCharacter(int ch
);
58 static inline bool IsNumberCharacter(int ch
);
59 static inline bool IsSeparatorOrDelimiterCharacter(int ch
);
60 static inline bool IsWordStartCharacter(int ch
);
61 static inline bool IsWordCharacter(int ch
);
63 static void ColouriseComment(StyleContext
& sc
, bool&) {
64 sc
.SetState(SCE_SPICE_COMMENTLINE
);
65 while (!sc
.atLineEnd
) {
70 static void ColouriseDelimiter(StyleContext
& sc
, bool& apostropheStartsAttribute
) {
71 apostropheStartsAttribute
= sc
.Match (')');
72 sc
.SetState(SCE_SPICE_DELIMITER
);
73 sc
.ForwardSetState(SCE_SPICE_DEFAULT
);
76 static void ColouriseNumber(StyleContext
& sc
, bool& apostropheStartsAttribute
) {
77 apostropheStartsAttribute
= true;
79 sc
.SetState(SCE_SPICE_NUMBER
);
80 // Get all characters up to a delimiter or a separator, including points, but excluding
81 // double points (ranges).
82 while (!IsSeparatorOrDelimiterCharacter(sc
.ch
) || (sc
.ch
== '.' && sc
.chNext
!= '.')) {
83 number
+= static_cast<char>(sc
.ch
);
86 // Special case: exponent with sign
87 if ((sc
.chPrev
== 'e' || sc
.chPrev
== 'E') &&
88 (sc
.ch
== '+' || sc
.ch
== '-')) {
89 number
+= static_cast<char>(sc
.ch
);
91 while (!IsSeparatorOrDelimiterCharacter(sc
.ch
)) {
92 number
+= static_cast<char>(sc
.ch
);
96 sc
.SetState(SCE_SPICE_DEFAULT
);
99 static void ColouriseWhiteSpace(StyleContext
& sc
, bool& ) {
100 sc
.SetState(SCE_SPICE_DEFAULT
);
101 sc
.ForwardSetState(SCE_SPICE_DEFAULT
);
104 static void ColouriseWord(StyleContext
& sc
, WordList
& keywords
, WordList
& keywords2
, WordList
& keywords3
, bool& apostropheStartsAttribute
) {
105 apostropheStartsAttribute
= true;
106 sc
.SetState(SCE_SPICE_IDENTIFIER
);
108 while (!sc
.atLineEnd
&& !IsSeparatorOrDelimiterCharacter(sc
.ch
)) {
109 word
+= static_cast<char>(tolower(sc
.ch
));
112 if (keywords
.InList(word
.c_str())) {
113 sc
.ChangeState(SCE_SPICE_KEYWORD
);
115 apostropheStartsAttribute
= false;
118 else if (keywords2
.InList(word
.c_str())) {
119 sc
.ChangeState(SCE_SPICE_KEYWORD2
);
121 apostropheStartsAttribute
= false;
124 else if (keywords3
.InList(word
.c_str())) {
125 sc
.ChangeState(SCE_SPICE_KEYWORD3
);
127 apostropheStartsAttribute
= false;
130 sc
.SetState(SCE_SPICE_DEFAULT
);
136 static void ColouriseDocument(
137 unsigned int startPos
,
140 WordList
*keywordlists
[],
142 WordList
&keywords
= *keywordlists
[0];
143 WordList
&keywords2
= *keywordlists
[1];
144 WordList
&keywords3
= *keywordlists
[2];
145 StyleContext
sc(startPos
, length
, initStyle
, styler
);
146 int lineCurrent
= styler
.GetLine(startPos
);
147 bool apostropheStartsAttribute
= (styler
.GetLineState(lineCurrent
) & 1) != 0;
150 // Go to the next line
153 // Remember the line state for future incremental lexing
154 styler
.SetLineState(lineCurrent
, apostropheStartsAttribute
);
155 // Don't continue any styles on the next line
156 sc
.SetState(SCE_SPICE_DEFAULT
);
159 if ((sc
.Match('*') && sc
.atLineStart
) || sc
.Match('*','~')) {
160 ColouriseComment(sc
, apostropheStartsAttribute
);
162 } else if (IsASpace(sc
.ch
)) {
163 ColouriseWhiteSpace(sc
, apostropheStartsAttribute
);
165 } else if (IsDelimiterCharacter(sc
.ch
)) {
166 ColouriseDelimiter(sc
, apostropheStartsAttribute
);
168 } else if (IsADigit(sc
.ch
) || sc
.ch
== '#') {
169 ColouriseNumber(sc
, apostropheStartsAttribute
);
170 // Keywords or identifiers
172 ColouriseWord(sc
, keywords
, keywords2
, keywords3
, apostropheStartsAttribute
);
178 static inline bool IsDelimiterCharacter(int ch
) {
202 static inline bool IsNumberCharacter(int ch
) {
203 return IsNumberStartCharacter(ch
) ||
207 (ch
>= 'a' && ch
<= 'f') ||
208 (ch
>= 'A' && ch
<= 'F');
211 static inline bool IsNumberStartCharacter(int ch
) {
215 static inline bool IsSeparatorOrDelimiterCharacter(int ch
) {
216 return IsASpace(ch
) || IsDelimiterCharacter(ch
);
219 static inline bool IsWordCharacter(int ch
) {
220 return IsWordStartCharacter(ch
) || IsADigit(ch
);
223 static inline bool IsWordStartCharacter(int ch
) {
224 return (isascii(ch
) && isalpha(ch
)) || ch
== '_';