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