]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexOthers.cxx
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.
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.
20 #include "Scintilla.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(
38 unsigned int lengthLine
,
39 unsigned int startLine
,
45 unsigned int state
= SCE_BAT_DEFAULT
;
47 while ((i
< lengthLine
) && isspacechar(lineBuffer
[i
])) { // Skip initial spaces
50 if (lineBuffer
[i
] == '@') { // Hide command (ECHO OFF)
51 styler
.ColourTo(startLine
+ i
, SCE_BAT_HIDE
);
53 while ((i
< lengthLine
) && isspacechar(lineBuffer
[i
])) { // Skip next spaces
57 if (lineBuffer
[i
] == ':') {
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
);
66 // Check if initial word is a keyword
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
);
80 // Check if it is in the list
81 if (keywords
.InList(wordBuffer
)) {
82 styler
.ColourTo(startLine
+ offset
- 1, SCE_BAT_WORD
); // Regular keyword
84 // Search end of word (can be a long path)
85 while (offset
< lengthLine
&&
86 !isspacechar(lineBuffer
[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
);
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
);
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
);
122 // if (endPos > startLine + offset - 1) {
123 styler
.ColourTo(endPos
, SCE_BAT_DEFAULT
); // Remainder of line, currently not lexed
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
,
138 WordList
*keywordlists
[],
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
);
158 if (linePos
> 0) { // Last line does not have ending characters
159 ColouriseBatchLine(lineBuffer
, linePos
, startLine
, startPos
+ length
- 1,
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
);
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
);
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
);
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
);
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
);
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
;
236 prevLevel
= styler
.LevelAt(curLine
-1);
238 int curLineStart
= styler
.LineStart(curLine
);
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(
265 unsigned int lengthLine
,
266 unsigned int startLine
,
271 while ((i
< lengthLine
) && isspacechar(lineBuffer
[i
])) // Skip initial spaces
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
);
284 // Search for the '=' character
285 while ((i
< lengthLine
) && (lineBuffer
[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
);
292 styler
.ColourTo(endPos
, SCE_PROPS_DEFAULT
);
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
);
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
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;
335 for (unsigned int i
= startPos
; i
< endPos
; i
++) {
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
) {
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;
356 lev
= levelPrevious
& SC_FOLDLEVELNUMBERMASK
;
361 lev
= SC_FOLDLEVELBASE
;
363 if (visibleChars
== 0 && foldCompact
)
364 lev
|= SC_FOLDLEVELWHITEFLAG
;
367 lev
|= SC_FOLDLEVELHEADERFLAG
;
369 if (lev
!= styler
.LevelAt(lineCurrent
)) {
370 styler
.SetLevel(lineCurrent
, lev
);
377 if (!isspacechar(ch
))
381 if (lineCurrent
> 0) {
382 int levelPrevious
= styler
.LevelAt(lineCurrent
- 1);
383 if (levelPrevious
& SC_FOLDLEVELHEADERFLAG
) {
384 lev
= SC_FOLDLEVELBASE
+ 1;
386 lev
= levelPrevious
& SC_FOLDLEVELNUMBERMASK
;
389 lev
= SC_FOLDLEVELBASE
;
391 int flagsNext
= styler
.LevelAt(lineCurrent
);
392 styler
.SetLevel(lineCurrent
, lev
| flagsNext
& ~SC_FOLDLEVELNUMBERMASK
);
395 static void ColouriseMakeLine(
397 unsigned int lengthLine
,
398 unsigned int startLine
,
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
])) {
410 if (lineBuffer
[i
] == '#') { // Comment
411 styler
.ColourTo(endPos
, SCE_MAKE_COMMENT
);
414 if (lineBuffer
[i
] == '!') { // Special directive
415 styler
.ColourTo(endPos
, SCE_MAKE_PREPROCESSOR
);
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
;
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
])) {
450 if (state
== SCE_MAKE_IDENTIFIER
) {
451 styler
.ColourTo(endPos
, SCE_MAKE_IDEOL
); // Error, variable reference not ended
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
);
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(
484 unsigned int lengthLine
,
485 // unsigned int startLine,
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 ")) {
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
);
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');
564 for (unsigned int i
= 0; i
< lengthLine
; i
++) {
565 char ch
= lineBuffer
[i
];
567 if ((i
+1) < lengthLine
)
568 chNext
= lineBuffer
[i
+1];
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 ':'.
577 } else if ((ch
== '(') && Is1To9(chNext
) && (!initialTab
)) {
579 // Check against '0' often removes phone numbers
581 } else if ((ch
== '\t') && (!initialTab
)) {
585 } else if (state
== 1) {
586 state
= Is1To9(ch
) ? 2 : unRecognized
;
587 } else if (state
== 2) {
589 state
= 3; // :9.*: is GCC
591 } else if (!Is0To9(ch
)) {
592 state
= unRecognized
;
594 } else if (state
== 10) {
595 state
= Is0To9(ch
) ? 11 : unRecognized
;
596 } else if (state
== 11) {
599 } else if (ch
== ')') {
601 } else if ((ch
!= ' ') && !Is0To9(ch
)) {
602 state
= unRecognized
;
604 } else if (state
== 12) {
605 if ((ch
== ' ') && (chNext
== ':')) {
608 state
= unRecognized
;
610 } else if (state
== 14) {
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
))) {
622 } else if ((ch
== '/') && (lineBuffer
[i
+1] == '^')) {
625 } else if ((state
== 21) && ((lineBuffer
[i
] == '$') && (lineBuffer
[i
+1] == '/'))) {
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
);
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
);
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
) {
668 unsigned int i
= 0, e
= 1;
670 s
[i
] = styler
[start
+ i
];
672 e
= styler
[start
+ i
] != '{';
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
++) {
690 chNext
= styler
.SafeGetCharAt(i
+ 1);
692 if (styler
.IsLeadByte(ch
)) {
693 chNext
= styler
.SafeGetCharAt(i
+ 2);
701 styler
.ColourTo(i
- 1, state
);
702 if (isSpecial(styler
[i
+ 1])) {
703 styler
.ColourTo(i
+ 1, SCE_L_COMMAND
);
705 chNext
= styler
.SafeGetCharAt(i
+ 1);
707 if (isTag(i
+ 1, styler
))
710 state
= SCE_L_COMMAND
;
714 styler
.ColourTo(i
- 1, state
);
718 chNext
= styler
.SafeGetCharAt(i
+ 1);
722 styler
.ColourTo(i
- 1, state
);
723 state
= SCE_L_COMMENT
;
728 if (chNext
== '[' || chNext
== '{' || chNext
== '}' ||
729 chNext
== ' ' || chNext
== '\r' || chNext
== '\n') {
730 styler
.ColourTo(i
, state
);
731 state
= SCE_L_DEFAULT
;
733 chNext
= styler
.SafeGetCharAt(i
+ 1);
738 styler
.ColourTo(i
, state
);
739 state
= SCE_L_DEFAULT
;
746 chNext
= styler
.SafeGetCharAt(i
+ 1);
748 styler
.ColourTo(i
, state
);
749 state
= SCE_L_DEFAULT
;
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
[] = {
767 static const char * const emptyWordListDesc
[] = {
771 static void ColouriseNullDoc(unsigned int startPos
, int length
, int, WordList
*[],
773 // Null language means all style bytes are 0 so just mark the end - no need to fill in.
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");