| 29 skipped lines |
|
| 31 | U | 31 | U | static inline bool AtEOL(Accessor &styler, unsigned int i) { |
|
| 32 | U | 32 | U | return (styler[i] == '\n') || |
|
| 33 | C | ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')); | | 33 | C | ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')); |
| | | 34 | C | } |
| | | 35 | C | |
| | | 36 | C | // Tests for BATCH Operators |
| | | 37 | C | static bool IsBOperator(char ch) { |
| | | 38 | C | return (ch == '=') || (ch == '+') || (ch == '>') || (ch == '<') || |
| | | 39 | C | (ch == '|') || (ch == '?') || (ch == '*'); |
| | | 40 | C | } |
| | | 41 | C | |
| | | 42 | C | // Tests for BATCH Separators |
| | | 43 | C | static bool IsBSeparator(char ch) { |
| | | 44 | C | return (ch == ':') || (ch == '\\') || (ch == '.') || (ch == ';') || |
| | | 45 | C | (ch == '\"') || (ch == '\'') || (ch == '/') || (ch == ')'); |
|
|
| 36 | U | 48 | U | static void ColouriseBatchLine( |
|
| 4 skipped lines |
| 41 | U | 53 | U | WordList &keywords, |
|
| 42 | U | 54 | U | Accessor &styler) { |
|
|
| 44 | C | unsigned int i = 0; | | 56 | C | unsigned int offset = 0;// Line Buffer Offset |
| | | 57 | C | unsigned int enVarEnd; // Environment Variable End point |
| | | 58 | C | unsigned int cmdLoc;// External Command / Program Location |
| | | 59 | C | char wordBuffer[81];// Word Buffer - large to catch long paths |
| | | 60 | C | unsigned int wbl; // Word Buffer Length |
| 45 | C | unsigned int state = SCE_BAT_DEFAULT; | | 61 | C | unsigned int wbo; // Word Buffer Offset - also Special Keyword Buffer Length |
| | | 62 | C | bool forFound = false; // No Local Variable without FOR statement |
| | | 63 | C | // CHOICE, ECHO, GOTO, PROMPT and SET have Default Text that may contain Regular Keywords |
| | | 64 | C | // Toggling Regular Keyword Checking off improves readability |
| | | 65 | C | // Other Regular Keywords and External Commands / Programs might also benefit from toggling |
| | | 66 | C | // Need a more robust algorithm to properly toggle Regular Keyword Checking |
| | | 67 | C | bool continueProcessing = true; // Used to toggle Regular Keyword Checking |
| | | 68 | C | // Special Keywords are those that allow certain characters without whitespace after the command |
| | | 69 | C | // Examples are: cd. cd\ md. rd. dir| dir> echo: echo. path= |
| | | 70 | C | // Special Keyword Buffer used to determine if the first n characters is a Keyword |
| | | 71 | C | char sKeywordBuffer[10];// Special Keyword Buffer |
| | | 72 | C | bool sKeywordFound; // Exit Special Keyword for-loop if found |
|
| 47 | C | while ((i < lengthLine) && isspacechar(lineBuffer[i])) {// Skip initial spaces | | 74 | C | // Skip initial spaces |
| 48 | C | i++; | | |
| 49 | C | } | | |
| 50 | C | if (lineBuffer[i] == '@') { // Hide command (ECHO OFF) | | |
| 51 | C | styler.ColourTo(startLine + i, SCE_BAT_HIDE); | | |
| 52 | C | i++; | | |
| 53 | C | while ((i < lengthLine) && isspacechar(lineBuffer[i])) {// Skip next spaces | | 75 | C | while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { |
| 54 | C | i++; | | 76 | C | offset++; |
| 55 | C | } | | |
|
| | | 78 | C | // Colorize Default Text |
| | | 79 | C | styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); |
| | | 80 | C | // Set External Command / Program Location |
| | | 81 | C | cmdLoc = offset; |
| | | 82 | C | |
| | | 83 | C | // Check for Fake Label (Comment) or Real Label - return if found |
| 57 | C | if (lineBuffer[i] == ':') { | | 84 | C | if (lineBuffer[offset] == ':') { |
| 58 | C | // Label | | |
| 59 | C | if (lineBuffer[i + 1] == ':') { | | 85 | C | if (lineBuffer[offset + 1] == ':') { |
| 60 | C | // :: is a fake label, similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm | | 86 | C | // Colorize Fake Label (Comment) - :: is similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm |
| 61 | U | 87 | U | styler.ColourTo(endPos, SCE_BAT_COMMENT); |
|
| 62 | C | } else {// Real label | | 88 | C | } else { |
| | | 89 | C | // Colorize Real Label |
| 63 | U | 90 | U | styler.ColourTo(endPos, SCE_BAT_LABEL); |
|
|
| | | 92 | C | return; |
| | | 93 | C | // Check for Drive Change (Drive Change is internal command) - return if found |
| 65 | C | } else { | | 94 | C | } else if ((isalpha(lineBuffer[offset])) && |
| | | 95 | C | (lineBuffer[offset + 1] == ':') && |
| | | 96 | C | ((isspacechar(lineBuffer[offset + 2])) || |
| | | 97 | C | (((lineBuffer[offset + 2] == '\\')) && |
| | | 98 | C | (isspacechar(lineBuffer[offset + 3]))))) { |
| | | 99 | C | // Colorize Regular Keyword |
| | | 100 | C | styler.ColourTo(endPos, SCE_BAT_WORD); |
| | | 101 | C | return; |
| | | 102 | C | } |
| | | 103 | C | |
| 66 | C | // Check if initial word is a keyword | | 104 | C | // Check for Hide Command (@ECHO OFF/ON) |
| 67 | C | char wordBuffer[21]; | | 105 | C | if (lineBuffer[offset] == '@') { |
| 68 | C | unsigned int wbl = 0, offset = i; | | 106 | C | styler.ColourTo(startLine + offset, SCE_BAT_HIDE); |
| 69 | C | // Copy word in buffer | | 107 | C | offset++; |
| | | 108 | C | // Check for Argument (%n) or Environment Variable (%x...%) |
| | | 109 | C | } else if (lineBuffer[offset] == '%') { |
| | | 110 | C | enVarEnd = offset + 1; |
| | | 111 | C | // Search end of word for second % (can be a long path) |
| | | 112 | C | while ((enVarEnd < lengthLine) && |
| | | 113 | C | (!isspacechar(lineBuffer[enVarEnd])) && |
| | | 114 | C | (lineBuffer[enVarEnd] != '%') && |
| | | 115 | C | (!IsBOperator(lineBuffer[enVarEnd])) && |
| | | 116 | C | (!IsBSeparator(lineBuffer[enVarEnd]))) { |
| | | 117 | C | enVarEnd++; |
| 27 skipped lines |
| | | 145 | C | } |
| | | 146 | C | |
| | | 147 | C | // Read remainder of line word-at-a-time or remainder-of-word-at-a-time |
| | | 148 | C | while (offset < lengthLine) { |
| | | 149 | C | if (offset > startLine) { |
| | | 150 | C | // Colorize Default Text |
| | | 151 | C | styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); |
| | | 152 | C | } |
| | | 153 | C | // Copy word from Line Buffer into Word Buffer |
| | | 154 | C | wbl = 0; |
| 70 | C | for (; offset < lengthLine && wbl < 20 && | | 155 | C | for (; offset < lengthLine && wbl < 80 && |
| 71 | U | 156 | U | !isspacechar(lineBuffer[offset]); wbl++, offset++) { |
|
| 72 | U | 157 | U | wordBuffer[wbl] = static_cast<char>(tolower(lineBuffer[offset])); |
|
|
| 74 | U | 159 | U | wordBuffer[wbl] = '\0'; |
|
| | | 160 | C | wbo = 0; |
| | | 161 | C | |
| 75 | C | // Check if it is a comment | | 162 | C | // Check for Comment - return if found |
| 76 | U | 163 | U | if (CompareCaseInsensitive(wordBuffer, "rem") == 0) { |
|
| 77 | U | 164 | U | styler.ColourTo(endPos, SCE_BAT_COMMENT); |
|
| 78 | C | return ; | | 165 | C | return; |
|
| 80 | C | // Check if it is in the list | | 167 | C | // Check for Separator |
| | | 168 | C | if (IsBSeparator(wordBuffer[0])) { |
| | | 169 | C | // Check for External Command / Program |
| | | 170 | C | if ((cmdLoc == offset - wbl) && |
| | | 171 | C | ((wordBuffer[0] == ':') || |
| | | 172 | C | (wordBuffer[0] == '\\') || |
| 81 | C | if (keywords.InList(wordBuffer)) { | | 173 | C | (wordBuffer[0] == '.'))) { |
| | | 174 | C | // Reset Offset to re-process remainder of word |
| | | 175 | C | offset -= (wbl - 1); |
| | | 176 | C | // Colorize External Command / Program |
| 82 | C | styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD); // Regular keyword | | 177 | C | styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); |
| | | 178 | C | // Reset External Command / Program Location |
| | | 179 | C | cmdLoc = offset; |
| 83 | C | } else { | | 180 | C | } else { |
| 84 | C | // Search end of word (can be a long path) | | 181 | C | // Reset Offset to re-process remainder of word |
| | | 182 | C | offset -= (wbl - 1); |
| | | 183 | C | // Colorize Default Text |
| | | 184 | C | styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); |
| | | 185 | C | } |
| | | 186 | C | // Check for Regular Keyword in list |
| 85 | C | while (offset < lengthLine && | | 187 | C | } else if ((keywords.InList(wordBuffer)) && |
| | | 188 | C | (continueProcessing)) { |
| | | 189 | C | // Local Variables do not exist if no FOR statement |
| 86 | C | !isspacechar(lineBuffer[offset])) { | | 190 | C | if (CompareCaseInsensitive(wordBuffer, "for") == 0) { |
| | | 191 | C | forFound = true; |
| | | 192 | C | } |
| | | 193 | C | // ECHO, GOTO, PROMPT and SET require no further Regular Keyword Checking |
| | | 194 | C | if ((CompareCaseInsensitive(wordBuffer, "echo") == 0) || |
| | | 195 | C | (CompareCaseInsensitive(wordBuffer, "goto") == 0) || |
| | | 196 | C | (CompareCaseInsensitive(wordBuffer, "prompt") == 0) || |
| | | 197 | C | (CompareCaseInsensitive(wordBuffer, "set") == 0)) { |
| | | 198 | C | continueProcessing = false; |
| | | 199 | C | } |
| | | 200 | C | // Identify External Command / Program Location for ERRORLEVEL, and EXIST |
| 52 skipped lines |
| | | 253 | C | ((IsBOperator(wordBuffer[wbo])) || |
| | | 254 | C | (IsBSeparator(wordBuffer[wbo])))) { |
| | | 255 | C | sKeywordFound = true; |
| | | 256 | C | // ECHO requires no further Regular Keyword Checking |
| | | 257 | C | if (CompareCaseInsensitive(sKeywordBuffer, "echo") == 0) { |
| | | 258 | C | continueProcessing = false; |
| | | 259 | C | } |
| | | 260 | C | // Colorize Special Keyword as Regular Keyword |
| | | 261 | C | styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_WORD); |
| | | 262 | C | // Reset Offset to re-process remainder of word |
| 87 | C | offset++; | | 263 | C | offset -= (wbl - wbo); |
|
| 89 | R | styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); // External command / program | | |
|
| 91 | C | // Remainder of the line: colourise the variables. | | 266 | C | // Check for External Command / Program or Default Text |
| 92 | C | | | 267 | C | if (!sKeywordFound) { |
| | | 268 | C | wbo = 0; |
| | | 269 | C | // Check for External Command / Program |
| 93 | C | while (offset < lengthLine) { | | 270 | C | if (cmdLoc == offset - wbl) { |
| | | 271 | C | // Read up to %, Operator or Separator |
| | | 272 | C | while ((wbo < wbl) && |
| 94 | C | if (state == SCE_BAT_DEFAULT && lineBuffer[offset] == '%') { | | 273 | C | (wordBuffer[wbo] != '%') && |
| | | 274 | C | (!IsBOperator(wordBuffer[wbo])) && |
| | | 275 | C | (!IsBSeparator(wordBuffer[wbo]))) { |
| | | 276 | C | wbo++; |
| | | 277 | C | } |
| | | 278 | C | // Reset External Command / Program Location |
| 95 | C | styler.ColourTo(startLine + offset - 1, state); | | 279 | C | cmdLoc = offset - (wbl - wbo); |
| | | 280 | C | // Reset Offset to re-process remainder of word |
| | | 281 | C | offset -= (wbl - wbo); |
| | | 282 | C | // CHOICE requires no further Regular Keyword Checking |
| 96 | C | if (Is0To9(lineBuffer[offset + 1])) { | | 283 | C | if (CompareCaseInsensitive(wordBuffer, "choice") == 0) { |
| 97 | C | styler.ColourTo(startLine + offset + 1, SCE_BAT_IDENTIFIER); | | 284 | C | continueProcessing = false; |
| 98 | C | offset += 2; | | 285 | C | } |
| | | 286 | C | // Check for START (and its switches) - What follows is External Command \ Program |
| | | 287 | C | if (CompareCaseInsensitive(wordBuffer, "start") == 0) { |
| | | 288 | C | // Reset External Command / Program Location |
| | | 289 | C | cmdLoc = offset; |
| | | 290 | C | // Skip next spaces |
| | | 291 | C | while ((cmdLoc < lengthLine) && |
| 99 | C | } else if (lineBuffer[offset + 1] == '%' && | | 292 | C | (isspacechar(lineBuffer[cmdLoc]))) { |
| | | 293 | C | cmdLoc++; |
| | | 294 | C | } |
| | | 295 | C | // Reset External Command / Program Location if command switch detected |
| | | 296 | C | if (lineBuffer[cmdLoc] == '/') { |
| | | 297 | C | // Skip command switch |
| | | 298 | C | while ((cmdLoc < lengthLine) && |
| 100 | C | !isspacechar(lineBuffer[offset + 2])) { | | 299 | C | (!isspacechar(lineBuffer[cmdLoc]))) { |
| 101 | C | // Should be safe, as there is CRLF at the end of the line... | | 300 | C | cmdLoc++; |
| | | 301 | C | } |
| | | 302 | C | // Skip next spaces |
| | | 303 | C | while ((cmdLoc < lengthLine) && |
| | | 304 | C | (isspacechar(lineBuffer[cmdLoc]))) { |
| | | 305 | C | cmdLoc++; |
| | | 306 | C | } |
| | | 307 | C | } |
| | | 308 | C | } |
| | | 309 | C | // Colorize External command / program |
| 102 | C | styler.ColourTo(startLine + offset + 2, SCE_BAT_IDENTIFIER); | | 310 | C | styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); |
| 103 | C | offset += 3; | | 311 | C | // No need to Reset Offset |
| | | 312 | C | // Check for Default Text |
|
| | | 314 | C | // Read up to %, Operator or Separator |
| | | 315 | C | while ((wbo < wbl) && |
| | | 316 | C | (wordBuffer[wbo] != '%') && |
| | | 317 | C | (!IsBOperator(wordBuffer[wbo])) && |
| | | 318 | C | (!IsBSeparator(wordBuffer[wbo]))) { |
| | | 319 | C | wbo++; |
| | | 320 | C | } |
| | | 321 | C | // Colorize Default Text |
| | | 322 | C | styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT); |
| | | 323 | C | // Reset Offset to re-process remainder of word |
| 25 skipped lines |
| | | 349 | C | offset -= (wbl - 2); |
| | | 350 | C | // Check for Environment Variable (%x...%) |
| | | 351 | C | } else if ((wordBuffer[1] != '%') && |
| | | 352 | C | (wordBuffer[wbo] == '%')) { |
| | | 353 | C | wbo++; |
| | | 354 | C | // Check for External Command / Program |
| | | 355 | C | if (cmdLoc == offset - wbl) { |
| | | 356 | C | cmdLoc = offset - (wbl - wbo); |
| | | 357 | C | } |
| | | 358 | C | // Colorize Environment Variable |
| 105 | C | state = SCE_BAT_IDENTIFIER; | | 359 | C | styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER); |
| | | 360 | C | // Reset Offset to re-process remainder of word |
| | | 361 | C | offset -= (wbl - wbo); |
| | | 362 | C | // Check for Local Variable (%%a) |
| | | 363 | C | } else if ((forFound) && |
| | | 364 | C | (wordBuffer[1] == '%') && |
| | | 365 | C | (wordBuffer[2] != '%') && |
| | | 366 | C | (!IsBOperator(wordBuffer[2])) && |
| | | 367 | C | (!IsBSeparator(wordBuffer[2]))) { |
| | | 368 | C | // Check for External Command / Program |
| | | 369 | C | if (cmdLoc == offset - wbl) { |
| | | 370 | C | cmdLoc = offset - (wbl - 3); |
|
| 107 | C | } else if (state == SCE_BAT_IDENTIFIER && lineBuffer[offset] == '%') { | | 372 | C | // Colorize Local Variable |
| 108 | C | styler.ColourTo(startLine + offset, state); | | 373 | C | styler.ColourTo(startLine + offset - 1 - (wbl - 3), SCE_BAT_IDENTIFIER); |
| 109 | C | state = SCE_BAT_DEFAULT; | | 374 | C | // Reset Offset to re-process remainder of word |
| 110 | C | } else if (state == SCE_BAT_DEFAULT && | | |
| 111 | C | (lineBuffer[offset] == '*' || | | |
| 112 | C | lineBuffer[offset] == '?' || | | |
| 113 | C | lineBuffer[offset] == '=' || | | |
| 114 | C | lineBuffer[offset] == '<' || | | |
| 115 | C | lineBuffer[offset] == '>' || | | |
| 116 | C | lineBuffer[offset] == '|')) { | | |
| 117 | C | styler.ColourTo(startLine + offset - 1, state); | | 375 | C | offset -= (wbl - 3); |
| 118 | C | styler.ColourTo(startLine + offset, SCE_BAT_OPERATOR); | | |
|
| | | 377 | A | // Check for Operator |
| | | 378 | A | } else if (IsBOperator(wordBuffer[0])) { |
| | | 379 | A | // Colorize Default Text |
| | | 380 | A | styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT); |
| | | 381 | A | // Check for Comparison Operator |
| 48 skipped lines |
| | | 430 | A | // Reset Offset to re-process remainder of word |
| | | 431 | A | offset -= (wbl - wbo); |
| | | 432 | A | } |
| | | 433 | A | // Skip next spaces - nothing happens if Offset was Reset |
| | | 434 | A | while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { |
|
|
| 122 | R | // if (endPos > startLine + offset - 1) { | | |
| 123 | R | styler.ColourTo(endPos, SCE_BAT_DEFAULT); // Remainder of line, currently not lexed | | |
| 124 | R | // } | | |
|
| 126 | C | | | 438 | C | // Colorize Default Text for remainder of line - currently not lexed |
| | | 439 | C | styler.ColourTo(endPos, SCE_BAT_DEFAULT); |
|
| 128 | R | // ToDo: (not necessarily at beginning of line) GOTO, [IF] NOT, ERRORLEVEL | | |
| 129 | R | // IF [NO] (test) (command) -- test is EXIST (filename) | (string1)==(string2) | ERRORLEVEL (number) | | |
| 130 | R | // FOR %%(variable) IN (set) DO (command) -- variable is [a-zA-Z] -- eg for %%X in (*.txt) do type %%X | | |
| 131 | R | // ToDo: %n (parameters), %EnvironmentVariable% colourising | | |
| 132 | R | // ToDo: Colourise = > >> < | " | | |
|
| 134 | U | 442 | U | static void ColouriseBatchDoc( |
|
| 135 | U | 443 | U | unsigned int startPos, |
|
| 104 skipped lines |
| 240 | U | 548 | U | int nextLevel = prevLevel; |
|
| 241 | U | 549 | U | if (prevLevel & SC_FOLDLEVELHEADERFLAG) |
|
| 242 | U | 550 | U | nextLevel = (prevLevel & SC_FOLDLEVELNUMBERMASK) + 1; |
|
| 243 | C | | | 551 | C | |
| 244 | U | 552 | U | int lineType = styler.StyleAt(curLineStart); |
|
| 245 | U | 553 | U | if (lineType == SCE_DIFF_COMMAND) |
|
| 246 | U | 554 | U | nextLevel = (SC_FOLDLEVELBASE + 1) | SC_FOLDLEVELHEADERFLAG; |
|
| 1 skipped line |
| 248 | U | 556 | U | nextLevel = (SC_FOLDLEVELBASE + 2) | SC_FOLDLEVELHEADERFLAG; |
|
| 249 | U | 557 | U | } else if (lineType == SCE_DIFF_POSITION) |
|
| 250 | U | 558 | U | nextLevel = (SC_FOLDLEVELBASE + 3) | SC_FOLDLEVELHEADERFLAG; |
|
| 251 | C | | | 559 | C | |
| 252 | U | 560 | U | if ((nextLevel & SC_FOLDLEVELHEADERFLAG) && (nextLevel == prevLevel)) |
|
| 253 | U | 561 | U | styler.SetLevel(curLine-1, prevLevel & ~SC_FOLDLEVELHEADERFLAG); |
|
|
| 255 | U | 563 | U | styler.SetLevel(curLine, nextLevel); |
|
| 256 | U | 564 | U | prevLevel = nextLevel; |
|
| 257 | C | | | 565 | C | |
| 258 | U | 566 | U | curLineStart = styler.LineStart(++curLine); |
|
| 259 | U | 567 | U | } while (static_cast<int>(startPos) + length > curLineStart); |
|
|
| 111 skipped lines |
|
|
| 374 | U | 682 | U | visibleChars = 0; |
|
| 375 | C | headerPoint=false; | | 683 | C | headerPoint = false; |
|
| 377 | U | 685 | U | if (!isspacechar(ch)) |
|
|
| 96 skipped lines |
|
|
|
| 478 | C | static bool strstart(char *haystack, char *needle) { | | 786 | C | static bool strstart(const char *haystack, const char *needle) { |
| 479 | U | 787 | U | return strncmp(haystack, needle, strlen(needle)) == 0; |
|
|
|
| 482 | C | static void ColouriseErrorListLine( | | |
| 483 | C | char *lineBuffer, | | |
| 484 | C | unsigned int lengthLine, | | |
| 485 | C | // unsigned int startLine, | | |
| 486 | C | unsigned int endPos, | | 790 | C | static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLine) { |
| 487 | C | Accessor &styler) { | | |
| 488 | C | const int unRecognized = 99; | | |
| 489 | U | 791 | U | if (lineBuffer[0] == '>') { |
|
| 490 | U | 792 | U | // Command or return status |
|
| 491 | C | styler.ColourTo(endPos, SCE_ERR_CMD); | | 793 | C | return SCE_ERR_CMD; |
| 492 | U | 794 | U | } else if (lineBuffer[0] == '<') { |
|
| 493 | U | 795 | U | // Diff removal, but not interested. Trapped to avoid hitting CTAG cases. |
|
| 494 | C | styler.ColourTo(endPos, SCE_ERR_DEFAULT); | | 796 | C | return SCE_ERR_DEFAULT; |
| 495 | U | 797 | U | } else if (lineBuffer[0] == '!') { |
|
| 496 | C | styler.ColourTo(endPos, SCE_ERR_DIFF_CHANGED); | | 798 | C | return SCE_ERR_DIFF_CHANGED; |
| 497 | U | 799 | U | } else if (lineBuffer[0] == '+') { |
|
| | | 800 | C | if (strstart(lineBuffer, "+++ ")) { |
| 498 | C | styler.ColourTo(endPos, SCE_ERR_DIFF_ADDITION); | | 801 | C | return SCE_ERR_DIFF_MESSAGE; |
| 499 | C | } else if (lineBuffer[0] == '-' && lineBuffer[1] == '-' && lineBuffer[2] == '-') { | | 802 | C | } else { |
| 500 | C | styler.ColourTo(endPos, SCE_ERR_DIFF_MESSAGE); | | 803 | C | return SCE_ERR_DIFF_ADDITION; |
| | | 804 | C | } |
| 501 | U | 805 | U | } else if (lineBuffer[0] == '-') { |
|
| | | 806 | C | if (strstart(lineBuffer, "--- ")) { |
| | | 807 | C | return SCE_ERR_DIFF_MESSAGE; |
| | | 808 | C | } else { |
| 502 | C | styler.ColourTo(endPos, SCE_ERR_DIFF_DELETION); | | 809 | C | return SCE_ERR_DIFF_DELETION; |
| | | 810 | C | } |
| 503 | U | 811 | U | } else if (strstart(lineBuffer, "cf90-")) { |
|
| 504 | U | 812 | U | // Absoft Pro Fortran 90/95 v8.2 error and/or warning message |
|
| 505 | C | styler.ColourTo(endPos, SCE_ERR_ABSF); | | 813 | C | return SCE_ERR_ABSF; |
| 506 | U | 814 | U | } else if (strstart(lineBuffer, "fortcom:")) { |
|
| 507 | U | 815 | U | // Intel Fortran Compiler v8.0 error/warning message |
|
| 508 | C | styler.ColourTo(endPos, SCE_ERR_IFORT); | | 816 | C | return SCE_ERR_IFORT; |
| 509 | U | 817 | U | } else if (strstr(lineBuffer, "File \"") && strstr(lineBuffer, ", line ")) { |
|
| 510 | C | styler.ColourTo(endPos, SCE_ERR_PYTHON); | | 818 | C | return SCE_ERR_PYTHON; |
| 511 | U | 819 | U | } else if (strstr(lineBuffer, " in ") && strstr(lineBuffer, " on line ")) { |
|
| 512 | C | styler.ColourTo(endPos, SCE_ERR_PHP); | | 820 | C | return SCE_ERR_PHP; |
| 513 | U | 821 | U | } else if ((strstart(lineBuffer, "Error ") || |
|
| 514 | C | strstart(lineBuffer, "Warning ")) && | | 822 | C | strstart(lineBuffer, "Warning ")) && |
| 515 | C | strstr(lineBuffer, " at (") && | | 823 | C | strstr(lineBuffer, " at (") && |
| 516 | C | strstr(lineBuffer, ") : ") && | | 824 | C | strstr(lineBuffer, ") : ") && |
| 517 | C | (strstr(lineBuffer, " at (") < strstr(lineBuffer, ") : "))) { | | 825 | C | (strstr(lineBuffer, " at (") < strstr(lineBuffer, ") : "))) { |
| 518 | U | 826 | U | // Intel Fortran Compiler error/warning message |
|
| 519 | C | styler.ColourTo(endPos, SCE_ERR_IFC); | | 827 | C | return SCE_ERR_IFC; |
| 520 | U | 828 | U | } else if (strstart(lineBuffer, "Error ")) { |
|
| 521 | U | 829 | U | // Borland error message |
|
| 522 | C | styler.ColourTo(endPos, SCE_ERR_BORLAND); | | 830 | C | return SCE_ERR_BORLAND; |
| 523 | U | 831 | U | } else if (strstart(lineBuffer, "Warning ")) { |
|
| 524 | U | 832 | U | // Borland warning message |
|
| 525 | C | styler.ColourTo(endPos, SCE_ERR_BORLAND); | | 833 | C | return SCE_ERR_BORLAND; |
| 526 | U | 834 | U | } else if (strstr(lineBuffer, "at line " ) && |
|
| 527 | U | 835 | U | (strstr(lineBuffer, "at line " ) < (lineBuffer + lengthLine)) && |
|
| 528 | U | 836 | U | strstr(lineBuffer, "file ") && |
|
| 529 | U | 837 | U | (strstr(lineBuffer, "file ") < (lineBuffer + lengthLine))) { |
|
| 530 | U | 838 | U | // Lua 4 error message |
|
| 531 | C | styler.ColourTo(endPos, SCE_ERR_LUA); | | 839 | C | return SCE_ERR_LUA; |
| 532 | U | 840 | U | } else if (strstr(lineBuffer, " at " ) && |
|
| 533 | U | 841 | U | (strstr(lineBuffer, " at " ) < (lineBuffer + lengthLine)) && |
|
| 534 | U | 842 | U | strstr(lineBuffer, " line ") && |
|
| 535 | U | 843 | U | (strstr(lineBuffer, " line ") < (lineBuffer + lengthLine)) && |
|
| 536 | C | (strstr(lineBuffer, " at " ) < (strstr(lineBuffer, " line ")))) { | | 844 | C | (strstr(lineBuffer, " at " ) < (strstr(lineBuffer, " line ")))) { |
| 537 | U | 845 | U | // perl error message |
|
| 538 | C | styler.ColourTo(endPos, SCE_ERR_PERL); | | 846 | C | return SCE_ERR_PERL; |
| 539 | U | 847 | U | } else if ((memcmp(lineBuffer, " at ", 6) == 0) && |
|
| 540 | C | strstr(lineBuffer, ":line ")) { | | 848 | C | strstr(lineBuffer, ":line ")) { |
| 541 | U | 849 | U | // A .NET traceback |
|
| 542 | C | styler.ColourTo(endPos, SCE_ERR_NET); | | 850 | C | return SCE_ERR_NET; |
| 543 | U | 851 | U | } else if (strstart(lineBuffer, "Line ") && |
|
| 544 | C | strstr(lineBuffer, ", file ")) { | | 852 | C | strstr(lineBuffer, ", file ")) { |
| 545 | U | 853 | U | // Essential Lahey Fortran error message |
|
| 546 | C | styler.ColourTo(endPos, SCE_ERR_ELF); | | 854 | C | return SCE_ERR_ELF; |
| 547 | U | 855 | U | } else if (strstart(lineBuffer, "line ") && |
|
| 548 | C | strstr(lineBuffer, " column ")) { | | 856 | C | strstr(lineBuffer, " column ")) { |
| 549 | U | 857 | U | // HTML tidy style: line 42 column 1 |
|
| 550 | C | styler.ColourTo(endPos, SCE_ERR_TIDY); | | 858 | C | return SCE_ERR_TIDY; |
| 551 | U | 859 | U | } else if (strstart(lineBuffer, "\tat ") && |
|
| 552 | C | strstr(lineBuffer, "(") && | | 860 | C | strstr(lineBuffer, "(") && |
| 553 | C | strstr(lineBuffer, ".java:")) { | | 861 | C | strstr(lineBuffer, ".java:")) { |
| 554 | U | 862 | U | // Java stack back trace |
|
| 555 | C | styler.ColourTo(endPos, SCE_ERR_JAVA_STACK); | | 863 | C | return SCE_ERR_JAVA_STACK; |
|
| | | 865 | C | // Look for one of the following formats: |
| 557 | C | // Look for GCC <filename>:<line>:message | | 866 | C | // GCC: <filename>:<line>:<message> |
| 558 | C | // Look for Microsoft <filename>(line) :message | | 867 | C | // Microsoft: <filename>(<line>) :<message> |
| | | 868 | C | // Common: <filename>(<line>): warning|error|note|remark|catastrophic|fatal |
| | | 869 | C | // Common: <filename>(<line>) warning|error|note|remark|catastrophic|fatal |
| 559 | C | // Look for Microsoft <filename>(line,pos)message | | 870 | C | // Microsoft: <filename>(<line>,<column>)<message> |
| 560 | C | // Look for CTags \tmessage | | 871 | C | // CTags: \t<message> |
| 561 | C | // Look for Lua 5 traceback \t<filename>:<line>:message | | 872 | C | // Lua 5 traceback: \t<filename>:<line>:<message> |
| 562 | U | 873 | U | bool initialTab = (lineBuffer[0] == '\t'); |
|
| | | 874 | C | enum { stInitial, |
| | | 875 | C | stGccStart, stGccDigit, stGcc, |
| | | 876 | C | stMsStart, stMsDigit, stMsBracket, stMsVc, stMsDigitComma, stMsDotNet, |
| | | 877 | C | stCtagsStart, stCtagsStartString, stCtagsStringDollar, stCtags, |
| | | 878 | C | stUnrecognized |
| 563 | C | int state = 0; | | 879 | C | } state = stInitial; |
| 564 | U | 880 | U | for (unsigned int i = 0; i < lengthLine; i++) { |
|
| 565 | U | 881 | U | char ch = lineBuffer[i]; |
|
| 566 | U | 882 | U | char chNext = ' '; |
|
| 567 | C | if ((i+1) < lengthLine) | | 883 | C | if ((i + 1) < lengthLine) |
| 568 | C | chNext = lineBuffer[i+1]; | | 884 | C | chNext = lineBuffer[i + 1]; |
| 569 | C | if (state == 0) { | | 885 | C | if (state == stInitial) { |
| 570 | U | 886 | U | if (ch == ':') { |
|
| 571 | U | 887 | U | // May be GCC, or might be Lua 5 (Lua traceback same but with tab prefix) |
|
| 572 | U | 888 | U | if ((chNext != '\\') && (chNext != '/')) { |
|
| 573 | U | 889 | U | // This check is not completely accurate as may be on |
|
| 574 | U | 890 | U | // GTK+ with a file name that includes ':'. |
|
| 575 | C | state = 1; | | 891 | C | state = stGccStart; |
|
| 577 | U | 893 | U | } else if ((ch == '(') && Is1To9(chNext) && (!initialTab)) { |
|
| 578 | U | 894 | U | // May be Microsoft |
|
| 579 | U | 895 | U | // Check against '0' often removes phone numbers |
|
| 580 | C | state = 10; | | 896 | C | state = stMsStart; |
| 581 | U | 897 | U | } else if ((ch == '\t') && (!initialTab)) { |
|
|
| 583 | C | state = 20; | | 899 | C | state = stCtagsStart; |
|
| 585 | C | } else if (state == 1) { | | 901 | C | } else if (state == stGccStart) { // <filename>: |
| 586 | C | state = Is1To9(ch) ? 2 : unRecognized; | | 902 | C | state = Is1To9(ch) ? stGccDigit : stUnrecognized; |
| 587 | C | } else if (state == 2) { | | 903 | C | } else if (state == stGccDigit) { // <filename>:<line> |
| 588 | U | 904 | U | if (ch == ':') { |
|
| 589 | C | state = 3; // :9.*: is GCC | | 905 | C | state = stGcc; // :9.*: is GCC |
|
| 591 | U | 907 | U | } else if (!Is0To9(ch)) { |
|
| 592 | C | state = unRecognized; | | 908 | C | state = stUnrecognized; |
|
| 594 | C | } else if (state == 10) { | | 910 | C | } else if (state == stMsStart) {// <filename>( |
| 595 | C | state = Is0To9(ch) ? 11 : unRecognized; | | 911 | C | state = Is0To9(ch) ? stMsDigit : stUnrecognized; |
| 596 | C | } else if (state == 11) { | | 912 | C | } else if (state == stMsDigit) {// <filename>(<line> |
| 597 | U | 913 | U | if (ch == ',') { |
|
| 598 | C | state = 14; | | 914 | C | state = stMsDigitComma; |
| 599 | U | 915 | U | } else if (ch == ')') { |
|
| 600 | C | state = 12; | | 916 | C | state = stMsBracket; |
| 601 | U | 917 | U | } else if ((ch != ' ') && !Is0To9(ch)) { |
|
| 602 | C | state = unRecognized; | | 918 | C | state = stUnrecognized; |
|
| 604 | C | } else if (state == 12) { | | 920 | C | } else if (state == stMsBracket) { // <filename>(<line>) |
| 605 | U | 921 | U | if ((ch == ' ') && (chNext == ':')) { |
|
| 606 | C | state = 13; | | 922 | C | state = stMsVc; |
| | | 923 | C | } else if ((ch == ':' && chNext == ' ') || (ch == ' ')) { |
| | | 924 | C | // Possibly Delphi.. don't test against chNext as it's one of the strings below. |
| | | 925 | C | char word[512]; |
| | | 926 | C | unsigned int j, chPos; |
| | | 927 | C | unsigned numstep; |
| | | 928 | C | chPos = 0; |
| | | 929 | C | if (ch == ' ') |
| | | 930 | C | numstep = 1; // ch was ' ', handle as if it's a delphi errorline, only add 1 to i. |
| | | 931 | C | else |
| | | 932 | C | numstep = 2; // otherwise add 2. |
| | | 933 | C | for (j = i + numstep; j < lengthLine && isalpha(lineBuffer[j]) && chPos < sizeof(word) - 1; j++) |
| | | 934 | C | word[chPos++] = lineBuffer[j]; |
| | | 935 | C | word[chPos] = 0; |
| | | 936 | C | if (!CompareCaseInsensitive(word, "error") || !CompareCaseInsensitive(word, "warning") || |
| | | 937 | C | !CompareCaseInsensitive(word, "fatal") || !CompareCaseInsensitive(word, "catastrophic") || |
| | | 938 | C | !CompareCaseInsensitive(word, "note") || !CompareCaseInsensitive(word, "remark")) { |
| | | 939 | C | state = stMsVc; |
| | | 940 | C | } else |
| | | 941 | C | state = stUnrecognized; |
|
| 608 | C | state = unRecognized; | | 943 | C | state = stUnrecognized; |
|
| 610 | C | } else if (state == 14) { | | 945 | C | } else if (state == stMsDigitComma) { // <filename>(<line>, |
| 611 | U | 946 | U | if (ch == ')') { |
|
| 612 | C | state = 15; | | 947 | C | state = stMsDotNet; |
|
| 614 | U | 949 | U | } else if ((ch != ' ') && !Is0To9(ch)) { |
|
| 615 | C | state = unRecognized; | | 950 | C | state = stUnrecognized; |
|
| 617 | C | } else if (state == 20) { | | 952 | C | } else if (state == stCtagsStart) { |
| 618 | C | if ((lineBuffer[i-1] == '\t') && | | 953 | C | if ((lineBuffer[i - 1] == '\t') && |
| 619 | C | ((ch == '/' && lineBuffer[i+1] == '^') || Is0To9(ch))) { | | 954 | C | ((ch == '/' && lineBuffer[i + 1] == '^') || Is0To9(ch))) { |
| 620 | C | state = 24; | | 955 | C | state = stCtags; |
|
| 622 | C | } else if ((ch == '/') && (lineBuffer[i+1] == '^')) { | | 957 | C | } else if ((ch == '/') && (lineBuffer[i + 1] == '^')) { |
| 623 | C | state = 21; | | 958 | C | state = stCtagsStartString; |
|
| 625 | C | } else if ((state == 21) && ((lineBuffer[i] == '$') && (lineBuffer[i+1] == '/'))) { | | 960 | C | } else if ((state == stCtagsStartString) && ((lineBuffer[i] == '$') && (lineBuffer[i + 1] == '/'))) { |
| 626 | C | state = 22; | | 961 | C | state = stCtagsStringDollar; |
|
|
|
| 630 | C | if (state == 3) { | | 965 | C | if (state == stGcc) { |
| 631 | C | styler.ColourTo(endPos, SCE_ERR_GCC); | | 966 | C | return SCE_ERR_GCC; |
| 632 | C | } else if ((state == 13) || (state == 14) || (state == 15)) { | | 967 | C | } else if ((state == stMsVc) || (state == stMsDotNet)) { |
| 633 | C | styler.ColourTo(endPos, SCE_ERR_MS); | | 968 | C | return SCE_ERR_MS; |
| 634 | C | } else if ((state == 22) || (state == 24)) { | | 969 | C | } else if ((state == stCtagsStringDollar) || (state == stCtags)) { |
| 635 | C | styler.ColourTo(endPos, SCE_ERR_CTAG); | | 970 | C | return SCE_ERR_CTAG; |
|
| 637 | C | styler.ColourTo(endPos, SCE_ERR_DEFAULT); | | 972 | C | return SCE_ERR_DEFAULT; |
|
|
|
|
| | | 977 | A | static void ColouriseErrorListLine( |
| | | 978 | A | char *lineBuffer, |
| | | 979 | A | unsigned int lengthLine, |
| | | 980 | A | unsigned int endPos, |
| | | 981 | A | Accessor &styler) { |
| | | 982 | A | styler.ColourTo(endPos, RecogniseErrorListLine(lineBuffer, lengthLine)); |
| | | 983 | A | } |
| | | 984 | A | |
| 642 | U | 985 | U | static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { |
|
| 643 | C | char lineBuffer[1024]; | | 986 | C | char lineBuffer[10000]; |
| 644 | U | 987 | U | styler.StartAt(startPos); |
|
| 645 | U | 988 | U | styler.StartSegment(startPos); |
|
| 646 | U | 989 | U | unsigned int linePos = 0; |
|
| 142 skipped lines |