*** empty log message ***
[anjuta-git-plugin.git] / scintilla / LexOthers.cxx
blobf777e300fa24ec132a68137cc899bc81762a8a62
1 // Scintilla source code edit control
2 /** @file LexOthers.cxx
3 ** Lexers for batch files, diff results, properties files, make files and error lists.
4 ** Also lexer for LaTeX documents.
5 **/
6 // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
7 // The License.txt file describes the conditions under which this software may be distributed.
9 #include <stdlib.h>
10 #include <string.h>
11 #include <ctype.h>
12 #include <stdio.h>
13 #include <stdarg.h>
15 #include "Platform.h"
17 #include "PropSet.h"
18 #include "Accessor.h"
19 #include "KeyWords.h"
20 #include "Scintilla.h"
21 #include "SciLexer.h"
23 static bool Is0To9(char ch) {
24 return (ch >= '0') && (ch <= '9');
27 static bool Is1To9(char ch) {
28 return (ch >= '1') && (ch <= '9');
31 static inline bool AtEOL(Accessor &styler, unsigned int i) {
32 return (styler[i] == '\n') ||
33 ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
36 static void ColouriseBatchLine(
37 char *lineBuffer,
38 unsigned int lengthLine,
39 unsigned int startLine,
40 unsigned int endPos,
41 WordList &keywords,
42 Accessor &styler) {
44 unsigned int i = 0;
45 unsigned int state = SCE_BAT_DEFAULT;
47 while ((i < lengthLine) && isspacechar(lineBuffer[i])) { // Skip initial spaces
48 i++;
50 if (lineBuffer[i] == '@') { // Hide command (ECHO OFF)
51 styler.ColourTo(startLine + i, SCE_BAT_HIDE);
52 i++;
53 while ((i < lengthLine) && isspacechar(lineBuffer[i])) { // Skip next spaces
54 i++;
57 if (lineBuffer[i] == ':') {
58 // Label
59 if (lineBuffer[i + 1] == ':') {
60 // :: is a fake label, similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm
61 styler.ColourTo(endPos, SCE_BAT_COMMENT);
62 } else { // Real label
63 styler.ColourTo(endPos, SCE_BAT_LABEL);
65 } else {
66 // Check if initial word is a keyword
67 char wordBuffer[21];
68 unsigned int wbl = 0, offset = i;
69 // Copy word in buffer
70 for (; offset < lengthLine && wbl < 20 &&
71 !isspacechar(lineBuffer[offset]); wbl++, offset++) {
72 wordBuffer[wbl] = static_cast<char>(tolower(lineBuffer[offset]));
74 wordBuffer[wbl] = '\0';
75 // Check if it is a comment
76 if (CompareCaseInsensitive(wordBuffer, "rem") == 0) {
77 styler.ColourTo(endPos, SCE_BAT_COMMENT);
78 return ;
80 // Check if it is in the list
81 if (keywords.InList(wordBuffer)) {
82 styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD); // Regular keyword
83 } else {
84 // Search end of word (can be a long path)
85 while (offset < lengthLine &&
86 !isspacechar(lineBuffer[offset])) {
87 offset++;
89 styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); // External command / program
91 // Remainder of the line: colourise the variables.
93 while (offset < lengthLine) {
94 if (state == SCE_BAT_DEFAULT && lineBuffer[offset] == '%') {
95 styler.ColourTo(startLine + offset - 1, state);
96 if (Is0To9(lineBuffer[offset + 1])) {
97 styler.ColourTo(startLine + offset + 1, SCE_BAT_IDENTIFIER);
98 offset += 2;
99 } else if (lineBuffer[offset + 1] == '%' &&
100 !isspacechar(lineBuffer[offset + 2])) {
101 // Should be safe, as there is CRLF at the end of the line...
102 styler.ColourTo(startLine + offset + 2, SCE_BAT_IDENTIFIER);
103 offset += 3;
104 } else {
105 state = SCE_BAT_IDENTIFIER;
107 } else if (state == SCE_BAT_IDENTIFIER && lineBuffer[offset] == '%') {
108 styler.ColourTo(startLine + offset, state);
109 state = SCE_BAT_DEFAULT;
110 } else if (state == SCE_BAT_DEFAULT &&
111 (lineBuffer[offset] == '*' ||
112 lineBuffer[offset] == '?' ||
113 lineBuffer[offset] == '=' ||
114 lineBuffer[offset] == '<' ||
115 lineBuffer[offset] == '>' ||
116 lineBuffer[offset] == '|')) {
117 styler.ColourTo(startLine + offset - 1, state);
118 styler.ColourTo(startLine + offset, SCE_BAT_OPERATOR);
120 offset++;
122 // if (endPos > startLine + offset - 1) {
123 styler.ColourTo(endPos, SCE_BAT_DEFAULT); // Remainder of line, currently not lexed
124 // }
128 // ToDo: (not necessarily at beginning of line) GOTO, [IF] NOT, ERRORLEVEL
129 // IF [NO] (test) (command) -- test is EXIST (filename) | (string1)==(string2) | ERRORLEVEL (number)
130 // FOR %%(variable) IN (set) DO (command) -- variable is [a-zA-Z] -- eg for %%X in (*.txt) do type %%X
131 // ToDo: %n (parameters), %EnvironmentVariable% colourising
132 // ToDo: Colourise = > >> < | "
134 static void ColouriseBatchDoc(
135 unsigned int startPos,
136 int length,
137 int /*initStyle*/,
138 WordList *keywordlists[],
139 Accessor &styler) {
141 char lineBuffer[1024];
142 WordList &keywords = *keywordlists[0];
144 styler.StartAt(startPos);
145 styler.StartSegment(startPos);
146 unsigned int linePos = 0;
147 unsigned int startLine = startPos;
148 for (unsigned int i = startPos; i < startPos + length; i++) {
149 lineBuffer[linePos++] = styler[i];
150 if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
151 // End of line (or of line buffer) met, colourise it
152 lineBuffer[linePos] = '\0';
153 ColouriseBatchLine(lineBuffer, linePos, startLine, i, keywords, styler);
154 linePos = 0;
155 startLine = i + 1;
158 if (linePos > 0) { // Last line does not have ending characters
159 ColouriseBatchLine(lineBuffer, linePos, startLine, startPos + length - 1,
160 keywords, styler);
164 static void ColouriseDiffLine(char *lineBuffer, int endLine, Accessor &styler) {
165 // It is needed to remember the current state to recognize starting
166 // comment lines before the first "diff " or "--- ". If a real
167 // difference starts then each line starting with ' ' is a whitespace
168 // otherwise it is considered a comment (Only in..., Binary file...)
169 if (0 == strncmp(lineBuffer, "diff ", 5)) {
170 styler.ColourTo(endLine, SCE_DIFF_COMMAND);
171 } else if (0 == strncmp(lineBuffer, "--- ", 4)) {
172 // In a context diff, --- appears in both the header and the position markers
173 if (atoi(lineBuffer+4) && !strchr(lineBuffer, '/'))
174 styler.ColourTo(endLine, SCE_DIFF_POSITION);
175 else
176 styler.ColourTo(endLine, SCE_DIFF_HEADER);
177 } else if (0 == strncmp(lineBuffer, "+++ ", 4)) {
178 // I don't know of any diff where "+++ " is a position marker, but for
179 // consistency, do the same as with "--- " and "*** ".
180 if (atoi(lineBuffer+4) && !strchr(lineBuffer, '/'))
181 styler.ColourTo(endLine, SCE_DIFF_POSITION);
182 else
183 styler.ColourTo(endLine, SCE_DIFF_HEADER);
184 } else if (0 == strncmp(lineBuffer, "====", 4)) { // For p4's diff
185 styler.ColourTo(endLine, SCE_DIFF_HEADER);
186 } else if (0 == strncmp(lineBuffer, "***", 3)) {
187 // In a context diff, *** appears in both the header and the position markers.
188 // Also ******** is a chunk header, but here it's treated as part of the
189 // position marker since there is no separate style for a chunk header.
190 if (lineBuffer[3] == ' ' && atoi(lineBuffer+4) && !strchr(lineBuffer, '/'))
191 styler.ColourTo(endLine, SCE_DIFF_POSITION);
192 else if (lineBuffer[3] == '*')
193 styler.ColourTo(endLine, SCE_DIFF_POSITION);
194 else
195 styler.ColourTo(endLine, SCE_DIFF_HEADER);
196 } else if (0 == strncmp(lineBuffer, "? ", 2)) { // For difflib
197 styler.ColourTo(endLine, SCE_DIFF_HEADER);
198 } else if (lineBuffer[0] == '@') {
199 styler.ColourTo(endLine, SCE_DIFF_POSITION);
200 } else if (lineBuffer[0] >= '0' && lineBuffer[0] <= '9') {
201 styler.ColourTo(endLine, SCE_DIFF_POSITION);
202 } else if (lineBuffer[0] == '-' || lineBuffer[0] == '<') {
203 styler.ColourTo(endLine, SCE_DIFF_DELETED);
204 } else if (lineBuffer[0] == '+' || lineBuffer[0] == '>') {
205 styler.ColourTo(endLine, SCE_DIFF_ADDED);
206 } else if (lineBuffer[0] != ' ') {
207 styler.ColourTo(endLine, SCE_DIFF_COMMENT);
208 } else {
209 styler.ColourTo(endLine, SCE_DIFF_DEFAULT);
213 static void ColouriseDiffDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
214 char lineBuffer[1024];
215 styler.StartAt(startPos);
216 styler.StartSegment(startPos);
217 unsigned int linePos = 0;
218 for (unsigned int i = startPos; i < startPos + length; i++) {
219 lineBuffer[linePos++] = styler[i];
220 if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
221 // End of line (or of line buffer) met, colourise it
222 lineBuffer[linePos] = '\0';
223 ColouriseDiffLine(lineBuffer, i, styler);
224 linePos = 0;
227 if (linePos > 0) { // Last line does not have ending characters
228 ColouriseDiffLine(lineBuffer, startPos + length - 1, styler);
232 static void FoldDiffDoc(unsigned int startPos, int length, int, WordList*[], Accessor &styler) {
233 int curLine = styler.GetLine(startPos);
234 int prevLevel = SC_FOLDLEVELBASE;
235 if (curLine > 0)
236 prevLevel = styler.LevelAt(curLine-1);
238 int curLineStart = styler.LineStart(curLine);
239 do {
240 int nextLevel = prevLevel;
241 if (prevLevel & SC_FOLDLEVELHEADERFLAG)
242 nextLevel = (prevLevel & SC_FOLDLEVELNUMBERMASK) + 1;
244 int lineType = styler.StyleAt(curLineStart);
245 if (lineType == SCE_DIFF_COMMAND)
246 nextLevel = (SC_FOLDLEVELBASE + 1) | SC_FOLDLEVELHEADERFLAG;
247 else if (lineType == SCE_DIFF_HEADER) {
248 nextLevel = (SC_FOLDLEVELBASE + 2) | SC_FOLDLEVELHEADERFLAG;
249 } else if (lineType == SCE_DIFF_POSITION)
250 nextLevel = (SC_FOLDLEVELBASE + 3) | SC_FOLDLEVELHEADERFLAG;
252 if ((nextLevel & SC_FOLDLEVELHEADERFLAG) && (nextLevel == prevLevel))
253 styler.SetLevel(curLine-1, prevLevel & ~SC_FOLDLEVELHEADERFLAG);
255 styler.SetLevel(curLine, nextLevel);
256 prevLevel = nextLevel;
258 curLineStart = styler.LineStart(++curLine);
259 } while (static_cast<int>(startPos) + length > curLineStart);
263 static void ColourisePropsLine(
264 char *lineBuffer,
265 unsigned int lengthLine,
266 unsigned int startLine,
267 unsigned int endPos,
268 Accessor &styler) {
270 unsigned int i = 0;
271 while ((i < lengthLine) && isspacechar(lineBuffer[i])) // Skip initial spaces
272 i++;
273 if (i < lengthLine) {
274 if (lineBuffer[i] == '#' || lineBuffer[i] == '!' || lineBuffer[i] == ';') {
275 styler.ColourTo(endPos, SCE_PROPS_COMMENT);
276 } else if (lineBuffer[i] == '[') {
277 styler.ColourTo(endPos, SCE_PROPS_SECTION);
278 } else if (lineBuffer[i] == '@') {
279 styler.ColourTo(startLine + i, SCE_PROPS_DEFVAL);
280 if (lineBuffer[++i] == '=')
281 styler.ColourTo(startLine + i, SCE_PROPS_ASSIGNMENT);
282 styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
283 } else {
284 // Search for the '=' character
285 while ((i < lengthLine) && (lineBuffer[i] != '='))
286 i++;
287 if ((i < lengthLine) && (lineBuffer[i] == '=')) {
288 styler.ColourTo(startLine + i - 1, SCE_PROPS_DEFAULT);
289 styler.ColourTo(startLine + i, 3);
290 styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
291 } else {
292 styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
295 } else {
296 styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
300 static void ColourisePropsDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
301 char lineBuffer[1024];
302 styler.StartAt(startPos);
303 styler.StartSegment(startPos);
304 unsigned int linePos = 0;
305 unsigned int startLine = startPos;
306 for (unsigned int i = startPos; i < startPos + length; i++) {
307 lineBuffer[linePos++] = styler[i];
308 if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
309 // End of line (or of line buffer) met, colourise it
310 lineBuffer[linePos] = '\0';
311 ColourisePropsLine(lineBuffer, linePos, startLine, i, styler);
312 linePos = 0;
313 startLine = i + 1;
316 if (linePos > 0) { // Last line does not have ending characters
317 ColourisePropsLine(lineBuffer, linePos, startLine, startPos + length - 1, styler);
321 // adaption by ksc, using the "} else {" trick of 1.53
322 // 030721
323 static void FoldPropsDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
324 bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
326 unsigned int endPos = startPos + length;
327 int visibleChars = 0;
328 int lineCurrent = styler.GetLine(startPos);
330 char chNext = styler[startPos];
331 int styleNext = styler.StyleAt(startPos);
332 bool headerPoint = false;
333 int lev;
335 for (unsigned int i = startPos; i < endPos; i++) {
336 char ch = chNext;
337 chNext = styler[i+1];
339 int style = styleNext;
340 styleNext = styler.StyleAt(i + 1);
341 bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
343 if (style == SCE_PROPS_SECTION) {
344 headerPoint = true;
347 if (atEOL) {
348 lev = SC_FOLDLEVELBASE;
350 if (lineCurrent > 0) {
351 int levelPrevious = styler.LevelAt(lineCurrent - 1);
353 if (levelPrevious & SC_FOLDLEVELHEADERFLAG) {
354 lev = SC_FOLDLEVELBASE + 1;
355 } else {
356 lev = levelPrevious & SC_FOLDLEVELNUMBERMASK;
360 if (headerPoint) {
361 lev = SC_FOLDLEVELBASE;
363 if (visibleChars == 0 && foldCompact)
364 lev |= SC_FOLDLEVELWHITEFLAG;
366 if (headerPoint) {
367 lev |= SC_FOLDLEVELHEADERFLAG;
369 if (lev != styler.LevelAt(lineCurrent)) {
370 styler.SetLevel(lineCurrent, lev);
373 lineCurrent++;
374 visibleChars = 0;
375 headerPoint=false;
377 if (!isspacechar(ch))
378 visibleChars++;
381 if (lineCurrent > 0) {
382 int levelPrevious = styler.LevelAt(lineCurrent - 1);
383 if (levelPrevious & SC_FOLDLEVELHEADERFLAG) {
384 lev = SC_FOLDLEVELBASE + 1;
385 } else {
386 lev = levelPrevious & SC_FOLDLEVELNUMBERMASK;
388 } else {
389 lev = SC_FOLDLEVELBASE;
391 int flagsNext = styler.LevelAt(lineCurrent);
392 styler.SetLevel(lineCurrent, lev | flagsNext & ~SC_FOLDLEVELNUMBERMASK);
395 static void ColouriseMakeLine(
396 char *lineBuffer,
397 unsigned int lengthLine,
398 unsigned int startLine,
399 unsigned int endPos,
400 Accessor &styler) {
402 unsigned int i = 0;
403 int lastNonSpace = -1;
404 unsigned int state = SCE_MAKE_DEFAULT;
405 bool bSpecial = false;
406 // Skip initial spaces
407 while ((i < lengthLine) && isspacechar(lineBuffer[i])) {
408 i++;
410 if (lineBuffer[i] == '#') { // Comment
411 styler.ColourTo(endPos, SCE_MAKE_COMMENT);
412 return;
414 if (lineBuffer[i] == '!') { // Special directive
415 styler.ColourTo(endPos, SCE_MAKE_PREPROCESSOR);
416 return;
418 while (i < lengthLine) {
419 if (lineBuffer[i] == '$' && lineBuffer[i + 1] == '(') {
420 styler.ColourTo(startLine + i - 1, state);
421 state = SCE_MAKE_IDENTIFIER;
422 } else if (state == SCE_MAKE_IDENTIFIER && lineBuffer[i] == ')') {
423 styler.ColourTo(startLine + i, state);
424 state = SCE_MAKE_DEFAULT;
426 if (!bSpecial) {
427 if (lineBuffer[i] == ':') {
428 // We should check that no colouring was made since the beginning of the line,
429 // to avoid colouring stuff like /OUT:file
430 if (lastNonSpace >= 0)
431 styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_TARGET);
432 styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
433 styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR);
434 bSpecial = true; // Only react to the first ':' of the line
435 state = SCE_MAKE_DEFAULT;
436 } else if (lineBuffer[i] == '=') {
437 if (lastNonSpace >= 0)
438 styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER);
439 styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
440 styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR);
441 bSpecial = true; // Only react to the first '=' of the line
442 state = SCE_MAKE_DEFAULT;
445 if (!isspacechar(lineBuffer[i])) {
446 lastNonSpace = i;
448 i++;
450 if (state == SCE_MAKE_IDENTIFIER) {
451 styler.ColourTo(endPos, SCE_MAKE_IDEOL); // Error, variable reference not ended
452 } else {
453 styler.ColourTo(endPos, SCE_MAKE_DEFAULT);
457 static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
458 char lineBuffer[1024];
459 styler.StartAt(startPos);
460 styler.StartSegment(startPos);
461 unsigned int linePos = 0;
462 unsigned int startLine = startPos;
463 for (unsigned int i = startPos; i < startPos + length; i++) {
464 lineBuffer[linePos++] = styler[i];
465 if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
466 // End of line (or of line buffer) met, colourise it
467 lineBuffer[linePos] = '\0';
468 ColouriseMakeLine(lineBuffer, linePos, startLine, i, styler);
469 linePos = 0;
470 startLine = i + 1;
473 if (linePos > 0) { // Last line does not have ending characters
474 ColouriseMakeLine(lineBuffer, linePos, startLine, startPos + length - 1, styler);
478 static bool strstart(char *haystack, char *needle) {
479 return strncmp(haystack, needle, strlen(needle)) == 0;
482 static void ColouriseErrorListLine(
483 char *lineBuffer,
484 unsigned int lengthLine,
485 // unsigned int startLine,
486 unsigned int endPos,
487 Accessor &styler) {
488 const int unRecognized = 99;
489 if (lineBuffer[0] == '>') {
490 // Command or return status
491 styler.ColourTo(endPos, SCE_ERR_CMD);
492 } else if (lineBuffer[0] == '<') {
493 // Diff removal, but not interested. Trapped to avoid hitting CTAG cases.
494 styler.ColourTo(endPos, SCE_ERR_DEFAULT);
495 } else if (lineBuffer[0] == '!') {
496 styler.ColourTo(endPos, SCE_ERR_DIFF_CHANGED);
497 } else if (lineBuffer[0] == '+') {
498 styler.ColourTo(endPos, SCE_ERR_DIFF_ADDITION);
499 } else if (lineBuffer[0] == '-' && lineBuffer[1] == '-' && lineBuffer[2] == '-') {
500 styler.ColourTo(endPos, SCE_ERR_DIFF_MESSAGE);
501 } else if (lineBuffer[0] == '-') {
502 styler.ColourTo(endPos, SCE_ERR_DIFF_DELETION);
503 } else if (strstart(lineBuffer, "cf90-")) {
504 // Absoft Pro Fortran 90/95 v8.2 error and/or warning message
505 styler.ColourTo(endPos, SCE_ERR_ABSF);
506 } else if (strstart(lineBuffer, "fortcom:")) {
507 // Intel Fortran Compiler v8.0 error/warning message
508 styler.ColourTo(endPos, SCE_ERR_IFORT);
509 } else if (strstr(lineBuffer, "File \"") && strstr(lineBuffer, ", line ")) {
510 styler.ColourTo(endPos, SCE_ERR_PYTHON);
511 } else if (strstr(lineBuffer, " in ") && strstr(lineBuffer, " on line ")) {
512 styler.ColourTo(endPos, SCE_ERR_PHP);
513 } else if ((strstart(lineBuffer, "Error ") ||
514 strstart(lineBuffer, "Warning ")) &&
515 strstr(lineBuffer, " at (") &&
516 strstr(lineBuffer, ") : ") &&
517 (strstr(lineBuffer, " at (") < strstr(lineBuffer, ") : "))) {
518 // Intel Fortran Compiler error/warning message
519 styler.ColourTo(endPos, SCE_ERR_IFC);
520 } else if (strstart(lineBuffer, "Error ")) {
521 // Borland error message
522 styler.ColourTo(endPos, SCE_ERR_BORLAND);
523 } else if (strstart(lineBuffer, "Warning ")) {
524 // Borland warning message
525 styler.ColourTo(endPos, SCE_ERR_BORLAND);
526 } else if (strstr(lineBuffer, "at line " ) &&
527 (strstr(lineBuffer, "at line " ) < (lineBuffer + lengthLine)) &&
528 strstr(lineBuffer, "file ") &&
529 (strstr(lineBuffer, "file ") < (lineBuffer + lengthLine))) {
530 // Lua 4 error message
531 styler.ColourTo(endPos, SCE_ERR_LUA);
532 } else if (strstr(lineBuffer, " at " ) &&
533 (strstr(lineBuffer, " at " ) < (lineBuffer + lengthLine)) &&
534 strstr(lineBuffer, " line ") &&
535 (strstr(lineBuffer, " line ") < (lineBuffer + lengthLine)) &&
536 (strstr(lineBuffer, " at " ) < (strstr(lineBuffer, " line ")))) {
537 // perl error message
538 styler.ColourTo(endPos, SCE_ERR_PERL);
539 } else if ((memcmp(lineBuffer, " at ", 6) == 0) &&
540 strstr(lineBuffer, ":line ")) {
541 // A .NET traceback
542 styler.ColourTo(endPos, SCE_ERR_NET);
543 } else if (strstart(lineBuffer, "Line ") &&
544 strstr(lineBuffer, ", file ")) {
545 // Essential Lahey Fortran error message
546 styler.ColourTo(endPos, SCE_ERR_ELF);
547 } else if (strstart(lineBuffer, "line ") &&
548 strstr(lineBuffer, " column ")) {
549 // HTML tidy style: line 42 column 1
550 styler.ColourTo(endPos, SCE_ERR_TIDY);
551 } else if (strstart(lineBuffer, "\tat ") &&
552 strstr(lineBuffer, "(") &&
553 strstr(lineBuffer, ".java:")) {
554 // Java stack back trace
555 styler.ColourTo(endPos, SCE_ERR_JAVA_STACK);
556 } else {
557 // Look for GCC <filename>:<line>:message
558 // Look for Microsoft <filename>(line) :message
559 // Look for Microsoft <filename>(line,pos)message
560 // Look for CTags \tmessage
561 // Look for Lua 5 traceback \t<filename>:<line>:message
562 bool initialTab = (lineBuffer[0] == '\t');
563 int state = 0;
564 for (unsigned int i = 0; i < lengthLine; i++) {
565 char ch = lineBuffer[i];
566 char chNext = ' ';
567 if ((i+1) < lengthLine)
568 chNext = lineBuffer[i+1];
569 if (state == 0) {
570 if (ch == ':') {
571 // May be GCC, or might be Lua 5 (Lua traceback same but with tab prefix)
572 if ((chNext != '\\') && (chNext != '/')) {
573 // This check is not completely accurate as may be on
574 // GTK+ with a file name that includes ':'.
575 state = 1;
577 } else if ((ch == '(') && Is1To9(chNext) && (!initialTab)) {
578 // May be Microsoft
579 // Check against '0' often removes phone numbers
580 state = 10;
581 } else if ((ch == '\t') && (!initialTab)) {
582 // May be CTags
583 state = 20;
585 } else if (state == 1) {
586 state = Is1To9(ch) ? 2 : unRecognized;
587 } else if (state == 2) {
588 if (ch == ':') {
589 state = 3; // :9.*: is GCC
590 break;
591 } else if (!Is0To9(ch)) {
592 state = unRecognized;
594 } else if (state == 10) {
595 state = Is0To9(ch) ? 11 : unRecognized;
596 } else if (state == 11) {
597 if (ch == ',') {
598 state = 14;
599 } else if (ch == ')') {
600 state = 12;
601 } else if ((ch != ' ') && !Is0To9(ch)) {
602 state = unRecognized;
604 } else if (state == 12) {
605 if ((ch == ' ') && (chNext == ':')) {
606 state = 13;
607 } else {
608 state = unRecognized;
610 } else if (state == 14) {
611 if (ch == ')') {
612 state = 15;
613 break;
614 } else if ((ch != ' ') && !Is0To9(ch)) {
615 state = unRecognized;
617 } else if (state == 20) {
618 if ((lineBuffer[i-1] == '\t') &&
619 ((ch == '/' && lineBuffer[i+1] == '^') || Is0To9(ch))) {
620 state = 24;
621 break;
622 } else if ((ch == '/') && (lineBuffer[i+1] == '^')) {
623 state = 21;
625 } else if ((state == 21) && ((lineBuffer[i] == '$') && (lineBuffer[i+1] == '/'))) {
626 state = 22;
627 break;
630 if (state == 3) {
631 styler.ColourTo(endPos, SCE_ERR_GCC);
632 } else if ((state == 13) || (state == 14) || (state == 15)) {
633 styler.ColourTo(endPos, SCE_ERR_MS);
634 } else if ((state == 22) || (state == 24)) {
635 styler.ColourTo(endPos, SCE_ERR_CTAG);
636 } else {
637 styler.ColourTo(endPos, SCE_ERR_DEFAULT);
642 static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
643 char lineBuffer[1024];
644 styler.StartAt(startPos);
645 styler.StartSegment(startPos);
646 unsigned int linePos = 0;
647 for (unsigned int i = startPos; i < startPos + length; i++) {
648 lineBuffer[linePos++] = styler[i];
649 if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
650 // End of line (or of line buffer) met, colourise it
651 lineBuffer[linePos] = '\0';
652 ColouriseErrorListLine(lineBuffer, linePos, i, styler);
653 linePos = 0;
656 if (linePos > 0) { // Last line does not have ending characters
657 ColouriseErrorListLine(lineBuffer, linePos, startPos + length - 1, styler);
661 static int isSpecial(char s) {
662 return (s == '\\') || (s == ',') || (s == ';') || (s == '\'') || (s == ' ') ||
663 (s == '\"') || (s == '`') || (s == '^') || (s == '~');
666 static int isTag(int start, Accessor &styler) {
667 char s[6];
668 unsigned int i = 0, e = 1;
669 while (i < 5 && e) {
670 s[i] = styler[start + i];
671 i++;
672 e = styler[start + i] != '{';
674 s[i] = '\0';
675 return (strcmp(s, "begin") == 0) || (strcmp(s, "end") == 0);
678 static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
679 WordList *[], Accessor &styler) {
681 styler.StartAt(startPos);
683 int state = initStyle;
684 char chNext = styler[startPos];
685 styler.StartSegment(startPos);
686 int lengthDoc = startPos + length;
688 for (int i = startPos; i < lengthDoc; i++) {
689 char ch = chNext;
690 chNext = styler.SafeGetCharAt(i + 1);
692 if (styler.IsLeadByte(ch)) {
693 chNext = styler.SafeGetCharAt(i + 2);
694 i++;
695 continue;
697 switch (state) {
698 case SCE_L_DEFAULT :
699 switch (ch) {
700 case '\\' :
701 styler.ColourTo(i - 1, state);
702 if (isSpecial(styler[i + 1])) {
703 styler.ColourTo(i + 1, SCE_L_COMMAND);
704 i++;
705 chNext = styler.SafeGetCharAt(i + 1);
706 } else {
707 if (isTag(i + 1, styler))
708 state = SCE_L_TAG;
709 else
710 state = SCE_L_COMMAND;
712 break;
713 case '$' :
714 styler.ColourTo(i - 1, state);
715 state = SCE_L_MATH;
716 if (chNext == '$') {
717 i++;
718 chNext = styler.SafeGetCharAt(i + 1);
720 break;
721 case '%' :
722 styler.ColourTo(i - 1, state);
723 state = SCE_L_COMMENT;
724 break;
726 break;
727 case SCE_L_COMMAND :
728 if (chNext == '[' || chNext == '{' || chNext == '}' ||
729 chNext == ' ' || chNext == '\r' || chNext == '\n') {
730 styler.ColourTo(i, state);
731 state = SCE_L_DEFAULT;
732 i++;
733 chNext = styler.SafeGetCharAt(i + 1);
735 break;
736 case SCE_L_TAG :
737 if (ch == '}') {
738 styler.ColourTo(i, state);
739 state = SCE_L_DEFAULT;
741 break;
742 case SCE_L_MATH :
743 if (ch == '$') {
744 if (chNext == '$') {
745 i++;
746 chNext = styler.SafeGetCharAt(i + 1);
748 styler.ColourTo(i, state);
749 state = SCE_L_DEFAULT;
751 break;
752 case SCE_L_COMMENT :
753 if (ch == '\r' || ch == '\n') {
754 styler.ColourTo(i - 1, state);
755 state = SCE_L_DEFAULT;
759 styler.ColourTo(lengthDoc-1, state);
762 static const char * const batchWordListDesc[] = {
763 "Keywords",
767 static const char * const emptyWordListDesc[] = {
771 static void ColouriseNullDoc(unsigned int startPos, int length, int, WordList *[],
772 Accessor &styler) {
773 // Null language means all style bytes are 0 so just mark the end - no need to fill in.
774 if (length > 0) {
775 styler.StartAt(startPos + length - 1);
776 styler.StartSegment(startPos + length - 1);
777 styler.ColourTo(startPos + length - 1, 0);
781 LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch", 0, batchWordListDesc);
782 LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff", FoldDiffDoc, emptyWordListDesc);
783 LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, "props", FoldPropsDoc, emptyWordListDesc);
784 LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile", 0, emptyWordListDesc);
785 LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist", 0, emptyWordListDesc);
786 LexerModule lmLatex(SCLEX_LATEX, ColouriseLatexDoc, "latex", 0, emptyWordListDesc);
787 LexerModule lmNull(SCLEX_NULL, ColouriseNullDoc, "null");