]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexCPP.cxx
3199322ba35a6eafc7837906c0a55ceeaef72600
[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, StylingContext &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 StylingContext &styler) {
43
44 WordList &keywords = *keywordlists[0];
45
46 styler.StartAt(startPos);
47
48 bool fold = styler.GetPropSet().GetInt("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 char chPrev = ' ';
55 char chNext = styler[startPos];
56 unsigned int lengthDoc = startPos + length;
57 int visChars = 0;
58 styler.StartSegment(startPos);
59 bool lastWordWasUUID = false;
60 for (unsigned int i = startPos; i <= lengthDoc; i++) {
61 char ch = chNext;
62 chNext = styler.SafeGetCharAt(i + 1);
63
64 if ((fold) && ((ch == '\r' && chNext != '\n') || (ch == '\n'))) {
65 int lev = levelPrev;
66 if (visChars == 0)
67 lev |= SC_FOLDLEVELWHITEFLAG;
68 if ((levelCurrent > levelPrev) && (visChars > 0))
69 lev |= SC_FOLDLEVELHEADERFLAG;
70 styler.SetLevel(lineCurrent, lev);
71 lineCurrent++;
72 visChars = 0;
73 levelPrev = levelCurrent;
74 }
75 if (!isspace(ch))
76 visChars++;
77
78 if (styler.IsLeadByte(ch)) {
79 chNext = styler.SafeGetCharAt(i + 2);
80 chPrev = ' ';
81 i += 1;
82 continue;
83 }
84
85 if (state == SCE_C_STRINGEOL) {
86 if (ch != '\r' && ch != '\n') {
87 styler.ColourTo(i-1, state);
88 state = SCE_C_DEFAULT;
89 }
90 }
91 if (state == SCE_C_DEFAULT) {
92 if (iswordstart(ch)) {
93 styler.ColourTo(i-1, state);
94 if (lastWordWasUUID) {
95 state = SCE_C_UUID;
96 lastWordWasUUID = false;
97 } else {
98 state = SCE_C_WORD;
99 }
100 } else if (ch == '/' && chNext == '*') {
101 styler.ColourTo(i-1, state);
102 if (styler.SafeGetCharAt(i + 2) == '*')
103 state = SCE_C_COMMENTDOC;
104 else
105 state = SCE_C_COMMENT;
106 } else if (ch == '/' && chNext == '/') {
107 styler.ColourTo(i-1, state);
108 state = SCE_C_COMMENTLINE;
109 } else if (ch == '\"') {
110 styler.ColourTo(i-1, state);
111 state = SCE_C_STRING;
112 } else if (ch == '\'') {
113 styler.ColourTo(i-1, state);
114 state = SCE_C_CHARACTER;
115 } else if (ch == '#') {
116 styler.ColourTo(i-1, state);
117 state = SCE_C_PREPROCESSOR;
118 } else if (isoperator(ch)) {
119 styler.ColourTo(i-1, state);
120 styler.ColourTo(i, SCE_C_OPERATOR);
121 if ((ch == '{') || (ch == '}')) {
122 levelCurrent += (ch == '{') ? 1 : -1;
123 }
124 }
125 } else if (state == SCE_C_WORD) {
126 if (!iswordchar(ch)) {
127 lastWordWasUUID = classifyWordCpp(styler.GetStartSegment(), i - 1, keywords, styler);
128 state = SCE_C_DEFAULT;
129 if (ch == '/' && chNext == '*') {
130 if (styler.SafeGetCharAt(i + 2) == '*')
131 state = SCE_C_COMMENTDOC;
132 else
133 state = SCE_C_COMMENT;
134 } else if (ch == '/' && chNext == '/') {
135 state = SCE_C_COMMENTLINE;
136 } else if (ch == '\"') {
137 state = SCE_C_STRING;
138 } else if (ch == '\'') {
139 state = SCE_C_CHARACTER;
140 } else if (ch == '#') {
141 state = SCE_C_PREPROCESSOR;
142 } else if (isoperator(ch)) {
143 styler.ColourTo(i, SCE_C_OPERATOR);
144 if ((ch == '{') || (ch == '}')) {
145 levelCurrent += (ch == '{') ? 1 : -1;
146 }
147 }
148 }
149 } else {
150 if (state == SCE_C_PREPROCESSOR) {
151 if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
152 styler.ColourTo(i-1, state);
153 state = SCE_C_DEFAULT;
154 }
155 } else if (state == SCE_C_COMMENT) {
156 if (ch == '/' && chPrev == '*') {
157 if (((i > styler.GetStartSegment() + 2) || (
158 (initStyle == SCE_C_COMMENT) &&
159 (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
160 styler.ColourTo(i, state);
161 state = SCE_C_DEFAULT;
162 }
163 }
164 } else if (state == SCE_C_COMMENTDOC) {
165 if (ch == '/' && chPrev == '*') {
166 if (((i > styler.GetStartSegment() + 3) || (
167 (initStyle == SCE_C_COMMENTDOC) &&
168 (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
169 styler.ColourTo(i, state);
170 state = SCE_C_DEFAULT;
171 }
172 }
173 } else if (state == SCE_C_COMMENTLINE) {
174 if (ch == '\r' || ch == '\n') {
175 styler.ColourTo(i-1, state);
176 state = SCE_C_DEFAULT;
177 }
178 } else if (state == SCE_C_STRING) {
179 if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
180 styler.ColourTo(i-1, state);
181 state = SCE_C_STRINGEOL;
182 } else 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 }
195 } else if (state == SCE_C_CHARACTER) {
196 if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
197 styler.ColourTo(i-1, state);
198 state = SCE_C_STRINGEOL;
199 } else if (ch == '\\') {
200 if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
201 i++;
202 ch = chNext;
203 chNext = styler.SafeGetCharAt(i + 1);
204 }
205 } else if (ch == '\'') {
206 styler.ColourTo(i, state);
207 state = SCE_C_DEFAULT;
208 i++;
209 ch = chNext;
210 chNext = styler.SafeGetCharAt(i + 1);
211 }
212 } else if (state == SCE_C_UUID) {
213 if (ch == '\r' || ch == '\n' || ch == ')') {
214 styler.ColourTo(i-1, state);
215 state = SCE_C_DEFAULT;
216 }
217 }
218 if (state == SCE_C_DEFAULT) { // One of the above succeeded
219 if (ch == '/' && chNext == '*') {
220 if (styler.SafeGetCharAt(i + 2) == '*')
221 state = SCE_C_COMMENTDOC;
222 else
223 state = SCE_C_COMMENT;
224 } else if (ch == '/' && chNext == '/') {
225 state = SCE_C_COMMENTLINE;
226 } else if (ch == '\"') {
227 state = SCE_C_STRING;
228 } else if (ch == '\'') {
229 state = SCE_C_CHARACTER;
230 } else if (ch == '#') {
231 state = SCE_C_PREPROCESSOR;
232 } else if (iswordstart(ch)) {
233 state = SCE_C_WORD;
234 } else if (isoperator(ch)) {
235 styler.ColourTo(i, SCE_C_OPERATOR);
236 if ((ch == '{') || (ch == '}')) {
237 levelCurrent += (ch == '{') ? 1 : -1;
238 }
239 }
240 }
241 }
242 chPrev = ch;
243 }
244 styler.ColourTo(lengthDoc - 1, state);
245
246 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
247 if (fold) {
248 int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
249 //styler.SetLevel(lineCurrent, levelCurrent | flagsNext);
250 styler.SetLevel(lineCurrent, levelPrev | flagsNext);
251
252 }
253 }
254
255 LexerModule lmCPP(SCLEX_CPP, ColouriseCppDoc);