]>
git.saurik.com Git - wxWidgets.git/blob - contrib/src/stc/scintilla/src/LexOthers.cxx
f188722ff208fb7396934517a686dbbf71188970
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 inline bool AtEOL(Accessor
&styler
, unsigned int i
) {
24 return (styler
[i
] == '\n') ||
25 ((styler
[i
] == '\r') && (styler
.SafeGetCharAt(i
+ 1) != '\n'));
28 static void ColouriseBatchLine(
30 unsigned int lengthLine
,
31 unsigned int startLine
,
37 unsigned int state
= SCE_BAT_DEFAULT
;
39 while ((i
< lengthLine
) && isspacechar(lineBuffer
[i
])) { // Skip initial spaces
42 if (lineBuffer
[i
] == '@') { // Hide command (ECHO OFF)
43 styler
.ColourTo(startLine
+ i
, SCE_BAT_HIDE
);
45 while ((i
< lengthLine
) && isspacechar(lineBuffer
[i
])) { // Skip next spaces
49 if (lineBuffer
[i
] == ':') {
51 if (lineBuffer
[i
+ 1] == ':') {
52 // :: is a fake label, similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm
53 styler
.ColourTo(endPos
, SCE_BAT_COMMENT
);
54 } else { // Real label
55 styler
.ColourTo(endPos
, SCE_BAT_LABEL
);
58 // Check if initial word is a keyword
60 unsigned int wbl
= 0, offset
= i
;
61 // Copy word in buffer
62 for (; offset
< lengthLine
&& wbl
< 20 &&
63 !isspacechar(lineBuffer
[offset
]); wbl
++, offset
++) {
64 wordBuffer
[wbl
] = static_cast<char>(tolower(lineBuffer
[offset
]));
66 wordBuffer
[wbl
] = '\0';
67 // Check if it is a comment
68 if (CompareCaseInsensitive(wordBuffer
, "rem") == 0) {
69 styler
.ColourTo(endPos
, SCE_BAT_COMMENT
);
72 // Check if it is in the list
73 if (keywords
.InList(wordBuffer
)) {
74 styler
.ColourTo(startLine
+ offset
- 1, SCE_BAT_WORD
); // Regular keyword
76 // Search end of word (can be a long path)
77 while (offset
< lengthLine
&&
78 !isspacechar(lineBuffer
[offset
])) {
81 styler
.ColourTo(startLine
+ offset
- 1, SCE_BAT_COMMAND
); // External command / program
83 // Remainder of the line: colourise the variables.
85 while (offset
< lengthLine
) {
86 if (state
== SCE_BAT_DEFAULT
&& lineBuffer
[offset
] == '%') {
87 styler
.ColourTo(startLine
+ offset
- 1, state
);
88 if (isdigit(lineBuffer
[offset
+ 1])) {
89 styler
.ColourTo(startLine
+ offset
+ 1, SCE_BAT_IDENTIFIER
);
91 } else if (lineBuffer
[offset
+ 1] == '%' &&
92 !isspacechar(lineBuffer
[offset
+ 2])) {
93 // Should be safe, as there is CRLF at the end of the line...
94 styler
.ColourTo(startLine
+ offset
+ 2, SCE_BAT_IDENTIFIER
);
97 state
= SCE_BAT_IDENTIFIER
;
99 } else if (state
== SCE_BAT_IDENTIFIER
&& lineBuffer
[offset
] == '%') {
100 styler
.ColourTo(startLine
+ offset
, state
);
101 state
= SCE_BAT_DEFAULT
;
102 } else if (state
== SCE_BAT_DEFAULT
&&
103 (lineBuffer
[offset
] == '*' ||
104 lineBuffer
[offset
] == '?' ||
105 lineBuffer
[offset
] == '=' ||
106 lineBuffer
[offset
] == '<' ||
107 lineBuffer
[offset
] == '>' ||
108 lineBuffer
[offset
] == '|')) {
109 styler
.ColourTo(startLine
+ offset
- 1, state
);
110 styler
.ColourTo(startLine
+ offset
, SCE_BAT_OPERATOR
);
114 // if (endPos > startLine + offset - 1) {
115 styler
.ColourTo(endPos
, SCE_BAT_DEFAULT
); // Remainder of line, currently not lexed
120 // ToDo: (not necessarily at beginning of line) GOTO, [IF] NOT, ERRORLEVEL
121 // IF [NO] (test) (command) -- test is EXIST (filename) | (string1)==(string2) | ERRORLEVEL (number)
122 // FOR %%(variable) IN (set) DO (command) -- variable is [a-zA-Z] -- eg for %%X in (*.txt) do type %%X
123 // ToDo: %n (parameters), %EnvironmentVariable% colourising
124 // ToDo: Colourise = > >> < | "
126 static void ColouriseBatchDoc(
127 unsigned int startPos
,
130 WordList
*keywordlists
[],
133 char lineBuffer
[1024];
134 WordList
&keywords
= *keywordlists
[0];
136 styler
.StartAt(startPos
);
137 styler
.StartSegment(startPos
);
138 unsigned int linePos
= 0;
139 unsigned int startLine
= startPos
;
140 for (unsigned int i
= startPos
; i
< startPos
+ length
; i
++) {
141 lineBuffer
[linePos
++] = styler
[i
];
142 if (AtEOL(styler
, i
) || (linePos
>= sizeof(lineBuffer
) - 1)) {
143 // End of line (or of line buffer) met, colourise it
144 lineBuffer
[linePos
] = '\0';
145 ColouriseBatchLine(lineBuffer
, linePos
, startLine
, i
, keywords
, styler
);
150 if (linePos
> 0) { // Last line does not have ending characters
151 ColouriseBatchLine(lineBuffer
, linePos
, startLine
, startPos
+ length
- 1,
156 static void ColouriseDiffLine(char *lineBuffer
, int endLine
, Accessor
&styler
) {
157 // It is needed to remember the current state to recognize starting
158 // comment lines before the first "diff " or "--- ". If a real
159 // difference starts then each line starting with ' ' is a whitespace
160 // otherwise it is considered a comment (Only in..., Binary file...)
161 if (0 == strncmp(lineBuffer
, "diff ", 3)) {
162 styler
.ColourTo(endLine
, 2);
163 } else if (0 == strncmp(lineBuffer
, "--- ", 3)) {
164 styler
.ColourTo(endLine
, 3);
165 } else if (0 == strncmp(lineBuffer
, "+++ ", 3)) {
166 styler
.ColourTo(endLine
, 3);
167 } else if (lineBuffer
[0] == '@') {
168 styler
.ColourTo(endLine
, 4);
169 } else if (lineBuffer
[0] == '-') {
170 styler
.ColourTo(endLine
, 5);
171 } else if (lineBuffer
[0] == '+') {
172 styler
.ColourTo(endLine
, 6);
173 } else if (lineBuffer
[0] != ' ') {
174 styler
.ColourTo(endLine
, 1);
176 styler
.ColourTo(endLine
, 0);
180 static void ColouriseDiffDoc(unsigned int startPos
, int length
, int, WordList
*[], Accessor
&styler
) {
181 char lineBuffer
[1024];
182 styler
.StartAt(startPos
);
183 styler
.StartSegment(startPos
);
184 unsigned int linePos
= 0;
185 for (unsigned int i
= startPos
; i
< startPos
+ length
; i
++) {
186 lineBuffer
[linePos
++] = styler
[i
];
187 if (AtEOL(styler
, i
) || (linePos
>= sizeof(lineBuffer
) - 1)) {
188 // End of line (or of line buffer) met, colourise it
189 lineBuffer
[linePos
] = '\0';
190 ColouriseDiffLine(lineBuffer
, i
, styler
);
194 if (linePos
> 0) { // Last line does not have ending characters
195 ColouriseDiffLine(lineBuffer
, startPos
+ length
- 1, styler
);
199 static void ColourisePropsLine(
201 unsigned int lengthLine
,
202 unsigned int startLine
,
207 while ((i
< lengthLine
) && isspacechar(lineBuffer
[i
])) // Skip initial spaces
209 if (i
< lengthLine
) {
210 if (lineBuffer
[i
] == '#' || lineBuffer
[i
] == '!' || lineBuffer
[i
] == ';') {
211 styler
.ColourTo(endPos
, 1);
212 } else if (lineBuffer
[i
] == '[') {
213 styler
.ColourTo(endPos
, 2);
214 } else if (lineBuffer
[i
] == '@') {
215 styler
.ColourTo(startLine
+ i
, 4);
216 if (lineBuffer
[++i
] == '=')
217 styler
.ColourTo(startLine
+ i
, 3);
218 styler
.ColourTo(endPos
, 0);
220 // Search for the '=' character
221 while ((i
< lengthLine
) && (lineBuffer
[i
] != '='))
223 if ((i
< lengthLine
) && (lineBuffer
[i
] == '=')) {
224 styler
.ColourTo(startLine
+ i
- 1, 0);
225 styler
.ColourTo(startLine
+ i
, 3);
226 styler
.ColourTo(endPos
, 0);
228 styler
.ColourTo(endPos
, 0);
232 styler
.ColourTo(endPos
, 0);
236 static void ColourisePropsDoc(unsigned int startPos
, int length
, int, WordList
*[], Accessor
&styler
) {
237 char lineBuffer
[1024];
238 styler
.StartAt(startPos
);
239 styler
.StartSegment(startPos
);
240 unsigned int linePos
= 0;
241 unsigned int startLine
= startPos
;
242 for (unsigned int i
= startPos
; i
< startPos
+ length
; i
++) {
243 lineBuffer
[linePos
++] = styler
[i
];
244 if (AtEOL(styler
, i
) || (linePos
>= sizeof(lineBuffer
) - 1)) {
245 // End of line (or of line buffer) met, colourise it
246 lineBuffer
[linePos
] = '\0';
247 ColourisePropsLine(lineBuffer
, linePos
, startLine
, i
, styler
);
252 if (linePos
> 0) { // Last line does not have ending characters
253 ColourisePropsLine(lineBuffer
, linePos
, startLine
, startPos
+ length
- 1, styler
);
257 static void ColouriseMakeLine(
259 unsigned int lengthLine
,
260 unsigned int startLine
,
265 unsigned int lastNonSpace
= 0;
266 unsigned int state
= SCE_MAKE_DEFAULT
;
267 bool bSpecial
= false;
268 // Skip initial spaces
269 while ((i
< lengthLine
) && isspacechar(lineBuffer
[i
])) {
272 if (lineBuffer
[i
] == '#') { // Comment
273 styler
.ColourTo(endPos
, SCE_MAKE_COMMENT
);
276 if (lineBuffer
[i
] == '!') { // Special directive
277 styler
.ColourTo(endPos
, SCE_MAKE_PREPROCESSOR
);
280 while (i
< lengthLine
) {
281 if (lineBuffer
[i
] == '$' && lineBuffer
[i
+ 1] == '(') {
282 styler
.ColourTo(startLine
+ i
- 1, state
);
283 state
= SCE_MAKE_IDENTIFIER
;
284 } else if (state
== SCE_MAKE_IDENTIFIER
&& lineBuffer
[i
] == ')') {
285 styler
.ColourTo(startLine
+ i
, state
);
286 state
= SCE_MAKE_DEFAULT
;
289 if (lineBuffer
[i
] == ':') {
290 // We should check that no colouring was made since the beginning of the line,
291 // to avoid colouring stuff like /OUT:file
292 styler
.ColourTo(startLine
+ lastNonSpace
, SCE_MAKE_TARGET
);
293 styler
.ColourTo(startLine
+ i
- 1, SCE_MAKE_DEFAULT
);
294 styler
.ColourTo(startLine
+ i
, SCE_MAKE_OPERATOR
);
295 bSpecial
= true; // Only react to the first ':' of the line
296 state
= SCE_MAKE_DEFAULT
;
297 } else if (lineBuffer
[i
] == '=') {
298 styler
.ColourTo(startLine
+ lastNonSpace
, SCE_MAKE_IDENTIFIER
);
299 styler
.ColourTo(startLine
+ i
- 1, SCE_MAKE_DEFAULT
);
300 styler
.ColourTo(startLine
+ i
, SCE_MAKE_OPERATOR
);
301 bSpecial
= true; // Only react to the first '=' of the line
302 state
= SCE_MAKE_DEFAULT
;
305 if (!isspacechar(lineBuffer
[i
])) {
310 if (state
== SCE_MAKE_IDENTIFIER
) {
311 styler
.ColourTo(endPos
, SCE_MAKE_IDEOL
); // Error, variable reference not ended
313 styler
.ColourTo(endPos
, SCE_MAKE_DEFAULT
);
317 static void ColouriseMakeDoc(unsigned int startPos
, int length
, int, WordList
*[], Accessor
&styler
) {
318 char lineBuffer
[1024];
319 styler
.StartAt(startPos
);
320 styler
.StartSegment(startPos
);
321 unsigned int linePos
= 0;
322 unsigned int startLine
= startPos
;
323 for (unsigned int i
= startPos
; i
< startPos
+ length
; i
++) {
324 lineBuffer
[linePos
++] = styler
[i
];
325 if (AtEOL(styler
, i
) || (linePos
>= sizeof(lineBuffer
) - 1)) {
326 // End of line (or of line buffer) met, colourise it
327 lineBuffer
[linePos
] = '\0';
328 ColouriseMakeLine(lineBuffer
, linePos
, startLine
, i
, styler
);
333 if (linePos
> 0) { // Last line does not have ending characters
334 ColouriseMakeLine(lineBuffer
, linePos
, startLine
, startPos
+ length
- 1, styler
);
338 static void ColouriseErrorListLine(
340 unsigned int lengthLine
,
341 // unsigned int startLine,
344 if (lineBuffer
[0] == '>') {
345 // Command or return status
346 styler
.ColourTo(endPos
, SCE_ERR_CMD
);
347 } else if (lineBuffer
[0] == '!') {
348 styler
.ColourTo(endPos
, SCE_ERR_DIFF_CHANGED
);
349 } else if (lineBuffer
[0] == '+') {
350 styler
.ColourTo(endPos
, SCE_ERR_DIFF_ADDITION
);
351 } else if (lineBuffer
[0] == '-' && lineBuffer
[1] == '-' && lineBuffer
[2] == '-') {
352 styler
.ColourTo(endPos
, SCE_ERR_DIFF_MESSAGE
);
353 } else if (lineBuffer
[0] == '-') {
354 styler
.ColourTo(endPos
, SCE_ERR_DIFF_DELETION
);
355 } else if (strstr(lineBuffer
, "File \"") && strstr(lineBuffer
, ", line ")) {
356 styler
.ColourTo(endPos
, SCE_ERR_PYTHON
);
357 } else if (0 == strncmp(lineBuffer
, "Error ", strlen("Error "))) {
358 // Borland error message
359 styler
.ColourTo(endPos
, SCE_ERR_BORLAND
);
360 } else if (0 == strncmp(lineBuffer
, "Warning ", strlen("Warning "))) {
361 // Borland warning message
362 styler
.ColourTo(endPos
, SCE_ERR_BORLAND
);
363 } else if (strstr(lineBuffer
, "at line " ) &&
364 (strstr(lineBuffer
, "at line " ) < (lineBuffer
+ lengthLine
)) &&
365 strstr(lineBuffer
, "file ") &&
366 (strstr(lineBuffer
, "file ") < (lineBuffer
+ lengthLine
))) {
368 styler
.ColourTo(endPos
, SCE_ERR_LUA
);
369 } else if (strstr(lineBuffer
, " at " ) &&
370 (strstr(lineBuffer
, " at " ) < (lineBuffer
+ lengthLine
)) &&
371 strstr(lineBuffer
, " line ") &&
372 (strstr(lineBuffer
, " line ") < (lineBuffer
+ lengthLine
))) {
373 // perl error message
374 styler
.ColourTo(endPos
, SCE_ERR_PERL
);
375 } else if ((memcmp(lineBuffer
, " at ", 6) == 0) &&
376 strstr(lineBuffer
, ":line ")) {
378 styler
.ColourTo(endPos
, SCE_ERR_NET
);
380 // Look for <filename>:<line>:message
381 // Look for <filename>(line)message
382 // Look for <filename>(line,pos)message
384 for (unsigned int i
= 0; i
< lengthLine
; i
++) {
385 if ((state
== 0) && (lineBuffer
[i
] == ':') && isdigit(lineBuffer
[i
+ 1])) {
387 } else if ((state
== 0) && (lineBuffer
[i
] == '(')) {
389 } else if ((state
== 1) && isdigit(lineBuffer
[i
])) {
391 } else if ((state
== 2) && (lineBuffer
[i
] == ':')) {
394 } else if ((state
== 2) && !isdigit(lineBuffer
[i
])) {
396 } else if ((state
== 10) && isdigit(lineBuffer
[i
])) {
398 } else if ((state
== 11) && (lineBuffer
[i
] == ',')) {
400 } else if ((state
== 11) && (lineBuffer
[i
] == ')')) {
402 } else if ((state
== 12) && (lineBuffer
[i
] == ':')) {
404 } else if ((state
== 14) && (lineBuffer
[i
] == ')')) {
407 } else if (((state
== 11) || (state
== 14)) && !((lineBuffer
[i
] == ' ') || isdigit(lineBuffer
[i
]))) {
412 styler
.ColourTo(endPos
, SCE_ERR_GCC
);
413 } else if ((state
== 13) || (state
== 14) || (state
== 15)) {
414 styler
.ColourTo(endPos
, SCE_ERR_MS
);
416 styler
.ColourTo(endPos
, SCE_ERR_DEFAULT
);
421 static void ColouriseErrorListDoc(unsigned int startPos
, int length
, int, WordList
*[], Accessor
&styler
) {
422 char lineBuffer
[1024];
423 styler
.StartAt(startPos
);
424 styler
.StartSegment(startPos
);
425 unsigned int linePos
= 0;
426 for (unsigned int i
= startPos
; i
< startPos
+ length
; i
++) {
427 lineBuffer
[linePos
++] = styler
[i
];
428 if (AtEOL(styler
, i
) || (linePos
>= sizeof(lineBuffer
) - 1)) {
429 // End of line (or of line buffer) met, colourise it
430 lineBuffer
[linePos
] = '\0';
431 ColouriseErrorListLine(lineBuffer
, linePos
, i
, styler
);
435 if (linePos
> 0) { // Last line does not have ending characters
436 ColouriseErrorListLine(lineBuffer
, linePos
, startPos
+ length
- 1, styler
);
440 static int isSpecial(char s
) {
441 return (s
== '\\') || (s
== ',') || (s
== ';') || (s
== '\'') || (s
== ' ') ||
442 (s
== '\"') || (s
== '`') || (s
== '^') || (s
== '~');
445 static int isTag(int start
, Accessor
&styler
) {
447 unsigned int i
= 0, e
= 1;
449 s
[i
] = styler
[start
+ i
];
451 e
= styler
[start
+ i
] != '{';
454 return (strcmp(s
, "begin") == 0) || (strcmp(s
, "end") == 0);
457 static void ColouriseLatexDoc(unsigned int startPos
, int length
, int initStyle
,
458 WordList
*[], Accessor
&styler
) {
460 styler
.StartAt(startPos
);
462 int state
= initStyle
;
463 char chNext
= styler
[startPos
];
464 styler
.StartSegment(startPos
);
465 int lengthDoc
= startPos
+ length
;
467 for (int i
= startPos
; i
< lengthDoc
; i
++) {
469 chNext
= styler
.SafeGetCharAt(i
+ 1);
471 if (styler
.IsLeadByte(ch
)) {
472 chNext
= styler
.SafeGetCharAt(i
+ 2);
480 styler
.ColourTo(i
- 1, state
);
481 if (isSpecial(styler
[i
+ 1])) {
482 styler
.ColourTo(i
+ 1, SCE_L_COMMAND
);
484 chNext
= styler
.SafeGetCharAt(i
+ 1);
486 if (isTag(i
+ 1, styler
))
489 state
= SCE_L_COMMAND
;
493 styler
.ColourTo(i
- 1, state
);
497 chNext
= styler
.SafeGetCharAt(i
+ 1);
501 styler
.ColourTo(i
- 1, state
);
502 state
= SCE_L_COMMENT
;
507 if (chNext
== '[' || chNext
== '{' || chNext
== '}' ||
508 chNext
== ' ' || chNext
== '\r' || chNext
== '\n') {
509 styler
.ColourTo(i
, state
);
510 state
= SCE_L_DEFAULT
;
512 chNext
= styler
.SafeGetCharAt(i
+ 1);
517 styler
.ColourTo(i
, state
);
518 state
= SCE_L_DEFAULT
;
525 chNext
= styler
.SafeGetCharAt(i
+ 1);
527 styler
.ColourTo(i
, state
);
528 state
= SCE_L_DEFAULT
;
532 if (ch
== '\r' || ch
== '\n') {
533 styler
.ColourTo(i
- 1, state
);
534 state
= SCE_L_DEFAULT
;
538 styler
.ColourTo(lengthDoc
, state
);
541 LexerModule
lmBatch(SCLEX_BATCH
, ColouriseBatchDoc
, "batch");
542 LexerModule
lmDiff(SCLEX_DIFF
, ColouriseDiffDoc
, "diff");
543 LexerModule
lmProps(SCLEX_PROPERTIES
, ColourisePropsDoc
, "props");
544 LexerModule
lmMake(SCLEX_MAKEFILE
, ColouriseMakeDoc
, "makefile");
545 LexerModule
lmErrorList(SCLEX_ERRORLIST
, ColouriseErrorListDoc
, "errorlist");
546 LexerModule
lmLatex(SCLEX_LATEX
, ColouriseLatexDoc
, "latex");