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