OSDN Git Service

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