Update Scintilla to version 3.4.4
[TortoiseGit.git] / ext / scintilla / lexers / LexScriptol.cxx
blob0b25068fca19c4595eb773f65d7779feaa76a624
1 // Scintilla source code edit control
2 /** @file LexScriptol.cxx
3 ** Lexer for Scriptol.
4 **/
6 #include <stdlib.h>
7 #include <string.h>
8 #include <stdio.h>
9 #include <stdarg.h>
10 #include <assert.h>
11 #include <ctype.h>
13 #include "ILexer.h"
14 #include "Scintilla.h"
15 #include "SciLexer.h"
17 #include "WordList.h"
18 #include "LexAccessor.h"
19 #include "Accessor.h"
20 #include "StyleContext.h"
21 #include "CharacterSet.h"
22 #include "LexerModule.h"
24 #ifdef SCI_NAMESPACE
25 using namespace Scintilla;
26 #endif
28 static void ClassifyWordSol(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord)
30 char s[100] = "";
31 bool wordIsNumber = isdigit(styler[start]) != 0;
32 for (unsigned int i = 0; i < end - start + 1 && i < 30; i++)
34 s[i] = styler[start + i];
35 s[i + 1] = '\0';
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
43 if (styler[start + i] == '.')
45 styler.ColourTo(start + i - 1, chAttr);
46 styler.ColourTo(start + i, SCE_SCRIPTOL_OPERATOR);
49 styler.ColourTo(end, chAttr);
50 strcpy(prevWord, s);
53 static bool IsSolComment(Accessor &styler, int pos, int len)
55 if(len > 0)
57 char c = styler[pos];
58 if(c == '`') return true;
59 if(len > 1)
61 if(c == '/')
63 c = styler[pos + 1];
64 if(c == '/') return true;
65 if(c == '*') return true;
69 return false;
72 static bool IsSolStringStart(char ch)
74 if (ch == '\'' || ch == '"') return true;
75 return false;
78 static bool IsSolWordStart(char ch)
80 return (iswordchar(ch) && !IsSolStringStart(ch));
84 static int GetSolStringState(Accessor &styler, int i, int *nextIndex)
86 char ch = styler.SafeGetCharAt(i);
87 char chNext = styler.SafeGetCharAt(i + 1);
89 if (ch != '\"' && ch != '\'')
91 *nextIndex = i + 1;
92 return SCE_SCRIPTOL_DEFAULT;
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))
98 *nextIndex = i + 3;
99 if(ch == '\"') return SCE_SCRIPTOL_TRIPLE;
100 if(ch == '\'') return SCE_SCRIPTOL_TRIPLE;
101 return SCE_SCRIPTOL_STRING;
103 else
105 *nextIndex = i + 1;
106 if (ch == '"') return SCE_SCRIPTOL_STRING;
107 else return SCE_SCRIPTOL_STRING;
112 static void ColouriseSolDoc(unsigned int startPos, int length, int initStyle,
113 WordList *keywordlists[], Accessor &styler)
116 int lengthDoc = startPos + length;
117 char stringType = '\"';
119 if (startPos > 0)
121 int lineCurrent = styler.GetLine(startPos);
122 if (lineCurrent > 0)
124 startPos = styler.LineStart(lineCurrent-1);
125 if (startPos == 0) initStyle = SCE_SCRIPTOL_DEFAULT;
126 else initStyle = styler.StyleAt(startPos-1);
130 styler.StartAt(startPos);
132 WordList &keywords = *keywordlists[0];
134 char prevWord[200];
135 prevWord[0] = '\0';
136 if (length == 0) return;
138 int state = initStyle & 31;
140 int nextIndex = 0;
141 char chPrev = ' ';
142 char chPrev2 = ' ';
143 char chNext = styler[startPos];
144 styler.StartSegment(startPos);
145 for (int i = startPos; i < lengthDoc; i++)
148 char ch = chNext;
149 chNext = styler.SafeGetCharAt(i + 1);
151 if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc))
153 if ((state == SCE_SCRIPTOL_DEFAULT) ||
154 (state == SCE_SCRIPTOL_TRIPLE) ||
155 (state == SCE_SCRIPTOL_COMMENTBLOCK))
157 styler.ColourTo(i, state);
161 if (styler.IsLeadByte(ch))
163 chNext = styler.SafeGetCharAt(i + 2);
164 chPrev = ' ';
165 chPrev2 = ' ';
166 i += 1;
167 continue;
170 if (state == SCE_SCRIPTOL_STRINGEOL)
172 if (ch != '\r' && ch != '\n')
174 styler.ColourTo(i - 1, state);
175 state = SCE_SCRIPTOL_DEFAULT;
179 if (state == SCE_SCRIPTOL_DEFAULT)
181 if (IsSolWordStart(ch))
183 styler.ColourTo(i - 1, state);
184 state = SCE_SCRIPTOL_KEYWORD;
186 else if (ch == '`')
188 styler.ColourTo(i - 1, state);
189 state = SCE_SCRIPTOL_COMMENTLINE;
191 else if (ch == '/')
193 styler.ColourTo(i - 1, state);
194 if(chNext == '/') state = SCE_SCRIPTOL_CSTYLE;
195 if(chNext == '*') state = SCE_SCRIPTOL_COMMENTBLOCK;
198 else if (IsSolStringStart(ch))
200 styler.ColourTo(i - 1, state);
201 state = GetSolStringState(styler, i, &nextIndex);
202 if(state == SCE_SCRIPTOL_STRING)
204 stringType = ch;
206 if (nextIndex != i + 1)
208 i = nextIndex - 1;
209 ch = ' ';
210 chPrev = ' ';
211 chNext = styler.SafeGetCharAt(i + 1);
214 else if (isoperator(ch))
216 styler.ColourTo(i - 1, state);
217 styler.ColourTo(i, SCE_SCRIPTOL_OPERATOR);
220 else if (state == SCE_SCRIPTOL_KEYWORD)
222 if (!iswordchar(ch))
224 ClassifyWordSol(styler.GetStartSegment(), i - 1, keywords, styler, prevWord);
225 state = SCE_SCRIPTOL_DEFAULT;
226 if (ch == '`')
228 state = chNext == '`' ? SCE_SCRIPTOL_PERSISTENT : SCE_SCRIPTOL_COMMENTLINE;
230 else if (IsSolStringStart(ch))
232 styler.ColourTo(i - 1, state);
233 state = GetSolStringState(styler, i, &nextIndex);
234 if (nextIndex != i + 1)
236 i = nextIndex - 1;
237 ch = ' ';
238 chPrev = ' ';
239 chNext = styler.SafeGetCharAt(i + 1);
242 else if (isoperator(ch))
244 styler.ColourTo(i, SCE_SCRIPTOL_OPERATOR);
248 else
250 if (state == SCE_SCRIPTOL_COMMENTLINE ||
251 state == SCE_SCRIPTOL_PERSISTENT ||
252 state == SCE_SCRIPTOL_CSTYLE)
254 if (ch == '\r' || ch == '\n')
256 styler.ColourTo(i - 1, state);
257 state = SCE_SCRIPTOL_DEFAULT;
260 else if(state == SCE_SCRIPTOL_COMMENTBLOCK)
262 if(chPrev == '*' && ch == '/')
264 styler.ColourTo(i, state);
265 state = SCE_SCRIPTOL_DEFAULT;
268 else if ((state == SCE_SCRIPTOL_STRING) ||
269 (state == SCE_SCRIPTOL_CHARACTER))
271 if ((ch == '\r' || ch == '\n') && (chPrev != '\\'))
273 styler.ColourTo(i - 1, state);
274 state = SCE_SCRIPTOL_STRINGEOL;
276 else if (ch == '\\')
278 if (chNext == '\"' || chNext == '\'' || chNext == '\\')
280 i++;
281 ch = chNext;
282 chNext = styler.SafeGetCharAt(i + 1);
285 else if ((ch == '\"') || (ch == '\''))
287 // must match the entered quote type
288 if(ch == stringType)
290 styler.ColourTo(i, state);
291 state = SCE_SCRIPTOL_DEFAULT;
295 else if (state == SCE_SCRIPTOL_TRIPLE)
297 if ((ch == '\'' && chPrev == '\'' && chPrev2 == '\'') ||
298 (ch == '\"' && chPrev == '\"' && chPrev2 == '\"'))
300 styler.ColourTo(i, state);
301 state = SCE_SCRIPTOL_DEFAULT;
306 chPrev2 = chPrev;
307 chPrev = ch;
309 if (state == SCE_SCRIPTOL_KEYWORD)
311 ClassifyWordSol(styler.GetStartSegment(),
312 lengthDoc-1, keywords, styler, prevWord);
314 else
316 styler.ColourTo(lengthDoc-1, state);
320 static void FoldSolDoc(unsigned int startPos, int length, int initStyle,
321 WordList *[], Accessor &styler)
323 int lengthDoc = startPos + length;
325 int lineCurrent = styler.GetLine(startPos);
326 if (startPos > 0)
328 if (lineCurrent > 0)
330 lineCurrent--;
331 startPos = styler.LineStart(lineCurrent);
332 if (startPos == 0)
333 initStyle = SCE_SCRIPTOL_DEFAULT;
334 else
335 initStyle = styler.StyleAt(startPos-1);
338 int state = initStyle & 31;
339 int spaceFlags = 0;
340 int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsSolComment);
341 if (state == SCE_SCRIPTOL_TRIPLE)
342 indentCurrent |= SC_FOLDLEVELWHITEFLAG;
343 char chNext = styler[startPos];
344 for (int i = startPos; i < lengthDoc; i++)
346 char ch = chNext;
347 chNext = styler.SafeGetCharAt(i + 1);
348 int style = styler.StyleAt(i) & 31;
350 if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc))
352 int lev = indentCurrent;
353 int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsSolComment);
354 if (style == SCE_SCRIPTOL_TRIPLE)
355 indentNext |= SC_FOLDLEVELWHITEFLAG;
356 if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG))
358 // Only non whitespace lines can be headers
359 if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
361 lev |= SC_FOLDLEVELHEADERFLAG;
363 else if (indentNext & SC_FOLDLEVELWHITEFLAG)
365 // Line after is blank so check the next - maybe should continue further?
366 int spaceFlags2 = 0;
367 int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsSolComment);
368 if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK))
370 lev |= SC_FOLDLEVELHEADERFLAG;
374 indentCurrent = indentNext;
375 styler.SetLevel(lineCurrent, lev);
376 lineCurrent++;
381 LexerModule lmScriptol(SCLEX_SCRIPTOL, ColouriseSolDoc, "scriptol", FoldSolDoc);