]> git.saurik.com Git - wxWidgets.git/blame - src/stc/scintilla/lexers/LexScriptol.cxx
wxMessageBox off the main thread lost result code.
[wxWidgets.git] / src / stc / scintilla / lexers / LexScriptol.cxx
CommitLineData
88a8b04e
RD
1// Scintilla source code edit control
2/** @file LexScriptol.cxx
3 ** Lexer for Scriptol.
4 **/
5
6#include <stdlib.h>
7#include <string.h>
88a8b04e
RD
8#include <stdio.h>
9#include <stdarg.h>
1dcf666d
RD
10#include <assert.h>
11#include <ctype.h>
88a8b04e 12
1dcf666d 13#include "ILexer.h"
88a8b04e
RD
14#include "Scintilla.h"
15#include "SciLexer.h"
7e0c58e9 16
1dcf666d
RD
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
7e0c58e9
RD
24#ifdef SCI_NAMESPACE
25using namespace Scintilla;
26#endif
88a8b04e
RD
27
28static void ClassifyWordSol(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord)
29{
8e54aaed
RD
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;
88a8b04e
RD
41 else for (unsigned int i = 0; i < end - start + 1; i++) // test dotted idents
42 {
8e54aaed 43 if (styler[start + i] == '.')
88a8b04e 44 {
8e54aaed
RD
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);
88a8b04e
RD
51}
52
53static bool IsSolComment(Accessor &styler, int pos, int len)
54{
88a8b04e
RD
55 if(len > 0)
56 {
1dcf666d 57 char c = styler[pos];
88a8b04e
RD
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
8e54aaed 72static bool IsSolStringStart(char ch)
88a8b04e
RD
73{
74 if (ch == '\'' || ch == '"') return true;
8e54aaed 75 return false;
88a8b04e
RD
76}
77
8e54aaed 78static bool IsSolWordStart(char ch)
88a8b04e 79{
8e54aaed 80 return (iswordchar(ch) && !IsSolStringStart(ch));
88a8b04e
RD
81}
82
8e54aaed 83
88a8b04e
RD
84static int GetSolStringState(Accessor &styler, int i, int *nextIndex)
85{
86 char ch = styler.SafeGetCharAt(i);
87 char chNext = styler.SafeGetCharAt(i + 1);
88
8e54aaed
RD
89 if (ch != '\"' && ch != '\'')
90 {
91 *nextIndex = i + 1;
92 return SCE_SCRIPTOL_DEFAULT;
88a8b04e 93 }
8e54aaed
RD
94 // ch is either single or double quotes in string
95 // code below seem non-sense but is here for future extensions
88a8b04e 96 if (ch == chNext && ch == styler.SafeGetCharAt(i + 2))
8e54aaed
RD
97 {
98 *nextIndex = i + 3;
99 if(ch == '\"') return SCE_SCRIPTOL_TRIPLE;
100 if(ch == '\'') return SCE_SCRIPTOL_TRIPLE;
101 return SCE_SCRIPTOL_STRING;
88a8b04e 102 }
8e54aaed
RD
103 else
104 {
105 *nextIndex = i + 1;
106 if (ch == '"') return SCE_SCRIPTOL_STRING;
107 else return SCE_SCRIPTOL_STRING;
88a8b04e
RD
108 }
109}
110
8e54aaed 111
88a8b04e 112static void ColouriseSolDoc(unsigned int startPos, int length, int initStyle,
8e54aaed 113 WordList *keywordlists[], Accessor &styler)
88a8b04e
RD
114 {
115
116 int lengthDoc = startPos + length;
8e54aaed 117 char stringType = '\"';
88a8b04e 118
88a8b04e 119 if (startPos > 0)
88a8b04e 120 {
8e54aaed
RD
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 }
88a8b04e
RD
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';
8e54aaed 137 if (length == 0) return;
88a8b04e
RD
138
139 int state = initStyle & 31;
140
141 int nextIndex = 0;
8e54aaed
RD
142 char chPrev = ' ';
143 char chPrev2 = ' ';
144 char chNext = styler[startPos];
88a8b04e
RD
145 styler.StartSegment(startPos);
146 bool atStartLine = true;
147 int spaceFlags = 0;
148 for (int i = startPos; i < lengthDoc; i++)
8e54aaed 149 {
88a8b04e 150
8e54aaed
RD
151 if (atStartLine)
152 {
88a8b04e
RD
153 char chBad = static_cast<char>(64);
154 char chGood = static_cast<char>(0);
155 char chFlags = chGood;
156
157 if (whingeLevel == 1)
158 {
8e54aaed 159 chFlags = (spaceFlags & wsInconsistent) ? chBad : chGood;
88a8b04e
RD
160 }
161 else if (whingeLevel == 2)
162 {
8e54aaed 163 chFlags = (spaceFlags & wsSpaceTab) ? chBad : chGood;
88a8b04e
RD
164 }
165 else if (whingeLevel == 3)
166 {
8e54aaed 167 chFlags = (spaceFlags & wsSpace) ? chBad : chGood;
88a8b04e
RD
168 }
169 else if (whingeLevel == 4)
170 {
8e54aaed 171 chFlags = (spaceFlags & wsTab) ? chBad : chGood;
88a8b04e
RD
172 }
173 styler.SetFlags(chFlags, static_cast<char>(state));
174 atStartLine = false;
175 }
176
8e54aaed
RD
177 char ch = chNext;
178 chNext = styler.SafeGetCharAt(i + 1);
88a8b04e 179
8e54aaed
RD
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 }
88a8b04e 190
8e54aaed
RD
191 if (styler.IsLeadByte(ch))
192 {
193 chNext = styler.SafeGetCharAt(i + 2);
194 chPrev = ' ';
195 chPrev2 = ' ';
196 i += 1;
197 continue;
198 }
88a8b04e 199
8e54aaed
RD
200 if (state == SCE_SCRIPTOL_STRINGEOL)
201 {
202 if (ch != '\r' && ch != '\n')
88a8b04e 203 {
8e54aaed
RD
204 styler.ColourTo(i - 1, state);
205 state = SCE_SCRIPTOL_DEFAULT;
88a8b04e 206 }
8e54aaed 207 }
88a8b04e 208
8e54aaed
RD
209 if (state == SCE_SCRIPTOL_DEFAULT)
210 {
211 if (IsSolWordStart(ch))
88a8b04e 212 {
8e54aaed
RD
213 styler.ColourTo(i - 1, state);
214 state = SCE_SCRIPTOL_KEYWORD;
88a8b04e
RD
215 }
216 else if (ch == '`')
217 {
8e54aaed
RD
218 styler.ColourTo(i - 1, state);
219 state = SCE_SCRIPTOL_COMMENTLINE;
88a8b04e
RD
220 }
221 else if (ch == '/')
222 {
8e54aaed
RD
223 styler.ColourTo(i - 1, state);
224 if(chNext == '/') state = SCE_SCRIPTOL_CSTYLE;
225 if(chNext == '*') state = SCE_SCRIPTOL_COMMENTBLOCK;
88a8b04e
RD
226 }
227
8e54aaed 228 else if (IsSolStringStart(ch))
88a8b04e
RD
229 {
230 styler.ColourTo(i - 1, state);
231 state = GetSolStringState(styler, i, &nextIndex);
8e54aaed
RD
232 if(state == SCE_SCRIPTOL_STRING)
233 {
234 stringType = ch;
235 }
88a8b04e
RD
236 if (nextIndex != i + 1)
237 {
8e54aaed
RD
238 i = nextIndex - 1;
239 ch = ' ';
240 chPrev = ' ';
241 chNext = styler.SafeGetCharAt(i + 1);
88a8b04e 242 }
8e54aaed 243 }
88a8b04e
RD
244 else if (isoperator(ch))
245 {
8e54aaed
RD
246 styler.ColourTo(i - 1, state);
247 styler.ColourTo(i, SCE_SCRIPTOL_OPERATOR);
248 }
88a8b04e 249 }
8e54aaed 250 else if (state == SCE_SCRIPTOL_KEYWORD)
88a8b04e
RD
251 {
252 if (!iswordchar(ch))
253 {
254 ClassifyWordSol(styler.GetStartSegment(), i - 1, keywords, styler, prevWord);
8e54aaed 255 state = SCE_SCRIPTOL_DEFAULT;
88a8b04e
RD
256 if (ch == '`')
257 {
8e54aaed 258 state = chNext == '`' ? SCE_SCRIPTOL_PERSISTENT : SCE_SCRIPTOL_COMMENTLINE;
88a8b04e 259 }
8e54aaed 260 else if (IsSolStringStart(ch))
88a8b04e
RD
261 {
262 styler.ColourTo(i - 1, state);
263 state = GetSolStringState(styler, i, &nextIndex);
8e54aaed 264 if (nextIndex != i + 1)
88a8b04e 265 {
8e54aaed
RD
266 i = nextIndex - 1;
267 ch = ' ';
268 chPrev = ' ';
269 chNext = styler.SafeGetCharAt(i + 1);
270 }
88a8b04e
RD
271 }
272 else if (isoperator(ch))
273 {
8e54aaed 274 styler.ColourTo(i, SCE_SCRIPTOL_OPERATOR);
88a8b04e
RD
275 }
276 }
277 }
278 else
279 {
8e54aaed
RD
280 if (state == SCE_SCRIPTOL_COMMENTLINE ||
281 state == SCE_SCRIPTOL_PERSISTENT ||
282 state == SCE_SCRIPTOL_CSTYLE)
88a8b04e 283 {
8e54aaed 284 if (ch == '\r' || ch == '\n')
88a8b04e 285 {
8e54aaed
RD
286 styler.ColourTo(i - 1, state);
287 state = SCE_SCRIPTOL_DEFAULT;
88a8b04e
RD
288 }
289 }
8e54aaed 290 else if(state == SCE_SCRIPTOL_COMMENTBLOCK)
88a8b04e 291 {
8e54aaed
RD
292 if(chPrev == '*' && ch == '/')
293 {
294 styler.ColourTo(i, state);
295 state = SCE_SCRIPTOL_DEFAULT;
296 }
88a8b04e 297 }
8e54aaed
RD
298 else if ((state == SCE_SCRIPTOL_STRING) ||
299 (state == SCE_SCRIPTOL_CHARACTER))
88a8b04e 300 {
8e54aaed 301 if ((ch == '\r' || ch == '\n') && (chPrev != '\\'))
88a8b04e 302 {
8e54aaed
RD
303 styler.ColourTo(i - 1, state);
304 state = SCE_SCRIPTOL_STRINGEOL;
305 }
88a8b04e
RD
306 else if (ch == '\\')
307 {
308 if (chNext == '\"' || chNext == '\'' || chNext == '\\')
309 {
8e54aaed
RD
310 i++;
311 ch = chNext;
312 chNext = styler.SafeGetCharAt(i + 1);
88a8b04e 313 }
88a8b04e 314 }
8e54aaed 315 else if ((ch == '\"') || (ch == '\''))
88a8b04e 316 {
8e54aaed
RD
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)
88a8b04e 326 {
8e54aaed
RD
327 if ((ch == '\'' && chPrev == '\'' && chPrev2 == '\'') ||
328 (ch == '\"' && chPrev == '\"' && chPrev2 == '\"'))
88a8b04e
RD
329 {
330 styler.ColourTo(i, state);
8e54aaed 331 state = SCE_SCRIPTOL_DEFAULT;
88a8b04e 332 }
8e54aaed 333 }
1dcf666d 334
8e54aaed
RD
335 }
336 chPrev2 = chPrev;
337 chPrev = ch;
88a8b04e 338 }
8e54aaed
RD
339 if (state == SCE_SCRIPTOL_KEYWORD)
340 {
341 ClassifyWordSol(styler.GetStartSegment(),
342 lengthDoc-1, keywords, styler, prevWord);
88a8b04e 343 }
8e54aaed
RD
344 else
345 {
346 styler.ColourTo(lengthDoc-1, state);
88a8b04e
RD
347 }
348}
349
350static void FoldSolDoc(unsigned int startPos, int length, int initStyle,
351 WordList *[], Accessor &styler)
352 {
353 int lengthDoc = startPos + length;
354
88a8b04e 355 int lineCurrent = styler.GetLine(startPos);
8e54aaed 356 if (startPos > 0)
88a8b04e 357 {
8e54aaed
RD
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 }
88a8b04e
RD
367 }
368 int state = initStyle & 31;
369 int spaceFlags = 0;
370 int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsSolComment);
1dcf666d 371 if (state == SCE_SCRIPTOL_TRIPLE)
8e54aaed 372 indentCurrent |= SC_FOLDLEVELWHITEFLAG;
88a8b04e
RD
373 char chNext = styler[startPos];
374 for (int i = startPos; i < lengthDoc; i++)
8e54aaed 375 {
88a8b04e
RD
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))
88a8b04e 381 {
8e54aaed
RD
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))
88a8b04e 387 {
8e54aaed
RD
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++;
88a8b04e
RD
407 }
408 }
409}
410
411LexerModule lmScriptol(SCLEX_SCRIPTOL, ColouriseSolDoc, "scriptol", FoldSolDoc);