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