]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/lexers/LexScriptol.cxx
simplify code so it always returns the same object
[wxWidgets.git] / src / stc / scintilla / lexers / LexScriptol.cxx
1 // Scintilla source code edit control
2 /** @file LexScriptol.cxx
3 ** Lexer for Scriptol.
4 **/
5
6 #include <stdlib.h>
7 #include <string.h>
8 #include <stdio.h>
9 #include <stdarg.h>
10 #include <assert.h>
11 #include <ctype.h>
12
13 #include "ILexer.h"
14 #include "Scintilla.h"
15 #include "SciLexer.h"
16
17 #include "WordList.h"
18 #include "LexAccessor.h"
19 #include "Accessor.h"
20 #include "StyleContext.h"
21 #include "CharacterSet.h"
22 #include "LexerModule.h"
23
24 #ifdef SCI_NAMESPACE
25 using namespace Scintilla;
26 #endif
27
28 static void ClassifyWordSol(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord)
29 {
30 char s[100];
31 bool wordIsNumber = isdigit(styler[start]) != 0;
32 for (unsigned int i = 0; i < end - start + 1 && i < 30; i++)
33 {
34 s[i] = styler[start + i];
35 s[i + 1] = '\0';
36 }
37 char chAttr = SCE_SCRIPTOL_IDENTIFIER;
38 if (0 == strcmp(prevWord, "class")) chAttr = SCE_SCRIPTOL_CLASSNAME;
39 else if (wordIsNumber) chAttr = SCE_SCRIPTOL_NUMBER;
40 else if (keywords.InList(s)) chAttr = SCE_SCRIPTOL_KEYWORD;
41 else for (unsigned int i = 0; i < end - start + 1; i++) // test dotted idents
42 {
43 if (styler[start + i] == '.')
44 {
45 styler.ColourTo(start + i - 1, chAttr);
46 styler.ColourTo(start + i, SCE_SCRIPTOL_OPERATOR);
47 }
48 }
49 styler.ColourTo(end, chAttr);
50 strcpy(prevWord, s);
51 }
52
53 static bool IsSolComment(Accessor &styler, int pos, int len)
54 {
55 if(len > 0)
56 {
57 char c = styler[pos];
58 if(c == '`') return true;
59 if(len > 1)
60 {
61 if(c == '/')
62 {
63 c = styler[pos + 1];
64 if(c == '/') return true;
65 if(c == '*') return true;
66 }
67 }
68 }
69 return false;
70 }
71
72 static bool IsSolStringStart(char ch)
73 {
74 if (ch == '\'' || ch == '"') return true;
75 return false;
76 }
77
78 static bool IsSolWordStart(char ch)
79 {
80 return (iswordchar(ch) && !IsSolStringStart(ch));
81 }
82
83
84 static int GetSolStringState(Accessor &styler, int i, int *nextIndex)
85 {
86 char ch = styler.SafeGetCharAt(i);
87 char chNext = styler.SafeGetCharAt(i + 1);
88
89 if (ch != '\"' && ch != '\'')
90 {
91 *nextIndex = i + 1;
92 return SCE_SCRIPTOL_DEFAULT;
93 }
94 // ch is either single or double quotes in string
95 // code below seem non-sense but is here for future extensions
96 if (ch == chNext && ch == styler.SafeGetCharAt(i + 2))
97 {
98 *nextIndex = i + 3;
99 if(ch == '\"') return SCE_SCRIPTOL_TRIPLE;
100 if(ch == '\'') return SCE_SCRIPTOL_TRIPLE;
101 return SCE_SCRIPTOL_STRING;
102 }
103 else
104 {
105 *nextIndex = i + 1;
106 if (ch == '"') return SCE_SCRIPTOL_STRING;
107 else return SCE_SCRIPTOL_STRING;
108 }
109 }
110
111
112 static void ColouriseSolDoc(unsigned int startPos, int length, int initStyle,
113 WordList *keywordlists[], Accessor &styler)
114 {
115
116 int lengthDoc = startPos + length;
117 char stringType = '\"';
118
119 if (startPos > 0)
120 {
121 int lineCurrent = styler.GetLine(startPos);
122 if (lineCurrent > 0)
123 {
124 startPos = styler.LineStart(lineCurrent-1);
125 if (startPos == 0) initStyle = SCE_SCRIPTOL_DEFAULT;
126 else initStyle = styler.StyleAt(startPos-1);
127 }
128 }
129
130 styler.StartAt(startPos, 127);
131
132 WordList &keywords = *keywordlists[0];
133
134 int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level");
135 char prevWord[200];
136 prevWord[0] = '\0';
137 if (length == 0) return;
138
139 int state = initStyle & 31;
140
141 int nextIndex = 0;
142 char chPrev = ' ';
143 char chPrev2 = ' ';
144 char chNext = styler[startPos];
145 styler.StartSegment(startPos);
146 bool atStartLine = true;
147 int spaceFlags = 0;
148 for (int i = startPos; i < lengthDoc; i++)
149 {
150
151 if (atStartLine)
152 {
153 char chBad = static_cast<char>(64);
154 char chGood = static_cast<char>(0);
155 char chFlags = chGood;
156
157 if (whingeLevel == 1)
158 {
159 chFlags = (spaceFlags & wsInconsistent) ? chBad : chGood;
160 }
161 else if (whingeLevel == 2)
162 {
163 chFlags = (spaceFlags & wsSpaceTab) ? chBad : chGood;
164 }
165 else if (whingeLevel == 3)
166 {
167 chFlags = (spaceFlags & wsSpace) ? chBad : chGood;
168 }
169 else if (whingeLevel == 4)
170 {
171 chFlags = (spaceFlags & wsTab) ? chBad : chGood;
172 }
173 styler.SetFlags(chFlags, static_cast<char>(state));
174 atStartLine = false;
175 }
176
177 char ch = chNext;
178 chNext = styler.SafeGetCharAt(i + 1);
179
180 if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc))
181 {
182 if ((state == SCE_SCRIPTOL_DEFAULT) ||
183 (state == SCE_SCRIPTOL_TRIPLE) ||
184 (state == SCE_SCRIPTOL_COMMENTBLOCK))
185 {
186 styler.ColourTo(i, state);
187 }
188 atStartLine = true;
189 }
190
191 if (styler.IsLeadByte(ch))
192 {
193 chNext = styler.SafeGetCharAt(i + 2);
194 chPrev = ' ';
195 chPrev2 = ' ';
196 i += 1;
197 continue;
198 }
199
200 if (state == SCE_SCRIPTOL_STRINGEOL)
201 {
202 if (ch != '\r' && ch != '\n')
203 {
204 styler.ColourTo(i - 1, state);
205 state = SCE_SCRIPTOL_DEFAULT;
206 }
207 }
208
209 if (state == SCE_SCRIPTOL_DEFAULT)
210 {
211 if (IsSolWordStart(ch))
212 {
213 styler.ColourTo(i - 1, state);
214 state = SCE_SCRIPTOL_KEYWORD;
215 }
216 else if (ch == '`')
217 {
218 styler.ColourTo(i - 1, state);
219 state = SCE_SCRIPTOL_COMMENTLINE;
220 }
221 else if (ch == '/')
222 {
223 styler.ColourTo(i - 1, state);
224 if(chNext == '/') state = SCE_SCRIPTOL_CSTYLE;
225 if(chNext == '*') state = SCE_SCRIPTOL_COMMENTBLOCK;
226 }
227
228 else if (IsSolStringStart(ch))
229 {
230 styler.ColourTo(i - 1, state);
231 state = GetSolStringState(styler, i, &nextIndex);
232 if(state == SCE_SCRIPTOL_STRING)
233 {
234 stringType = ch;
235 }
236 if (nextIndex != i + 1)
237 {
238 i = nextIndex - 1;
239 ch = ' ';
240 chPrev = ' ';
241 chNext = styler.SafeGetCharAt(i + 1);
242 }
243 }
244 else if (isoperator(ch))
245 {
246 styler.ColourTo(i - 1, state);
247 styler.ColourTo(i, SCE_SCRIPTOL_OPERATOR);
248 }
249 }
250 else if (state == SCE_SCRIPTOL_KEYWORD)
251 {
252 if (!iswordchar(ch))
253 {
254 ClassifyWordSol(styler.GetStartSegment(), i - 1, keywords, styler, prevWord);
255 state = SCE_SCRIPTOL_DEFAULT;
256 if (ch == '`')
257 {
258 state = chNext == '`' ? SCE_SCRIPTOL_PERSISTENT : SCE_SCRIPTOL_COMMENTLINE;
259 }
260 else if (IsSolStringStart(ch))
261 {
262 styler.ColourTo(i - 1, state);
263 state = GetSolStringState(styler, i, &nextIndex);
264 if (nextIndex != i + 1)
265 {
266 i = nextIndex - 1;
267 ch = ' ';
268 chPrev = ' ';
269 chNext = styler.SafeGetCharAt(i + 1);
270 }
271 }
272 else if (isoperator(ch))
273 {
274 styler.ColourTo(i, SCE_SCRIPTOL_OPERATOR);
275 }
276 }
277 }
278 else
279 {
280 if (state == SCE_SCRIPTOL_COMMENTLINE ||
281 state == SCE_SCRIPTOL_PERSISTENT ||
282 state == SCE_SCRIPTOL_CSTYLE)
283 {
284 if (ch == '\r' || ch == '\n')
285 {
286 styler.ColourTo(i - 1, state);
287 state = SCE_SCRIPTOL_DEFAULT;
288 }
289 }
290 else if(state == SCE_SCRIPTOL_COMMENTBLOCK)
291 {
292 if(chPrev == '*' && ch == '/')
293 {
294 styler.ColourTo(i, state);
295 state = SCE_SCRIPTOL_DEFAULT;
296 }
297 }
298 else if ((state == SCE_SCRIPTOL_STRING) ||
299 (state == SCE_SCRIPTOL_CHARACTER))
300 {
301 if ((ch == '\r' || ch == '\n') && (chPrev != '\\'))
302 {
303 styler.ColourTo(i - 1, state);
304 state = SCE_SCRIPTOL_STRINGEOL;
305 }
306 else if (ch == '\\')
307 {
308 if (chNext == '\"' || chNext == '\'' || chNext == '\\')
309 {
310 i++;
311 ch = chNext;
312 chNext = styler.SafeGetCharAt(i + 1);
313 }
314 }
315 else if ((ch == '\"') || (ch == '\''))
316 {
317 // must match the entered quote type
318 if(ch == stringType)
319 {
320 styler.ColourTo(i, state);
321 state = SCE_SCRIPTOL_DEFAULT;
322 }
323 }
324 }
325 else if (state == SCE_SCRIPTOL_TRIPLE)
326 {
327 if ((ch == '\'' && chPrev == '\'' && chPrev2 == '\'') ||
328 (ch == '\"' && chPrev == '\"' && chPrev2 == '\"'))
329 {
330 styler.ColourTo(i, state);
331 state = SCE_SCRIPTOL_DEFAULT;
332 }
333 }
334
335 }
336 chPrev2 = chPrev;
337 chPrev = ch;
338 }
339 if (state == SCE_SCRIPTOL_KEYWORD)
340 {
341 ClassifyWordSol(styler.GetStartSegment(),
342 lengthDoc-1, keywords, styler, prevWord);
343 }
344 else
345 {
346 styler.ColourTo(lengthDoc-1, state);
347 }
348 }
349
350 static void FoldSolDoc(unsigned int startPos, int length, int initStyle,
351 WordList *[], Accessor &styler)
352 {
353 int lengthDoc = startPos + length;
354
355 int lineCurrent = styler.GetLine(startPos);
356 if (startPos > 0)
357 {
358 if (lineCurrent > 0)
359 {
360 lineCurrent--;
361 startPos = styler.LineStart(lineCurrent);
362 if (startPos == 0)
363 initStyle = SCE_SCRIPTOL_DEFAULT;
364 else
365 initStyle = styler.StyleAt(startPos-1);
366 }
367 }
368 int state = initStyle & 31;
369 int spaceFlags = 0;
370 int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsSolComment);
371 if (state == SCE_SCRIPTOL_TRIPLE)
372 indentCurrent |= SC_FOLDLEVELWHITEFLAG;
373 char chNext = styler[startPos];
374 for (int i = startPos; i < lengthDoc; i++)
375 {
376 char ch = chNext;
377 chNext = styler.SafeGetCharAt(i + 1);
378 int style = styler.StyleAt(i) & 31;
379
380 if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc))
381 {
382 int lev = indentCurrent;
383 int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsSolComment);
384 if (style == SCE_SCRIPTOL_TRIPLE)
385 indentNext |= SC_FOLDLEVELWHITEFLAG;
386 if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG))
387 {
388 // Only non whitespace lines can be headers
389 if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
390 {
391 lev |= SC_FOLDLEVELHEADERFLAG;
392 }
393 else if (indentNext & SC_FOLDLEVELWHITEFLAG)
394 {
395 // Line after is blank so check the next - maybe should continue further?
396 int spaceFlags2 = 0;
397 int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsSolComment);
398 if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK))
399 {
400 lev |= SC_FOLDLEVELHEADERFLAG;
401 }
402 }
403 }
404 indentCurrent = indentNext;
405 styler.SetLevel(lineCurrent, lev);
406 lineCurrent++;
407 }
408 }
409 }
410
411 LexerModule lmScriptol(SCLEX_SCRIPTOL, ColouriseSolDoc, "scriptol", FoldSolDoc);