]> git.saurik.com Git - wxWidgets.git/blob - contrib/src/stc/scintilla/src/LexCPP.cxx
4f042bd61dd82f077177bf0a008c82371f063c82
[wxWidgets.git] / contrib / src / stc / scintilla / src / LexCPP.cxx
1 // SciTE - Scintilla based Text Editor
2 // LexCPP.cxx - lexer for C++, C, Java, and Javascript
3 // Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
4 // The License.txt file describes the conditions under which this software may be distributed.
5
6 #include <stdlib.h>
7 #include <string.h>
8 #include <ctype.h>
9 #include <stdio.h>
10 #include <stdarg.h>
11
12 #include "Platform.h"
13
14 #include "PropSet.h"
15 #include "Accessor.h"
16 #include "KeyWords.h"
17 #include "Scintilla.h"
18 #include "SciLexer.h"
19
20 static bool classifyWordCpp(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
21 char s[100];
22 bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
23 bool wordIsUUID = false;
24 for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
25 s[i] = styler[start + i];
26 s[i + 1] = '\0';
27 }
28 char chAttr = SCE_C_IDENTIFIER;
29 if (wordIsNumber)
30 chAttr = SCE_C_NUMBER;
31 else {
32 if (keywords.InList(s)) {
33 chAttr = SCE_C_WORD;
34 wordIsUUID = strcmp(s, "uuid") == 0;
35 }
36 }
37 styler.ColourTo(end, chAttr);
38 return wordIsUUID;
39 }
40
41 static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
42 Accessor &styler) {
43
44 WordList &keywords = *keywordlists[0];
45
46 styler.StartAt(startPos);
47
48 bool fold = styler.GetPropertyInt("fold");
49 int lineCurrent = styler.GetLine(startPos);
50 int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
51 int levelCurrent = levelPrev;
52
53 int state = initStyle;
54 if (state == SCE_C_STRINGEOL) // Does not leak onto next line
55 state = SCE_C_DEFAULT;
56 char chPrev = ' ';
57 char chNext = styler[startPos];
58 unsigned int lengthDoc = startPos + length;
59 int visChars = 0;
60 styler.StartSegment(startPos);
61 bool lastWordWasUUID = false;
62 for (unsigned int i = startPos; i < lengthDoc; i++) {
63 char ch = chNext;
64 chNext = styler.SafeGetCharAt(i + 1);
65
66 if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
67 // End of line
68 if (state == SCE_C_STRINGEOL) {
69 styler.ColourTo(i, state);
70 state = SCE_C_DEFAULT;
71 }
72 if (fold) {
73 int lev = levelPrev;
74 if (visChars == 0)
75 lev |= SC_FOLDLEVELWHITEFLAG;
76 if ((levelCurrent > levelPrev) && (visChars > 0))
77 lev |= SC_FOLDLEVELHEADERFLAG;
78 styler.SetLevel(lineCurrent, lev);
79 lineCurrent++;
80 visChars = 0;
81 levelPrev = levelCurrent;
82 }
83 }
84 if (!isspace(ch))
85 visChars++;
86
87 if (styler.IsLeadByte(ch)) {
88 chNext = styler.SafeGetCharAt(i + 2);
89 chPrev = ' ';
90 i += 1;
91 continue;
92 }
93
94 if (state == SCE_C_DEFAULT) {
95 if (iswordstart(ch)) {
96 styler.ColourTo(i-1, state);
97 if (lastWordWasUUID) {
98 state = SCE_C_UUID;
99 lastWordWasUUID = false;
100 } else {
101 state = SCE_C_WORD;
102 }
103 } else if (ch == '/' && chNext == '*') {
104 styler.ColourTo(i-1, state);
105 if (styler.SafeGetCharAt(i + 2) == '*')
106 state = SCE_C_COMMENTDOC;
107 else
108 state = SCE_C_COMMENT;
109 } else if (ch == '/' && chNext == '/') {
110 styler.ColourTo(i-1, state);
111 state = SCE_C_COMMENTLINE;
112 } else if (ch == '\"') {
113 styler.ColourTo(i-1, state);
114 state = SCE_C_STRING;
115 } else if (ch == '\'') {
116 styler.ColourTo(i-1, state);
117 state = SCE_C_CHARACTER;
118 } else if (ch == '#') {
119 styler.ColourTo(i-1, state);
120 state = SCE_C_PREPROCESSOR;
121 } else if (isoperator(ch)) {
122 styler.ColourTo(i-1, state);
123 styler.ColourTo(i, SCE_C_OPERATOR);
124 if ((ch == '{') || (ch == '}')) {
125 levelCurrent += (ch == '{') ? 1 : -1;
126 }
127 }
128 } else if (state == SCE_C_WORD) {
129 if (!iswordchar(ch)) {
130 lastWordWasUUID = classifyWordCpp(styler.GetStartSegment(), i - 1, keywords, styler);
131 state = SCE_C_DEFAULT;
132 if (ch == '/' && chNext == '*') {
133 if (styler.SafeGetCharAt(i + 2) == '*')
134 state = SCE_C_COMMENTDOC;
135 else
136 state = SCE_C_COMMENT;
137 } else if (ch == '/' && chNext == '/') {
138 state = SCE_C_COMMENTLINE;
139 } else if (ch == '\"') {
140 state = SCE_C_STRING;
141 } else if (ch == '\'') {
142 state = SCE_C_CHARACTER;
143 } else if (ch == '#') {
144 state = SCE_C_PREPROCESSOR;
145 } else if (isoperator(ch)) {
146 styler.ColourTo(i, SCE_C_OPERATOR);
147 if ((ch == '{') || (ch == '}')) {
148 levelCurrent += (ch == '{') ? 1 : -1;
149 }
150 }
151 }
152 } else {
153 if (state == SCE_C_PREPROCESSOR) {
154 if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
155 styler.ColourTo(i-1, state);
156 state = SCE_C_DEFAULT;
157 }
158 } else if (state == SCE_C_COMMENT) {
159 if (ch == '/' && chPrev == '*') {
160 if (((i > styler.GetStartSegment() + 2) || (
161 (initStyle == SCE_C_COMMENT) &&
162 (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
163 styler.ColourTo(i, state);
164 state = SCE_C_DEFAULT;
165 }
166 }
167 } else if (state == SCE_C_COMMENTDOC) {
168 if (ch == '/' && chPrev == '*') {
169 if (((i > styler.GetStartSegment() + 2) || (
170 (initStyle == SCE_C_COMMENTDOC) &&
171 (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
172 styler.ColourTo(i, state);
173 state = SCE_C_DEFAULT;
174 }
175 }
176 } else if (state == SCE_C_COMMENTLINE) {
177 if (ch == '\r' || ch == '\n') {
178 styler.ColourTo(i-1, state);
179 state = SCE_C_DEFAULT;
180 }
181 } else if (state == SCE_C_STRING) {
182 if (ch == '\\') {
183 if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
184 i++;
185 ch = chNext;
186 chNext = styler.SafeGetCharAt(i + 1);
187 }
188 } else if (ch == '\"') {
189 styler.ColourTo(i, state);
190 state = SCE_C_DEFAULT;
191 i++;
192 ch = chNext;
193 chNext = styler.SafeGetCharAt(i + 1);
194 } else if (chNext == '\r' || chNext == '\n') {
195 styler.ColourTo(i-1, SCE_C_STRINGEOL);
196 state = SCE_C_STRINGEOL;
197 }
198 } else if (state == SCE_C_CHARACTER) {
199 if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
200 styler.ColourTo(i-1, SCE_C_STRINGEOL);
201 state = SCE_C_STRINGEOL;
202 } else if (ch == '\\') {
203 if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
204 i++;
205 ch = chNext;
206 chNext = styler.SafeGetCharAt(i + 1);
207 }
208 } else if (ch == '\'') {
209 styler.ColourTo(i, state);
210 state = SCE_C_DEFAULT;
211 i++;
212 ch = chNext;
213 chNext = styler.SafeGetCharAt(i + 1);
214 }
215 } else if (state == SCE_C_UUID) {
216 if (ch == '\r' || ch == '\n' || ch == ')') {
217 styler.ColourTo(i-1, state);
218 state = SCE_C_DEFAULT;
219 }
220 }
221 if (state == SCE_C_DEFAULT) { // One of the above succeeded
222 if (ch == '/' && chNext == '*') {
223 if (styler.SafeGetCharAt(i + 2) == '*')
224 state = SCE_C_COMMENTDOC;
225 else
226 state = SCE_C_COMMENT;
227 } else if (ch == '/' && chNext == '/') {
228 state = SCE_C_COMMENTLINE;
229 } else if (ch == '\"') {
230 state = SCE_C_STRING;
231 } else if (ch == '\'') {
232 state = SCE_C_CHARACTER;
233 } else if (ch == '#') {
234 state = SCE_C_PREPROCESSOR;
235 } else if (iswordstart(ch)) {
236 state = SCE_C_WORD;
237 } else if (isoperator(ch)) {
238 styler.ColourTo(i, SCE_C_OPERATOR);
239 if ((ch == '{') || (ch == '}')) {
240 levelCurrent += (ch == '{') ? 1 : -1;
241 }
242 }
243 }
244 }
245 chPrev = ch;
246 }
247 styler.ColourTo(lengthDoc - 1, state);
248
249 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
250 if (fold) {
251 int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
252 //styler.SetLevel(lineCurrent, levelCurrent | flagsNext);
253 styler.SetLevel(lineCurrent, levelPrev | flagsNext);
254
255 }
256 }
257
258 LexerModule lmCPP(SCLEX_CPP, ColouriseCppDoc);