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.
18 #include "StyleContext.h"
24 using namespace Scintilla
;
31 static void ColouriseDocument(
32 unsigned int startPos
,
35 WordList
*keywordlists
[],
38 static const char * const spiceWordListDesc
[] = {
39 "Keywords", // SPICE command
40 "Keywords2", // SPICE functions
41 "Keywords3", // SPICE params
45 LexerModule
lmSpice(SCLEX_SPICE
, ColouriseDocument
, "spice", NULL
, spiceWordListDesc
);
51 static void ColouriseComment(StyleContext
& sc
, bool& apostropheStartsAttribute
);
52 static void ColouriseDelimiter(StyleContext
& sc
, bool& apostropheStartsAttribute
);
53 static void ColouriseNumber(StyleContext
& sc
, bool& apostropheStartsAttribute
);
54 static void ColouriseWhiteSpace(StyleContext
& sc
, bool& apostropheStartsAttribute
);
55 static void ColouriseWord(StyleContext
& sc
, WordList
& keywords
, WordList
& keywords2
, WordList
& keywords3
, bool& apostropheStartsAttribute
);
57 static inline bool IsDelimiterCharacter(int ch
);
58 static inline bool IsNumberStartCharacter(int ch
);
59 static inline bool IsNumberCharacter(int ch
);
60 static inline bool IsSeparatorOrDelimiterCharacter(int ch
);
61 static inline bool IsWordStartCharacter(int ch
);
62 static inline bool IsWordCharacter(int ch
);
64 static void ColouriseComment(StyleContext
& sc
, bool&) {
65 sc
.SetState(SCE_SPICE_COMMENTLINE
);
66 while (!sc
.atLineEnd
) {
71 static void ColouriseDelimiter(StyleContext
& sc
, bool& apostropheStartsAttribute
) {
72 apostropheStartsAttribute
= sc
.Match (')');
73 sc
.SetState(SCE_SPICE_DELIMITER
);
74 sc
.ForwardSetState(SCE_SPICE_DEFAULT
);
77 static void ColouriseNumber(StyleContext
& sc
, bool& apostropheStartsAttribute
) {
78 apostropheStartsAttribute
= true;
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
);
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
);
92 while (!IsSeparatorOrDelimiterCharacter(sc
.ch
)) {
93 number
+= static_cast<char>(sc
.ch
);
97 sc
.SetState(SCE_SPICE_DEFAULT
);
100 static void ColouriseWhiteSpace(StyleContext
& sc
, bool& ) {
101 sc
.SetState(SCE_SPICE_DEFAULT
);
102 sc
.ForwardSetState(SCE_SPICE_DEFAULT
);
105 static void ColouriseWord(StyleContext
& sc
, WordList
& keywords
, WordList
& keywords2
, WordList
& keywords3
, bool& apostropheStartsAttribute
) {
106 apostropheStartsAttribute
= true;
107 sc
.SetState(SCE_SPICE_IDENTIFIER
);
109 while (!sc
.atLineEnd
&& !IsSeparatorOrDelimiterCharacter(sc
.ch
)) {
110 word
+= static_cast<char>(tolower(sc
.ch
));
113 if (keywords
.InList(word
.c_str())) {
114 sc
.ChangeState(SCE_SPICE_KEYWORD
);
116 apostropheStartsAttribute
= false;
119 else if (keywords2
.InList(word
.c_str())) {
120 sc
.ChangeState(SCE_SPICE_KEYWORD2
);
122 apostropheStartsAttribute
= false;
125 else if (keywords3
.InList(word
.c_str())) {
126 sc
.ChangeState(SCE_SPICE_KEYWORD3
);
128 apostropheStartsAttribute
= false;
131 sc
.SetState(SCE_SPICE_DEFAULT
);
137 static void ColouriseDocument(
138 unsigned int startPos
,
141 WordList
*keywordlists
[],
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;
151 // Go to the next line
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
);
160 if ((sc
.Match('*') && sc
.atLineStart
) || sc
.Match('*','~')) {
161 ColouriseComment(sc
, apostropheStartsAttribute
);
163 } else if (IsASpace(sc
.ch
)) {
164 ColouriseWhiteSpace(sc
, apostropheStartsAttribute
);
166 } else if (IsDelimiterCharacter(sc
.ch
)) {
167 ColouriseDelimiter(sc
, apostropheStartsAttribute
);
169 } else if (IsADigit(sc
.ch
) || sc
.ch
== '#') {
170 ColouriseNumber(sc
, apostropheStartsAttribute
);
171 // Keywords or identifiers
173 ColouriseWord(sc
, keywords
, keywords2
, keywords3
, apostropheStartsAttribute
);
179 static inline bool IsDelimiterCharacter(int ch
) {
203 static inline bool IsNumberCharacter(int ch
) {
204 return IsNumberStartCharacter(ch
) ||
208 (ch
>= 'a' && ch
<= 'f') ||
209 (ch
>= 'A' && ch
<= 'F');
212 static inline bool IsNumberStartCharacter(int ch
) {
216 static inline bool IsSeparatorOrDelimiterCharacter(int ch
) {
217 return IsASpace(ch
) || IsDelimiterCharacter(ch
);
220 static inline bool IsWordCharacter(int ch
) {
221 return IsWordStartCharacter(ch
) || IsADigit(ch
);
224 static inline bool IsWordStartCharacter(int ch
) {
225 return (isascii(ch
) && isalpha(ch
)) || ch
== '_';