]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexScriptol.cxx
fda10e316c61bea044cf1c55e4a9499290f557e2
[wxWidgets.git] / src / stc / scintilla / src / 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 <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 void ClassifyWordSol(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord)
21 {
22 char s[100];
23 bool wordIsNumber = isdigit(styler[start]) != 0;
24 for (unsigned int i = 0; i < end - start + 1 && i < 30; i++)
25 {
26 s[i] = styler[start + i];
27 s[i + 1] = '\0';
28 }
29 char chAttr = SCE_P_IDENTIFIER;
30 if (0 == strcmp(prevWord, "class")) chAttr = SCE_P_CLASSNAME;
31 else if (wordIsNumber) chAttr = SCE_P_NUMBER;
32 else if (keywords.InList(s)) chAttr = SCE_P_WORD;
33 else for (unsigned int i = 0; i < end - start + 1; i++) // test dotted idents
34 {
35 if (styler[start + i] == '.')
36 {
37 styler.ColourTo(start + i - 1, chAttr);
38 styler.ColourTo(start + i, SCE_P_OPERATOR);
39 }
40 }
41 styler.ColourTo(end, chAttr);
42 strcpy(prevWord, s);
43 }
44
45 static bool IsSolComment(Accessor &styler, int pos, int len)
46 {
47 // return len > 0 && styler[pos]=='`';
48 char c;
49 if(len > 0)
50 {
51 c = styler[pos];
52 if(c == '`') return true;
53 if(len > 1)
54 {
55 if(c == '/')
56 {
57 c = styler[pos + 1];
58 if(c == '/') return true;
59 if(c == '*') return true;
60 }
61 }
62 }
63 return false;
64 }
65
66 static bool IsSolStringStart(char ch, char /*chNext*/)
67 {
68 if (ch == '\'' || ch == '"') return true;
69 //chNext = chNext; // for future use
70
71 return false;
72 }
73
74 static bool IsSolWordStart(char ch, char chNext)
75 {
76 return (iswordchar(ch) && !IsSolStringStart(ch, chNext));
77 }
78
79 /* Return the state to use for the string starting at i; *nextIndex will be set to the first index following the quote(s) */
80 static int GetSolStringState(Accessor &styler, int i, int *nextIndex)
81 {
82 char ch = styler.SafeGetCharAt(i);
83 char chNext = styler.SafeGetCharAt(i + 1);
84
85 if (ch != '"' && ch != '\'') {
86 *nextIndex = i + 1;
87 return SCE_P_DEFAULT;
88 }
89
90 if (ch == chNext && ch == styler.SafeGetCharAt(i + 2))
91 {
92 *nextIndex = i + 3;
93 if (ch == '"') return SCE_P_TRIPLEDOUBLE;
94 else return SCE_P_TRIPLE;
95 }
96 else
97 {
98 *nextIndex = i + 1;
99 if (ch == '"') return SCE_P_STRING;
100 else return SCE_P_CHARACTER;
101 }
102 }
103
104 static void ColouriseSolDoc(unsigned int startPos, int length, int initStyle,
105 WordList *keywordlists[], Accessor &styler)
106 {
107
108 int lengthDoc = startPos + length;
109
110 // Backtrack to previous line in case need to fix its tab whinging
111 if (startPos > 0)
112 {
113 int lineCurrent = styler.GetLine(startPos);
114 if (lineCurrent > 0)
115 {
116 startPos = styler.LineStart(lineCurrent-1);
117 if (startPos == 0) initStyle = SCE_P_DEFAULT;
118 else initStyle = styler.StyleAt(startPos-1);
119 }
120 }
121
122 styler.StartAt(startPos, 127);
123
124 WordList &keywords = *keywordlists[0];
125
126 int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level");
127 char prevWord[200];
128 prevWord[0] = '\0';
129 if (length == 0) return ;
130
131 int state = initStyle & 31;
132
133 int nextIndex = 0;
134 char chPrev = ' ';
135 //char chPrev2 = ' ';
136 char chNext = styler[startPos];
137 styler.StartSegment(startPos);
138 bool atStartLine = true;
139 int spaceFlags = 0;
140 for (int i = startPos; i < lengthDoc; i++)
141 {
142
143 if (atStartLine)
144 {
145 char chBad = static_cast<char>(64);
146 char chGood = static_cast<char>(0);
147 char chFlags = chGood;
148
149 if (whingeLevel == 1)
150 {
151 chFlags = (spaceFlags & wsInconsistent) ? chBad : chGood;
152 }
153 else if (whingeLevel == 2)
154 {
155 chFlags = (spaceFlags & wsSpaceTab) ? chBad : chGood;
156 }
157 else if (whingeLevel == 3)
158 {
159 chFlags = (spaceFlags & wsSpace) ? chBad : chGood;
160 }
161 else if (whingeLevel == 4)
162 {
163 chFlags = (spaceFlags & wsTab) ? chBad : chGood;
164 }
165 styler.SetFlags(chFlags, static_cast<char>(state));
166 atStartLine = false;
167 }
168
169 char ch = chNext;
170 chNext = styler.SafeGetCharAt(i + 1);
171
172 if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc))
173 {
174 if ((state == SCE_P_DEFAULT) || (state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE))
175 {
176 styler.ColourTo(i, state);
177 }
178 atStartLine = true;
179 }
180
181 if (styler.IsLeadByte(ch))
182 {
183 chNext = styler.SafeGetCharAt(i + 2);
184 chPrev = ' ';
185 //chPrev2 = ' ';
186 i += 1;
187 continue;
188 }
189
190 if (state == SCE_P_STRINGEOL)
191 {
192 if (ch != '\r' && ch != '\n')
193 {
194 styler.ColourTo(i - 1, state);
195 state = SCE_P_DEFAULT;
196 }
197 }
198
199 if (state == SCE_P_DEFAULT)
200 {
201 if (IsSolWordStart(ch, chNext))
202 {
203 styler.ColourTo(i - 1, state);
204 state = SCE_P_WORD;
205 }
206 else if (ch == '`')
207 {
208 styler.ColourTo(i - 1, state);
209 state = SCE_P_COMMENTLINE;
210 }
211 else if (ch == '/')
212 {
213 styler.ColourTo(i - 1, state);
214 if(chNext == '/') state = SCE_P_COMMENTLINE;
215 if(chNext == '*') state = SCE_P_COMMENTBLOCK;
216 }
217
218 else if (ch == '=' && chNext == 'b')
219 {
220 // =begin indicates the start of a comment (doc) block
221 if(styler.SafeGetCharAt(i + 2) == 'e' && styler.SafeGetCharAt(i + 3) == 'g' && styler.SafeGetCharAt(i + 4) == 'i' && styler.SafeGetCharAt(i + 5) == 'n')
222 {
223 styler.ColourTo(i - 1, state);
224 state = SCE_P_TRIPLEDOUBLE; //SCE_C_COMMENT;
225 }
226 }
227 else if (IsSolStringStart(ch, chNext))
228 {
229 styler.ColourTo(i - 1, state);
230 state = GetSolStringState(styler, i, &nextIndex);
231 if (nextIndex != i + 1)
232 {
233 i = nextIndex - 1;
234 ch = ' ';
235 //chPrev = ' ';
236 chNext = styler.SafeGetCharAt(i + 1);
237 }
238 }
239 else if (isoperator(ch))
240 {
241 styler.ColourTo(i - 1, state);
242 styler.ColourTo(i, SCE_P_OPERATOR);
243 }
244 }
245 else if (state == SCE_P_WORD)
246 {
247 if (!iswordchar(ch))
248 {
249 ClassifyWordSol(styler.GetStartSegment(), i - 1, keywords, styler, prevWord);
250 state = SCE_P_DEFAULT;
251 if (ch == '`')
252 {
253 state = chNext == '`' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE;
254 }
255 else if (IsSolStringStart(ch, chNext))
256 {
257 styler.ColourTo(i - 1, state);
258 state = GetSolStringState(styler, i, &nextIndex);
259 if (nextIndex != i + 1)
260 {
261 i = nextIndex - 1;
262 ch = ' ';
263 //chPrev = ' ';
264 chNext = styler.SafeGetCharAt(i + 1);
265 }
266 }
267 else if (isoperator(ch))
268 {
269 styler.ColourTo(i, SCE_P_OPERATOR);
270 }
271 }
272 }
273 else
274 {
275 if (state == SCE_P_COMMENTLINE)
276 {
277 if (ch == '\r' || ch == '\n')
278 {
279 styler.ColourTo(i - 1, state);
280 state = SCE_P_DEFAULT;
281 }
282 }
283 else if(state == SCE_P_COMMENTBLOCK)
284 {
285 if(ch == '*' && chNext == '/') state = SCE_P_DEFAULT;
286 }
287 else if (state == SCE_P_STRING)
288 {
289 if ((ch == '\r' || ch == '\n') && (chPrev != '\\'))
290 {
291 styler.ColourTo(i - 1, state);
292 state = SCE_P_STRINGEOL;
293 }
294 else if (ch == '\\')
295 {
296 if (chNext == '\"' || chNext == '\'' || chNext == '\\')
297 {
298 i++;
299 ch = chNext;
300 chNext = styler.SafeGetCharAt(i + 1);
301 }
302 }
303 else if (ch == '\"')
304 {
305 styler.ColourTo(i, state);
306 state = SCE_P_DEFAULT;
307 }
308 }
309 else if (state == SCE_P_CHARACTER)
310 {
311 if ((ch == '\r' || ch == '\n') && (chPrev != '\\'))
312 {
313 styler.ColourTo(i - 1, state);
314 state = SCE_P_STRINGEOL;
315 }
316 else if (ch == '\\')
317 {
318 if (chNext == '\"' || chNext == '\'' || chNext == '\\')
319 {
320 i++;
321 ch = chNext;
322 chNext = styler.SafeGetCharAt(i + 1);
323 }
324 }
325 else if (ch == '\'')
326 {
327 styler.ColourTo(i, state);
328 state = SCE_P_DEFAULT;
329 }
330 }
331 /*
332 else if (state == SCE_P_TRIPLE)
333 {
334 if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'')
335 {
336 styler.ColourTo(i, state);
337 state = SCE_P_DEFAULT;
338 }
339 }
340 else if (state == SCE_P_TRIPLEDOUBLE)
341 {
342 // =end terminates the comment block
343 if (ch == 'd' && chPrev == 'n' && chPrev2 == 'e')
344 {
345 if (styler.SafeGetCharAt(i - 3) == '=')
346 {
347 styler.ColourTo(i, state);
348 state = SCE_P_DEFAULT;
349 }
350 }
351 }
352 */
353 }
354 //chPrev2 = chPrev;
355 chPrev = ch;
356 }
357 if (state == SCE_P_WORD)
358 {
359 ClassifyWordSol(styler.GetStartSegment(), lengthDoc-1, keywords, styler, prevWord);
360 }
361 else
362 {
363 styler.ColourTo(lengthDoc-1, state);
364 }
365 }
366
367 static void FoldSolDoc(unsigned int startPos, int length, int initStyle,
368 WordList *[], Accessor &styler)
369 {
370 int lengthDoc = startPos + length;
371
372 // Backtrack to previous line in case need to fix its fold status
373 int lineCurrent = styler.GetLine(startPos);
374 if (startPos > 0) {
375 if (lineCurrent > 0)
376 {
377 lineCurrent--;
378 startPos = styler.LineStart(lineCurrent);
379 if (startPos == 0)
380 initStyle = SCE_P_DEFAULT;
381 else
382 initStyle = styler.StyleAt(startPos-1);
383 }
384 }
385 int state = initStyle & 31;
386 int spaceFlags = 0;
387 int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsSolComment);
388 if ((state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE))
389 indentCurrent |= SC_FOLDLEVELWHITEFLAG;
390 char chNext = styler[startPos];
391 for (int i = startPos; i < lengthDoc; i++)
392 {
393 char ch = chNext;
394 chNext = styler.SafeGetCharAt(i + 1);
395 int style = styler.StyleAt(i) & 31;
396
397 if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc))
398 {
399 int lev = indentCurrent;
400 int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsSolComment);
401 if ((style == SCE_P_TRIPLE) || (style== SCE_P_TRIPLEDOUBLE))
402 indentNext |= SC_FOLDLEVELWHITEFLAG;
403 if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG))
404 {
405 // Only non whitespace lines can be headers
406 if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
407 {
408 lev |= SC_FOLDLEVELHEADERFLAG;
409 } else if (indentNext & SC_FOLDLEVELWHITEFLAG)
410 {
411 // Line after is blank so check the next - maybe should continue further?
412 int spaceFlags2 = 0;
413 int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsSolComment);
414 if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK))
415 {
416 lev |= SC_FOLDLEVELHEADERFLAG;
417 }
418 }
419 }
420 indentCurrent = indentNext;
421 styler.SetLevel(lineCurrent, lev);
422 lineCurrent++;
423 }
424 }
425 }
426
427 LexerModule lmScriptol(SCLEX_SCRIPTOL, ColouriseSolDoc, "scriptol", FoldSolDoc);