]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexCPP.cxx
b6358ab3328a955401678b72d455d674dedb40ee
[wxWidgets.git] / 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 for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
23 s[i] = styler[start + i];
24 s[i + 1] = '\0';
25 }
26 bool wordIsUUID = false;
27 char chAttr = SCE_C_IDENTIFIER;
28 if (isdigit(s[0]) || (s[0] == '.'))
29 chAttr = SCE_C_NUMBER;
30 else {
31 if (keywords.InList(s)) {
32 chAttr = SCE_C_WORD;
33 wordIsUUID = strcmp(s, "uuid") == 0;
34 }
35 }
36 styler.ColourTo(end, chAttr);
37 return wordIsUUID;
38 }
39
40 static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
41 Accessor &styler) {
42
43 WordList &keywords = *keywordlists[0];
44
45 styler.StartAt(startPos);
46
47 bool fold = styler.GetPropertyInt("fold");
48 bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor");
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 visibleChars = 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 // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
68 // Avoid triggering two times on Dos/Win
69 // End of line
70 if (state == SCE_C_STRINGEOL) {
71 styler.ColourTo(i, state);
72 state = SCE_C_DEFAULT;
73 }
74 if (fold) {
75 int lev = levelPrev;
76 if (visibleChars == 0)
77 lev |= SC_FOLDLEVELWHITEFLAG;
78 if ((levelCurrent > levelPrev) && (visibleChars > 0))
79 lev |= SC_FOLDLEVELHEADERFLAG;
80 styler.SetLevel(lineCurrent, lev);
81 lineCurrent++;
82 levelPrev = levelCurrent;
83 }
84 visibleChars = 0;
85 }
86 if (!isspace(ch))
87 visibleChars++;
88
89 if (styler.IsLeadByte(ch)) {
90 chNext = styler.SafeGetCharAt(i + 2);
91 chPrev = ' ';
92 i += 1;
93 continue;
94 }
95
96 if (state == SCE_C_DEFAULT) {
97 if (ch == '@' && chNext == '\"') {
98 styler.ColourTo(i-1, state);
99 state = SCE_C_VERBATIM;
100 i++;
101 ch = chNext;
102 chNext = styler.SafeGetCharAt(i + 1);
103 } else if (iswordstart(ch) || (ch == '@')) {
104 styler.ColourTo(i-1, state);
105 if (lastWordWasUUID) {
106 state = SCE_C_UUID;
107 lastWordWasUUID = false;
108 } else {
109 state = SCE_C_IDENTIFIER;
110 }
111 } else if (ch == '/' && chNext == '*') {
112 styler.ColourTo(i-1, state);
113 if (styler.SafeGetCharAt(i + 2) == '*')
114 state = SCE_C_COMMENTDOC;
115 else
116 state = SCE_C_COMMENT;
117 } else if (ch == '/' && chNext == '/') {
118 styler.ColourTo(i-1, state);
119 state = SCE_C_COMMENTLINE;
120 } else if (ch == '\"') {
121 styler.ColourTo(i-1, state);
122 state = SCE_C_STRING;
123 } else if (ch == '\'') {
124 styler.ColourTo(i-1, state);
125 state = SCE_C_CHARACTER;
126 } else if (ch == '#' && visibleChars == 1) {
127 // Preprocessor commands are alone on their line
128 styler.ColourTo(i-1, state);
129 state = SCE_C_PREPROCESSOR;
130 // Skip whitespace between # and preprocessor word
131 do {
132 i++;
133 ch = chNext;
134 chNext = styler.SafeGetCharAt(i + 1);
135 } while (isspace(ch) && (i < lengthDoc));
136 } else if (isoperator(ch)) {
137 styler.ColourTo(i-1, state);
138 styler.ColourTo(i, SCE_C_OPERATOR);
139 if ((ch == '{') || (ch == '}')) {
140 levelCurrent += (ch == '{') ? 1 : -1;
141 }
142 }
143 } else if (state == SCE_C_IDENTIFIER) {
144 if (!iswordchar(ch)) {
145 lastWordWasUUID = classifyWordCpp(styler.GetStartSegment(), i - 1, keywords, styler);
146 state = SCE_C_DEFAULT;
147 if (ch == '/' && chNext == '*') {
148 if (styler.SafeGetCharAt(i + 2) == '*')
149 state = SCE_C_COMMENTDOC;
150 else
151 state = SCE_C_COMMENT;
152 } else if (ch == '/' && chNext == '/') {
153 state = SCE_C_COMMENTLINE;
154 } else if (ch == '\"') {
155 state = SCE_C_STRING;
156 } else if (ch == '\'') {
157 state = SCE_C_CHARACTER;
158 } else if (isoperator(ch)) {
159 styler.ColourTo(i, SCE_C_OPERATOR);
160 if ((ch == '{') || (ch == '}')) {
161 levelCurrent += (ch == '{') ? 1 : -1;
162 }
163 }
164 }
165 } else {
166 if (state == SCE_C_PREPROCESSOR) {
167 if (stylingWithinPreprocessor) {
168 if (isspace(ch)) {
169 styler.ColourTo(i-1, state);
170 state = SCE_C_DEFAULT;
171 }
172 } else {
173 if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
174 styler.ColourTo(i-1, state);
175 state = SCE_C_DEFAULT;
176 }
177 }
178 } else if (state == SCE_C_COMMENT) {
179 if (ch == '/' && chPrev == '*') {
180 if (((i > styler.GetStartSegment() + 2) || (
181 (initStyle == SCE_C_COMMENT) &&
182 (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
183 styler.ColourTo(i, state);
184 state = SCE_C_DEFAULT;
185 }
186 }
187 } else if (state == SCE_C_COMMENTDOC) {
188 if (ch == '/' && chPrev == '*') {
189 if (((i > styler.GetStartSegment() + 2) || (
190 (initStyle == SCE_C_COMMENTDOC) &&
191 (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
192 styler.ColourTo(i, state);
193 state = SCE_C_DEFAULT;
194 }
195 }
196 } else if (state == SCE_C_COMMENTLINE) {
197 if (ch == '\r' || ch == '\n') {
198 styler.ColourTo(i-1, state);
199 state = SCE_C_DEFAULT;
200 }
201 } else if (state == SCE_C_STRING) {
202 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 } else if (chNext == '\r' || chNext == '\n') {
212 styler.ColourTo(i-1, SCE_C_STRINGEOL);
213 state = SCE_C_STRINGEOL;
214 }
215 } else if (state == SCE_C_CHARACTER) {
216 if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
217 styler.ColourTo(i-1, SCE_C_STRINGEOL);
218 state = SCE_C_STRINGEOL;
219 } else if (ch == '\\') {
220 if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
221 i++;
222 ch = chNext;
223 chNext = styler.SafeGetCharAt(i + 1);
224 }
225 } else if (ch == '\'') {
226 styler.ColourTo(i, state);
227 state = SCE_C_DEFAULT;
228 }
229 } else if (state == SCE_C_VERBATIM) {
230 if (ch == '\"') {
231 if (chNext == '\"') {
232 i++;
233 ch = chNext;
234 chNext = styler.SafeGetCharAt(i + 1);
235 } else {
236 styler.ColourTo(i, state);
237 state = SCE_C_DEFAULT;
238 }
239 }
240 } else if (state == SCE_C_UUID) {
241 if (ch == '\r' || ch == '\n' || ch == ')') {
242 styler.ColourTo(i-1, state);
243 if (ch == ')')
244 styler.ColourTo(i, SCE_C_OPERATOR);
245 state = SCE_C_DEFAULT;
246 }
247 }
248 }
249 chPrev = ch;
250 }
251 styler.ColourTo(lengthDoc - 1, state);
252
253 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
254 if (fold) {
255 int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
256 //styler.SetLevel(lineCurrent, levelCurrent | flagsNext);
257 styler.SetLevel(lineCurrent, levelPrev | flagsNext);
258
259 }
260 }
261
262 LexerModule lmCPP(SCLEX_CPP, ColouriseCppDoc);