]>
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 void ColouriseBatchLine(
25 unsigned int lengthLine
,
26 unsigned int startLine
,
32 unsigned int state
= SCE_BAT_DEFAULT
;
34 while (isspacechar(lineBuffer
[i
]) && (i
< lengthLine
)) { // Skip initial spaces
37 if (lineBuffer
[i
] == '@') { // Hide command (ECHO OFF)
38 styler
.ColourTo(startLine
+ i
, SCE_BAT_HIDE
);
40 while (isspacechar(lineBuffer
[i
]) && (i
< lengthLine
)) { // Skip next spaces
44 if (lineBuffer
[i
] == ':') {
46 if (lineBuffer
[i
+ 1] == ':') {
47 // :: is a fake label, similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm
48 styler
.ColourTo(endPos
, SCE_BAT_COMMENT
);
49 } else { // Real label
50 styler
.ColourTo(endPos
, SCE_BAT_LABEL
);
53 // Check if initial word is a keyword
55 unsigned int wbl
= 0, offset
= i
;
56 // Copy word in buffer
57 for (; offset
< lengthLine
&& wbl
< 20 &&
58 !isspacechar(lineBuffer
[offset
]); wbl
++, offset
++) {
59 wordBuffer
[wbl
] = static_cast<char>(tolower(lineBuffer
[offset
]));
61 wordBuffer
[wbl
] = '\0';
62 // Check if it is a comment
63 if (CompareCaseInsensitive(wordBuffer
, "rem") == 0) {
64 styler
.ColourTo(endPos
, SCE_BAT_COMMENT
);
67 // Check if it is in the list
68 if (keywords
.InList(wordBuffer
)) {
69 styler
.ColourTo(startLine
+ offset
- 1, SCE_BAT_WORD
); // Regular keyword
71 // Search end of word (can be a long path)
72 while (offset
< lengthLine
&&
73 !isspacechar(lineBuffer
[offset
])) {
76 styler
.ColourTo(startLine
+ offset
- 1, SCE_BAT_COMMAND
); // External command / program
78 // Remainder of the line: colourise the variables.
80 while (offset
< lengthLine
) {
81 if (state
== SCE_BAT_DEFAULT
&& lineBuffer
[offset
] == '%') {
82 styler
.ColourTo(startLine
+ offset
- 1, state
);
83 if (isdigit(lineBuffer
[offset
+ 1])) {
84 styler
.ColourTo(startLine
+ offset
+ 1, SCE_BAT_IDENTIFIER
);
86 } else if (lineBuffer
[offset
+ 1] == '%' &&
87 !isspacechar(lineBuffer
[offset
+ 2])) {
88 // Should be safe, as there is CRLF at the end of the line...
89 styler
.ColourTo(startLine
+ offset
+ 2, SCE_BAT_IDENTIFIER
);
92 state
= SCE_BAT_IDENTIFIER
;
94 } else if (state
== SCE_BAT_IDENTIFIER
&& lineBuffer
[offset
] == '%') {
95 styler
.ColourTo(startLine
+ offset
, state
);
96 state
= SCE_BAT_DEFAULT
;
97 } else if (state
== SCE_BAT_DEFAULT
&&
98 (lineBuffer
[offset
] == '*' ||
99 lineBuffer
[offset
] == '?' ||
100 lineBuffer
[offset
] == '=' ||
101 lineBuffer
[offset
] == '<' ||
102 lineBuffer
[offset
] == '>' ||
103 lineBuffer
[offset
] == '|')) {
104 styler
.ColourTo(startLine
+ offset
- 1, state
);
105 styler
.ColourTo(startLine
+ offset
, SCE_BAT_OPERATOR
);
109 // if (endPos > startLine + offset - 1) {
110 styler
.ColourTo(endPos
, SCE_BAT_DEFAULT
); // Remainder of line, currently not lexed
115 // ToDo: (not necessarily at beginning of line) GOTO, [IF] NOT, ERRORLEVEL
116 // IF [NO] (test) (command) -- test is EXIST (filename) | (string1)==(string2) | ERRORLEVEL (number)
117 // FOR %%(variable) IN (set) DO (command) -- variable is [a-zA-Z] -- eg for %%X in (*.txt) do type %%X
118 // ToDo: %n (parameters), %EnvironmentVariable% colourising
119 // ToDo: Colourise = > >> < | "
121 static void ColouriseBatchDoc(
122 unsigned int startPos
,
125 WordList
*keywordlists
[],
128 char lineBuffer
[1024];
129 WordList
&keywords
= *keywordlists
[0];
131 styler
.StartAt(startPos
);
132 styler
.StartSegment(startPos
);
133 unsigned int linePos
= 0, startLine
= startPos
;
134 for (unsigned int i
= startPos
; i
<= startPos
+ length
; i
++) {
135 lineBuffer
[linePos
++] = styler
[i
];
136 if (styler
[i
] == '\r' || styler
[i
] == '\n' || (linePos
>=
137 sizeof(lineBuffer
) - 1)) {
138 // End of line (or of line buffer) met, colourise it
139 if (styler
[i
+ 1] == '\n') {
140 lineBuffer
[linePos
++] = styler
[++i
];
142 lineBuffer
[linePos
] = '\0';
143 ColouriseBatchLine(lineBuffer
, linePos
, startLine
, i
, keywords
, styler
);
149 ColouriseBatchLine(lineBuffer
, linePos
, startLine
, startPos
+ length
,
154 static void ColouriseDiffLine(char *lineBuffer
, int endLine
, Accessor
&styler
) {
155 // It is needed to remember the current state to recognize starting
156 // comment lines before the first "diff " or "--- ". If a real
157 // difference starts then each line starting with ' ' is a whitespace
158 // otherwise it is considered a comment (Only in..., Binary file...)
159 if (0 == strncmp(lineBuffer
, "diff ", 3)) {
160 styler
.ColourTo(endLine
, 2);
161 } else if (0 == strncmp(lineBuffer
, "--- ", 3)) {
162 styler
.ColourTo(endLine
, 3);
163 } else if (0 == strncmp(lineBuffer
, "+++ ", 3)) {
164 styler
.ColourTo(endLine
, 3);
165 } else if (lineBuffer
[0] == '@') {
166 styler
.ColourTo(endLine
, 4);
167 } else if (lineBuffer
[0] == '-') {
168 styler
.ColourTo(endLine
, 5);
169 } else if (lineBuffer
[0] == '+') {
170 styler
.ColourTo(endLine
, 6);
171 } else if (lineBuffer
[0] != ' ') {
172 styler
.ColourTo(endLine
, 1);
174 styler
.ColourTo(endLine
, 0);
178 static void ColouriseDiffDoc(unsigned int startPos
, int length
, int, WordList
*[], Accessor
&styler
) {
179 char lineBuffer
[1024];
180 styler
.StartAt(startPos
);
181 styler
.StartSegment(startPos
);
182 unsigned int linePos
= 0;
183 for (unsigned int i
= startPos
; i
< startPos
+ length
; i
++) {
184 lineBuffer
[linePos
++] = styler
[i
];
185 if (styler
[i
] == '\r' || styler
[i
] == '\n' || (linePos
>= sizeof(lineBuffer
) - 1)) {
186 ColouriseDiffLine(lineBuffer
, i
, styler
);
191 ColouriseDiffLine(lineBuffer
, startPos
+ length
, styler
);
194 static void ColourisePropsLine(
196 unsigned int lengthLine
,
197 unsigned int startLine
,
202 while (isspacechar(lineBuffer
[i
]) && (i
< lengthLine
)) // Skip initial spaces
204 if (lineBuffer
[i
] == '#' || lineBuffer
[i
] == '!' || lineBuffer
[i
] == ';') {
205 styler
.ColourTo(endPos
, 1);
206 } else if (lineBuffer
[i
] == '[') {
207 styler
.ColourTo(endPos
, 2);
208 } else if (lineBuffer
[i
] == '@') {
209 styler
.ColourTo(startLine
+ i
, 4);
210 if (lineBuffer
[++i
] == '=')
211 styler
.ColourTo(startLine
+ i
, 3);
212 styler
.ColourTo(endPos
, 0);
214 // Search for the '=' character
215 while (lineBuffer
[i
] != '=' && (i
< lengthLine
- 1))
217 if (lineBuffer
[i
] == '=') {
218 styler
.ColourTo(startLine
+ i
- 1, 0);
219 styler
.ColourTo(startLine
+ i
, 3);
220 styler
.ColourTo(endPos
, 0);
222 styler
.ColourTo(endPos
, 0);
227 static void ColourisePropsDoc(unsigned int startPos
, int length
, int, WordList
*[], Accessor
&styler
) {
228 char lineBuffer
[1024];
229 styler
.StartAt(startPos
);
230 styler
.StartSegment(startPos
);
231 unsigned int linePos
= 0, startLine
= startPos
;
232 for (unsigned int i
= startPos
; i
<= startPos
+ length
; i
++) {
233 lineBuffer
[linePos
++] = styler
[i
];
234 if ((styler
[i
] == '\r' && styler
.SafeGetCharAt(i
+ 1) != '\n') ||
236 (linePos
>= sizeof(lineBuffer
) - 1)) {
237 lineBuffer
[linePos
] = '\0';
238 ColourisePropsLine(lineBuffer
, linePos
, startLine
, i
, styler
);
244 ColourisePropsLine(lineBuffer
, linePos
, startLine
, startPos
+ length
, styler
);
247 static void ColouriseMakeLine(
249 unsigned int lengthLine
,
250 unsigned int startLine
,
255 unsigned int lastNonSpace
= 0;
256 unsigned int state
= SCE_MAKE_DEFAULT
;
257 bool bSpecial
= false;
258 // Skip initial spaces
259 while (isspacechar(lineBuffer
[i
]) && (i
< lengthLine
)) {
262 if (lineBuffer
[i
] == '#') { // Comment
263 styler
.ColourTo(endPos
, SCE_MAKE_COMMENT
);
266 if (lineBuffer
[i
] == '!') { // Special directive
267 styler
.ColourTo(endPos
, SCE_MAKE_PREPROCESSOR
);
270 while (i
< lengthLine
) {
271 if (lineBuffer
[i
] == '$' && lineBuffer
[i
+ 1] == '(') {
272 styler
.ColourTo(startLine
+ i
- 1, state
);
273 state
= SCE_MAKE_IDENTIFIER
;
274 } else if (state
== SCE_MAKE_IDENTIFIER
&& lineBuffer
[i
] == ')') {
275 styler
.ColourTo(startLine
+ i
, state
);
276 state
= SCE_MAKE_DEFAULT
;
279 if (lineBuffer
[i
] == ':') {
280 styler
.ColourTo(startLine
+ lastNonSpace
, SCE_MAKE_TARGET
);
281 styler
.ColourTo(startLine
+ i
- 1, SCE_MAKE_DEFAULT
);
282 styler
.ColourTo(startLine
+ i
, SCE_MAKE_OPERATOR
);
283 bSpecial
= true; // Only react to the first ':' of the line
284 state
= SCE_MAKE_DEFAULT
;
285 } else if (lineBuffer
[i
] == '=') {
286 styler
.ColourTo(startLine
+ lastNonSpace
, SCE_MAKE_IDENTIFIER
);
287 styler
.ColourTo(startLine
+ i
- 1, SCE_MAKE_DEFAULT
);
288 styler
.ColourTo(startLine
+ i
, SCE_MAKE_OPERATOR
);
289 bSpecial
= true; // Only react to the first '=' of the line
290 state
= SCE_MAKE_DEFAULT
;
293 if (!isspacechar(lineBuffer
[i
])) {
298 if (state
== SCE_MAKE_IDENTIFIER
) {
299 styler
.ColourTo(endPos
, SCE_MAKE_IDEOL
); // Error, variable reference not ended
301 styler
.ColourTo(endPos
, SCE_MAKE_DEFAULT
);
305 static void ColouriseMakeDoc(unsigned int startPos
, int length
, int, WordList
*[], Accessor
&styler
) {
306 char lineBuffer
[1024];
307 styler
.StartAt(startPos
);
308 styler
.StartSegment(startPos
);
309 unsigned int linePos
= 0, startLine
= startPos
;
310 for (unsigned int i
= startPos
; i
<= startPos
+ length
; i
++) {
311 lineBuffer
[linePos
++] = styler
[i
];
312 if (styler
[i
] == '\r' || styler
[i
] == '\n' || (linePos
>= sizeof(lineBuffer
) - 1)) {
313 lineBuffer
[linePos
] = '\0';
314 ColouriseMakeLine(lineBuffer
, linePos
, startLine
, i
, styler
);
320 ColouriseMakeLine(lineBuffer
, linePos
, startLine
, startPos
+ length
, styler
);
324 static void ColouriseErrorListLine(
326 unsigned int lengthLine
,
327 // unsigned int startLine,
330 if (lineBuffer
[0] == '>') {
331 // Command or return status
332 styler
.ColourTo(endPos
, SCE_ERR_CMD
);
333 } else if (lineBuffer
[0] == '!') {
334 styler
.ColourTo(endPos
, SCE_ERR_DIFF_CHANGED
);
335 } else if (lineBuffer
[0] == '+') {
336 styler
.ColourTo(endPos
, SCE_ERR_DIFF_ADDITION
);
337 } else if (lineBuffer
[0] == '-' && lineBuffer
[1] == '-' && lineBuffer
[2] == '-') {
338 styler
.ColourTo(endPos
, SCE_ERR_DIFF_MESSAGE
);
339 } else if (lineBuffer
[0] == '-') {
340 styler
.ColourTo(endPos
, SCE_ERR_DIFF_DELETION
);
341 } else if (strstr(lineBuffer
, "File \"") && strstr(lineBuffer
, ", line ")) {
342 styler
.ColourTo(endPos
, SCE_ERR_PYTHON
);
343 } else if (0 == strncmp(lineBuffer
, "Error ", strlen("Error "))) {
344 // Borland error message
345 styler
.ColourTo(endPos
, SCE_ERR_BORLAND
);
346 } else if (0 == strncmp(lineBuffer
, "Warning ", strlen("Warning "))) {
347 // Borland warning message
348 styler
.ColourTo(endPos
, SCE_ERR_BORLAND
);
349 } else if (strstr(lineBuffer
, "at line " ) &&
350 strstr(lineBuffer
, "at line " ) < lineBuffer
+ lengthLine
&&
351 strstr(lineBuffer
, "file ") &&
352 strstr(lineBuffer
, "file ") < lineBuffer
+ lengthLine
) {
354 styler
.ColourTo(endPos
, SCE_ERR_LUA
);
355 } else if (strstr(lineBuffer
, " at " ) &&
356 strstr(lineBuffer
, " at " ) < lineBuffer
+ lengthLine
&&
357 strstr(lineBuffer
, " line ") &&
358 strstr(lineBuffer
, " line ") < lineBuffer
+ lengthLine
) {
359 // perl error message
360 styler
.ColourTo(endPos
, SCE_ERR_PERL
);
361 } else if ((memcmp(lineBuffer
, " at ", 6) == 0) &&
362 strstr(lineBuffer
, ":line ")) {
364 styler
.ColourTo(endPos
, SCE_ERR_NET
);
366 // Look for <filename>:<line>:message
367 // Look for <filename>(line)message
368 // Look for <filename>(line,pos)message
370 for (unsigned int i
= 0; i
< lengthLine
; i
++) {
371 if (state
== 0 && lineBuffer
[i
] == ':' && isdigit(lineBuffer
[i
+ 1])) {
373 } else if (state
== 0 && lineBuffer
[i
] == '(') {
375 } else if (state
== 1 && isdigit(lineBuffer
[i
])) {
377 } else if (state
== 2 && lineBuffer
[i
] == ':') {
380 } else if (state
== 2 && !isdigit(lineBuffer
[i
])) {
382 } else if (state
== 10 && isdigit(lineBuffer
[i
])) {
384 } else if (state
== 11 && lineBuffer
[i
] == ',') {
386 } else if (state
== 11 && lineBuffer
[i
] == ')') {
388 } else if (state
== 12 && lineBuffer
[i
] == ':') {
390 } else if (state
== 14 && lineBuffer
[i
] == ')') {
393 } else if (((state
== 11) || (state
== 14)) && !((lineBuffer
[i
] == ' ') || isdigit(lineBuffer
[i
]))) {
398 styler
.ColourTo(endPos
, SCE_ERR_GCC
);
399 } else if ((state
== 13) || (state
== 14) || (state
== 15)) {
400 styler
.ColourTo(endPos
, SCE_ERR_MS
);
402 styler
.ColourTo(endPos
, SCE_ERR_DEFAULT
);
407 static void ColouriseErrorListDoc(unsigned int startPos
, int length
, int, WordList
*[], Accessor
&styler
) {
408 char lineBuffer
[1024];
409 styler
.StartAt(startPos
);
410 styler
.StartSegment(startPos
);
411 unsigned int linePos
= 0;
412 for (unsigned int i
= startPos
; i
<= startPos
+ length
; i
++) {
413 lineBuffer
[linePos
++] = styler
[i
];
414 if (styler
[i
] == '\r' || styler
[i
] == '\n' || (linePos
>= sizeof(lineBuffer
) - 1)) {
415 ColouriseErrorListLine(lineBuffer
, linePos
, i
, styler
);
420 ColouriseErrorListLine(lineBuffer
, linePos
, startPos
+ length
, styler
);
423 static int isSpecial(char s
) {
424 return (s
== '\\') || (s
== ',') || (s
== ';') || (s
== '\'') || (s
== ' ') ||
425 (s
== '\"') || (s
== '`') || (s
== '^') || (s
== '~');
428 static int isTag(int start
, Accessor
&styler
) {
430 unsigned int i
= 0, e
= 1;
432 s
[i
] = styler
[start
+ i
];
434 e
= styler
[start
+ i
] != '{';
437 return (strcmp(s
, "begin") == 0) || (strcmp(s
, "end") == 0);
440 static void ColouriseLatexDoc(unsigned int startPos
, int length
, int initStyle
,
441 WordList
*[], Accessor
&styler
) {
443 styler
.StartAt(startPos
);
445 int state
= initStyle
;
446 char chNext
= styler
[startPos
];
447 styler
.StartSegment(startPos
);
448 int lengthDoc
= startPos
+ length
;
450 for (int i
= startPos
; i
< lengthDoc
; i
++) {
452 chNext
= styler
.SafeGetCharAt(i
+ 1);
454 if (styler
.IsLeadByte(ch
)) {
455 chNext
= styler
.SafeGetCharAt(i
+ 2);
463 styler
.ColourTo(i
- 1, state
);
464 if (isSpecial(styler
[i
+ 1])) {
465 styler
.ColourTo(i
+ 1, SCE_L_COMMAND
);
467 chNext
= styler
.SafeGetCharAt(i
+ 1);
469 if (isTag(i
+ 1, styler
))
472 state
= SCE_L_COMMAND
;
476 styler
.ColourTo(i
- 1, state
);
480 chNext
= styler
.SafeGetCharAt(i
+ 1);
484 styler
.ColourTo(i
- 1, state
);
485 state
= SCE_L_COMMENT
;
490 if (chNext
== '[' || chNext
== '{' || chNext
== '}' ||
491 chNext
== ' ' || chNext
== '\r' || chNext
== '\n') {
492 styler
.ColourTo(i
, state
);
493 state
= SCE_L_DEFAULT
;
495 chNext
= styler
.SafeGetCharAt(i
+ 1);
500 styler
.ColourTo(i
, state
);
501 state
= SCE_L_DEFAULT
;
508 chNext
= styler
.SafeGetCharAt(i
+ 1);
510 styler
.ColourTo(i
, state
);
511 state
= SCE_L_DEFAULT
;
515 if (ch
== '\r' || ch
== '\n') {
516 styler
.ColourTo(i
- 1, state
);
517 state
= SCE_L_DEFAULT
;
521 styler
.ColourTo(lengthDoc
, state
);
524 LexerModule
lmBatch(SCLEX_BATCH
, ColouriseBatchDoc
, "batch");
525 LexerModule
lmDiff(SCLEX_DIFF
, ColouriseDiffDoc
, "diff");
526 LexerModule
lmProps(SCLEX_PROPERTIES
, ColourisePropsDoc
, "props");
527 LexerModule
lmMake(SCLEX_MAKEFILE
, ColouriseMakeDoc
, "makefile");
528 LexerModule
lmErrorList(SCLEX_ERRORLIST
, ColouriseErrorListDoc
, "errorlist");
529 LexerModule
lmLatex(SCLEX_LATEX
, ColouriseLatexDoc
, "latex");