You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1140 lines
39 KiB
1140 lines
39 KiB
// Scintilla source code edit control |
|
/** @file LexOthers.cxx |
|
** Lexers for batch files, diff results, properties files, make files and error lists. |
|
** Also lexer for LaTeX documents. |
|
**/ |
|
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> |
|
// The License.txt file describes the conditions under which this software may be distributed. |
|
|
|
#include <stdlib.h> |
|
#include <string.h> |
|
#include <ctype.h> |
|
#include <stdio.h> |
|
#include <stdarg.h> |
|
|
|
#include "Platform.h" |
|
|
|
#include "PropSet.h" |
|
#include "Accessor.h" |
|
#include "KeyWords.h" |
|
#include "Scintilla.h" |
|
#include "SciLexer.h" |
|
|
|
static bool Is0To9(char ch) { |
|
return (ch >= '0') && (ch <= '9'); |
|
} |
|
|
|
static bool Is1To9(char ch) { |
|
return (ch >= '1') && (ch <= '9'); |
|
} |
|
|
|
static inline bool AtEOL(Accessor &styler, unsigned int i) { |
|
return (styler[i] == '\n') || |
|
((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')); |
|
} |
|
|
|
// Tests for BATCH Operators |
|
static bool IsBOperator(char ch) { |
|
return (ch == '=') || (ch == '+') || (ch == '>') || (ch == '<') || |
|
(ch == '|') || (ch == '?') || (ch == '*'); |
|
} |
|
|
|
// Tests for BATCH Separators |
|
static bool IsBSeparator(char ch) { |
|
return (ch == '\\') || (ch == '.') || (ch == ';') || |
|
(ch == '\"') || (ch == '\'') || (ch == '/') || (ch == ')'); |
|
} |
|
|
|
static void ColouriseBatchLine( |
|
char *lineBuffer, |
|
unsigned int lengthLine, |
|
unsigned int startLine, |
|
unsigned int endPos, |
|
WordList *keywordlists[], |
|
Accessor &styler) { |
|
|
|
unsigned int offset = 0; // Line Buffer Offset |
|
unsigned int enVarEnd; // Environment Variable End point |
|
unsigned int cmdLoc; // External Command / Program Location |
|
char wordBuffer[81]; // Word Buffer - large to catch long paths |
|
unsigned int wbl; // Word Buffer Length |
|
unsigned int wbo; // Word Buffer Offset - also Special Keyword Buffer Length |
|
WordList &keywords = *keywordlists[0]; // Internal Commands |
|
WordList &keywords2 = *keywordlists[1]; // External Commands (optional) |
|
|
|
// CHOICE, ECHO, GOTO, PROMPT and SET have Default Text that may contain Regular Keywords |
|
// Toggling Regular Keyword Checking off improves readability |
|
// Other Regular Keywords and External Commands / Programs might also benefit from toggling |
|
// Need a more robust algorithm to properly toggle Regular Keyword Checking |
|
bool continueProcessing = true; // Used to toggle Regular Keyword Checking |
|
// Special Keywords are those that allow certain characters without whitespace after the command |
|
// Examples are: cd. cd\ md. rd. dir| dir> echo: echo. path= |
|
// Special Keyword Buffer used to determine if the first n characters is a Keyword |
|
char sKeywordBuffer[10]; // Special Keyword Buffer |
|
bool sKeywordFound; // Exit Special Keyword for-loop if found |
|
|
|
// Skip initial spaces |
|
while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { |
|
offset++; |
|
} |
|
// Colorize Default Text |
|
styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); |
|
// Set External Command / Program Location |
|
cmdLoc = offset; |
|
|
|
// Check for Fake Label (Comment) or Real Label - return if found |
|
if (lineBuffer[offset] == ':') { |
|
if (lineBuffer[offset + 1] == ':') { |
|
// Colorize Fake Label (Comment) - :: is similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm |
|
styler.ColourTo(endPos, SCE_BAT_COMMENT); |
|
} else { |
|
// Colorize Real Label |
|
styler.ColourTo(endPos, SCE_BAT_LABEL); |
|
} |
|
return; |
|
// Check for Drive Change (Drive Change is internal command) - return if found |
|
} else if ((isalpha(lineBuffer[offset])) && |
|
(lineBuffer[offset + 1] == ':') && |
|
((isspacechar(lineBuffer[offset + 2])) || |
|
(((lineBuffer[offset + 2] == '\\')) && |
|
(isspacechar(lineBuffer[offset + 3]))))) { |
|
// Colorize Regular Keyword |
|
styler.ColourTo(endPos, SCE_BAT_WORD); |
|
return; |
|
} |
|
|
|
// Check for Hide Command (@ECHO OFF/ON) |
|
if (lineBuffer[offset] == '@') { |
|
styler.ColourTo(startLine + offset, SCE_BAT_HIDE); |
|
offset++; |
|
// Check for Argument (%n) or Environment Variable (%x...%) |
|
} else if (lineBuffer[offset] == '%') { |
|
enVarEnd = offset + 1; |
|
// Search end of word for second % (can be a long path) |
|
while ((enVarEnd < lengthLine) && |
|
(!isspacechar(lineBuffer[enVarEnd])) && |
|
(lineBuffer[enVarEnd] != '%') && |
|
(!IsBOperator(lineBuffer[enVarEnd])) && |
|
(!IsBSeparator(lineBuffer[enVarEnd]))) { |
|
enVarEnd++; |
|
} |
|
// Check for Argument (%n) |
|
if ((Is0To9(lineBuffer[offset + 1])) && |
|
(lineBuffer[enVarEnd] != '%')) { |
|
// Colorize Argument |
|
styler.ColourTo(startLine + offset + 1, SCE_BAT_IDENTIFIER); |
|
offset += 2; |
|
// Check for External Command / Program |
|
if (!isspacechar(lineBuffer[offset])) { |
|
cmdLoc = offset; |
|
} |
|
// Check for Environment Variable (%x...%) |
|
} else if ((lineBuffer[offset + 1] != '%') && |
|
(lineBuffer[enVarEnd] == '%')) { |
|
offset = enVarEnd; |
|
// Colorize Environment Variable |
|
styler.ColourTo(startLine + offset, SCE_BAT_IDENTIFIER); |
|
offset++; |
|
// Check for External Command / Program |
|
if (!isspacechar(lineBuffer[offset])) { |
|
cmdLoc = offset; |
|
} |
|
} |
|
} |
|
// Skip next spaces |
|
while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { |
|
offset++; |
|
} |
|
|
|
// Read remainder of line word-at-a-time or remainder-of-word-at-a-time |
|
while (offset < lengthLine) { |
|
if (offset > startLine) { |
|
// Colorize Default Text |
|
styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); |
|
} |
|
// Copy word from Line Buffer into Word Buffer |
|
wbl = 0; |
|
for (; offset < lengthLine && wbl < 80 && |
|
!isspacechar(lineBuffer[offset]); wbl++, offset++) { |
|
wordBuffer[wbl] = static_cast<char>(tolower(lineBuffer[offset])); |
|
} |
|
wordBuffer[wbl] = '\0'; |
|
wbo = 0; |
|
|
|
// Check for Comment - return if found |
|
if (CompareCaseInsensitive(wordBuffer, "rem") == 0) { |
|
styler.ColourTo(endPos, SCE_BAT_COMMENT); |
|
return; |
|
} |
|
// Check for Separator |
|
if (IsBSeparator(wordBuffer[0])) { |
|
// Check for External Command / Program |
|
if ((cmdLoc == offset - wbl) && |
|
((wordBuffer[0] == ':') || |
|
(wordBuffer[0] == '\\') || |
|
(wordBuffer[0] == '.'))) { |
|
// Reset Offset to re-process remainder of word |
|
offset -= (wbl - 1); |
|
// Colorize External Command / Program |
|
if (!keywords2) { |
|
styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); |
|
} else if (keywords2.InList(wordBuffer)) { |
|
styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); |
|
} else { |
|
styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); |
|
} |
|
// Reset External Command / Program Location |
|
cmdLoc = offset; |
|
} else { |
|
// Reset Offset to re-process remainder of word |
|
offset -= (wbl - 1); |
|
// Colorize Default Text |
|
styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); |
|
} |
|
// Check for Regular Keyword in list |
|
} else if ((keywords.InList(wordBuffer)) && |
|
(continueProcessing)) { |
|
// ECHO, GOTO, PROMPT and SET require no further Regular Keyword Checking |
|
if ((CompareCaseInsensitive(wordBuffer, "echo") == 0) || |
|
(CompareCaseInsensitive(wordBuffer, "goto") == 0) || |
|
(CompareCaseInsensitive(wordBuffer, "prompt") == 0) || |
|
(CompareCaseInsensitive(wordBuffer, "set") == 0)) { |
|
continueProcessing = false; |
|
} |
|
// Identify External Command / Program Location for ERRORLEVEL, and EXIST |
|
if ((CompareCaseInsensitive(wordBuffer, "errorlevel") == 0) || |
|
(CompareCaseInsensitive(wordBuffer, "exist") == 0)) { |
|
// Reset External Command / Program Location |
|
cmdLoc = offset; |
|
// Skip next spaces |
|
while ((cmdLoc < lengthLine) && |
|
(isspacechar(lineBuffer[cmdLoc]))) { |
|
cmdLoc++; |
|
} |
|
// Skip comparison |
|
while ((cmdLoc < lengthLine) && |
|
(!isspacechar(lineBuffer[cmdLoc]))) { |
|
cmdLoc++; |
|
} |
|
// Skip next spaces |
|
while ((cmdLoc < lengthLine) && |
|
(isspacechar(lineBuffer[cmdLoc]))) { |
|
cmdLoc++; |
|
} |
|
// Identify External Command / Program Location for CALL, DO, LOADHIGH and LH |
|
} else if ((CompareCaseInsensitive(wordBuffer, "call") == 0) || |
|
(CompareCaseInsensitive(wordBuffer, "do") == 0) || |
|
(CompareCaseInsensitive(wordBuffer, "loadhigh") == 0) || |
|
(CompareCaseInsensitive(wordBuffer, "lh") == 0)) { |
|
// Reset External Command / Program Location |
|
cmdLoc = offset; |
|
// Skip next spaces |
|
while ((cmdLoc < lengthLine) && |
|
(isspacechar(lineBuffer[cmdLoc]))) { |
|
cmdLoc++; |
|
} |
|
} |
|
// Colorize Regular keyword |
|
styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD); |
|
// No need to Reset Offset |
|
// Check for Special Keyword in list, External Command / Program, or Default Text |
|
} else if ((wordBuffer[0] != '%') && |
|
(!IsBOperator(wordBuffer[0])) && |
|
(continueProcessing)) { |
|
// Check for Special Keyword |
|
// Affected Commands are in Length range 2-6 |
|
// Good that ERRORLEVEL, EXIST, CALL, DO, LOADHIGH, and LH are unaffected |
|
sKeywordFound = false; |
|
for (unsigned int keywordLength = 2; keywordLength < wbl && keywordLength < 7 && !sKeywordFound; keywordLength++) { |
|
wbo = 0; |
|
// Copy Keyword Length from Word Buffer into Special Keyword Buffer |
|
for (; wbo < keywordLength; wbo++) { |
|
sKeywordBuffer[wbo] = static_cast<char>(wordBuffer[wbo]); |
|
} |
|
sKeywordBuffer[wbo] = '\0'; |
|
// Check for Special Keyword in list |
|
if ((keywords.InList(sKeywordBuffer)) && |
|
((IsBOperator(wordBuffer[wbo])) || |
|
(IsBSeparator(wordBuffer[wbo])))) { |
|
sKeywordFound = true; |
|
// ECHO requires no further Regular Keyword Checking |
|
if (CompareCaseInsensitive(sKeywordBuffer, "echo") == 0) { |
|
continueProcessing = false; |
|
} |
|
// Colorize Special Keyword as Regular Keyword |
|
styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_WORD); |
|
// Reset Offset to re-process remainder of word |
|
offset -= (wbl - wbo); |
|
} |
|
} |
|
// Check for External Command / Program or Default Text |
|
if (!sKeywordFound) { |
|
wbo = 0; |
|
// Check for External Command / Program |
|
if (cmdLoc == offset - wbl) { |
|
// Read up to %, Operator or Separator |
|
while ((wbo < wbl) && |
|
(wordBuffer[wbo] != '%') && |
|
(!IsBOperator(wordBuffer[wbo])) && |
|
(!IsBSeparator(wordBuffer[wbo]))) { |
|
wbo++; |
|
} |
|
// Reset External Command / Program Location |
|
cmdLoc = offset - (wbl - wbo); |
|
// Reset Offset to re-process remainder of word |
|
offset -= (wbl - wbo); |
|
// CHOICE requires no further Regular Keyword Checking |
|
if (CompareCaseInsensitive(wordBuffer, "choice") == 0) { |
|
continueProcessing = false; |
|
} |
|
// Check for START (and its switches) - What follows is External Command \ Program |
|
if (CompareCaseInsensitive(wordBuffer, "start") == 0) { |
|
// Reset External Command / Program Location |
|
cmdLoc = offset; |
|
// Skip next spaces |
|
while ((cmdLoc < lengthLine) && |
|
(isspacechar(lineBuffer[cmdLoc]))) { |
|
cmdLoc++; |
|
} |
|
// Reset External Command / Program Location if command switch detected |
|
if (lineBuffer[cmdLoc] == '/') { |
|
// Skip command switch |
|
while ((cmdLoc < lengthLine) && |
|
(!isspacechar(lineBuffer[cmdLoc]))) { |
|
cmdLoc++; |
|
} |
|
// Skip next spaces |
|
while ((cmdLoc < lengthLine) && |
|
(isspacechar(lineBuffer[cmdLoc]))) { |
|
cmdLoc++; |
|
} |
|
} |
|
} |
|
// Colorize External Command / Program |
|
if (!keywords2) { |
|
styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); |
|
} else if (keywords2.InList(wordBuffer)) { |
|
styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); |
|
} else { |
|
styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); |
|
} |
|
// No need to Reset Offset |
|
// Check for Default Text |
|
} else { |
|
// Read up to %, Operator or Separator |
|
while ((wbo < wbl) && |
|
(wordBuffer[wbo] != '%') && |
|
(!IsBOperator(wordBuffer[wbo])) && |
|
(!IsBSeparator(wordBuffer[wbo]))) { |
|
wbo++; |
|
} |
|
// Colorize Default Text |
|
styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT); |
|
// Reset Offset to re-process remainder of word |
|
offset -= (wbl - wbo); |
|
} |
|
} |
|
// Check for Argument (%n), Environment Variable (%x...%) or Local Variable (%%a) |
|
} else if (wordBuffer[0] == '%') { |
|
// Colorize Default Text |
|
styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT); |
|
wbo++; |
|
// Search to end of word for second % (can be a long path) |
|
while ((wbo < wbl) && |
|
(wordBuffer[wbo] != '%') && |
|
(!IsBOperator(wordBuffer[wbo])) && |
|
(!IsBSeparator(wordBuffer[wbo]))) { |
|
wbo++; |
|
} |
|
// Check for Argument (%n) |
|
if ((Is0To9(wordBuffer[1])) && |
|
(wordBuffer[wbo] != '%')) { |
|
// Check for External Command / Program |
|
if (cmdLoc == offset - wbl) { |
|
cmdLoc = offset - (wbl - 2); |
|
} |
|
// Colorize Argument |
|
styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_IDENTIFIER); |
|
// Reset Offset to re-process remainder of word |
|
offset -= (wbl - 2); |
|
// Check for Environment Variable (%x...%) |
|
} else if ((wordBuffer[1] != '%') && |
|
(wordBuffer[wbo] == '%')) { |
|
wbo++; |
|
// Check for External Command / Program |
|
if (cmdLoc == offset - wbl) { |
|
cmdLoc = offset - (wbl - wbo); |
|
} |
|
// Colorize Environment Variable |
|
styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER); |
|
// Reset Offset to re-process remainder of word |
|
offset -= (wbl - wbo); |
|
// Check for Local Variable (%%a) |
|
} else if ( |
|
(wordBuffer[1] == '%') && |
|
(wordBuffer[2] != '%') && |
|
(!IsBOperator(wordBuffer[2])) && |
|
(!IsBSeparator(wordBuffer[2]))) { |
|
// Check for External Command / Program |
|
if (cmdLoc == offset - wbl) { |
|
cmdLoc = offset - (wbl - 3); |
|
} |
|
// Colorize Local Variable |
|
styler.ColourTo(startLine + offset - 1 - (wbl - 3), SCE_BAT_IDENTIFIER); |
|
// Reset Offset to re-process remainder of word |
|
offset -= (wbl - 3); |
|
} |
|
// Check for Operator |
|
} else if (IsBOperator(wordBuffer[0])) { |
|
// Colorize Default Text |
|
styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT); |
|
// Check for Comparison Operator |
|
if ((wordBuffer[0] == '=') && (wordBuffer[1] == '=')) { |
|
// Identify External Command / Program Location for IF |
|
cmdLoc = offset; |
|
// Skip next spaces |
|
while ((cmdLoc < lengthLine) && |
|
(isspacechar(lineBuffer[cmdLoc]))) { |
|
cmdLoc++; |
|
} |
|
// Colorize Comparison Operator |
|
styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_OPERATOR); |
|
// Reset Offset to re-process remainder of word |
|
offset -= (wbl - 2); |
|
// Check for Pipe Operator |
|
} else if (wordBuffer[0] == '|') { |
|
// Reset External Command / Program Location |
|
cmdLoc = offset - wbl + 1; |
|
// Skip next spaces |
|
while ((cmdLoc < lengthLine) && |
|
(isspacechar(lineBuffer[cmdLoc]))) { |
|
cmdLoc++; |
|
} |
|
// Colorize Pipe Operator |
|
styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR); |
|
// Reset Offset to re-process remainder of word |
|
offset -= (wbl - 1); |
|
// Check for Other Operator |
|
} else { |
|
// Check for > Operator |
|
if (wordBuffer[0] == '>') { |
|
// Turn Keyword and External Command / Program checking back on |
|
continueProcessing = true; |
|
} |
|
// Colorize Other Operator |
|
styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR); |
|
// Reset Offset to re-process remainder of word |
|
offset -= (wbl - 1); |
|
} |
|
// Check for Default Text |
|
} else { |
|
// Read up to %, Operator or Separator |
|
while ((wbo < wbl) && |
|
(wordBuffer[wbo] != '%') && |
|
(!IsBOperator(wordBuffer[wbo])) && |
|
(!IsBSeparator(wordBuffer[wbo]))) { |
|
wbo++; |
|
} |
|
// Colorize Default Text |
|
styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT); |
|
// Reset Offset to re-process remainder of word |
|
offset -= (wbl - wbo); |
|
} |
|
// Skip next spaces - nothing happens if Offset was Reset |
|
while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { |
|
offset++; |
|
} |
|
} |
|
// Colorize Default Text for remainder of line - currently not lexed |
|
styler.ColourTo(endPos, SCE_BAT_DEFAULT); |
|
} |
|
|
|
static void ColouriseBatchDoc( |
|
unsigned int startPos, |
|
int length, |
|
int /*initStyle*/, |
|
WordList *keywordlists[], |
|
Accessor &styler) { |
|
|
|
char lineBuffer[1024]; |
|
|
|
styler.StartAt(startPos); |
|
styler.StartSegment(startPos); |
|
unsigned int linePos = 0; |
|
unsigned int startLine = startPos; |
|
for (unsigned int i = startPos; i < startPos + length; i++) { |
|
lineBuffer[linePos++] = styler[i]; |
|
if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) { |
|
// End of line (or of line buffer) met, colourise it |
|
lineBuffer[linePos] = '\0'; |
|
ColouriseBatchLine(lineBuffer, linePos, startLine, i, keywordlists, styler); |
|
linePos = 0; |
|
startLine = i + 1; |
|
} |
|
} |
|
if (linePos > 0) { // Last line does not have ending characters |
|
ColouriseBatchLine(lineBuffer, linePos, startLine, startPos + length - 1, |
|
keywordlists, styler); |
|
} |
|
} |
|
|
|
static void ColouriseDiffLine(char *lineBuffer, int endLine, Accessor &styler) { |
|
// It is needed to remember the current state to recognize starting |
|
// comment lines before the first "diff " or "--- ". If a real |
|
// difference starts then each line starting with ' ' is a whitespace |
|
// otherwise it is considered a comment (Only in..., Binary file...) |
|
if (0 == strncmp(lineBuffer, "diff ", 5)) { |
|
styler.ColourTo(endLine, SCE_DIFF_COMMAND); |
|
} else if (0 == strncmp(lineBuffer, "--- ", 4)) { |
|
// In a context diff, --- appears in both the header and the position markers |
|
if (atoi(lineBuffer+4) && !strchr(lineBuffer, '/')) |
|
styler.ColourTo(endLine, SCE_DIFF_POSITION); |
|
else |
|
styler.ColourTo(endLine, SCE_DIFF_HEADER); |
|
} else if (0 == strncmp(lineBuffer, "+++ ", 4)) { |
|
// I don't know of any diff where "+++ " is a position marker, but for |
|
// consistency, do the same as with "--- " and "*** ". |
|
if (atoi(lineBuffer+4) && !strchr(lineBuffer, '/')) |
|
styler.ColourTo(endLine, SCE_DIFF_POSITION); |
|
else |
|
styler.ColourTo(endLine, SCE_DIFF_HEADER); |
|
} else if (0 == strncmp(lineBuffer, "====", 4)) { // For p4's diff |
|
styler.ColourTo(endLine, SCE_DIFF_HEADER); |
|
} else if (0 == strncmp(lineBuffer, "***", 3)) { |
|
// In a context diff, *** appears in both the header and the position markers. |
|
// Also ******** is a chunk header, but here it's treated as part of the |
|
// position marker since there is no separate style for a chunk header. |
|
if (lineBuffer[3] == ' ' && atoi(lineBuffer+4) && !strchr(lineBuffer, '/')) |
|
styler.ColourTo(endLine, SCE_DIFF_POSITION); |
|
else if (lineBuffer[3] == '*') |
|
styler.ColourTo(endLine, SCE_DIFF_POSITION); |
|
else |
|
styler.ColourTo(endLine, SCE_DIFF_HEADER); |
|
} else if (0 == strncmp(lineBuffer, "? ", 2)) { // For difflib |
|
styler.ColourTo(endLine, SCE_DIFF_HEADER); |
|
} else if (lineBuffer[0] == '@') { |
|
styler.ColourTo(endLine, SCE_DIFF_POSITION); |
|
} else if (lineBuffer[0] >= '0' && lineBuffer[0] <= '9') { |
|
styler.ColourTo(endLine, SCE_DIFF_POSITION); |
|
} else if (lineBuffer[0] == '-' || lineBuffer[0] == '<') { |
|
styler.ColourTo(endLine, SCE_DIFF_DELETED); |
|
} else if (lineBuffer[0] == '+' || lineBuffer[0] == '>') { |
|
styler.ColourTo(endLine, SCE_DIFF_ADDED); |
|
} else if (lineBuffer[0] != ' ') { |
|
styler.ColourTo(endLine, SCE_DIFF_COMMENT); |
|
} else { |
|
styler.ColourTo(endLine, SCE_DIFF_DEFAULT); |
|
} |
|
} |
|
|
|
static void ColouriseDiffDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { |
|
char lineBuffer[1024]; |
|
styler.StartAt(startPos); |
|
styler.StartSegment(startPos); |
|
unsigned int linePos = 0; |
|
for (unsigned int i = startPos; i < startPos + length; i++) { |
|
lineBuffer[linePos++] = styler[i]; |
|
if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) { |
|
// End of line (or of line buffer) met, colourise it |
|
lineBuffer[linePos] = '\0'; |
|
ColouriseDiffLine(lineBuffer, i, styler); |
|
linePos = 0; |
|
} |
|
} |
|
if (linePos > 0) { // Last line does not have ending characters |
|
ColouriseDiffLine(lineBuffer, startPos + length - 1, styler); |
|
} |
|
} |
|
|
|
static void FoldDiffDoc(unsigned int startPos, int length, int, WordList*[], Accessor &styler) { |
|
int curLine = styler.GetLine(startPos); |
|
int prevLevel = SC_FOLDLEVELBASE; |
|
if (curLine > 0) |
|
prevLevel = styler.LevelAt(curLine-1); |
|
|
|
int curLineStart = styler.LineStart(curLine); |
|
do { |
|
int nextLevel = prevLevel; |
|
if (prevLevel & SC_FOLDLEVELHEADERFLAG) |
|
nextLevel = (prevLevel & SC_FOLDLEVELNUMBERMASK) + 1; |
|
|
|
int lineType = styler.StyleAt(curLineStart); |
|
if (lineType == SCE_DIFF_COMMAND) |
|
nextLevel = (SC_FOLDLEVELBASE + 1) | SC_FOLDLEVELHEADERFLAG; |
|
else if (lineType == SCE_DIFF_HEADER) { |
|
nextLevel = (SC_FOLDLEVELBASE + 2) | SC_FOLDLEVELHEADERFLAG; |
|
} else if (lineType == SCE_DIFF_POSITION) |
|
nextLevel = (SC_FOLDLEVELBASE + 3) | SC_FOLDLEVELHEADERFLAG; |
|
|
|
if ((nextLevel & SC_FOLDLEVELHEADERFLAG) && (nextLevel == prevLevel)) |
|
styler.SetLevel(curLine-1, prevLevel & ~SC_FOLDLEVELHEADERFLAG); |
|
|
|
styler.SetLevel(curLine, nextLevel); |
|
prevLevel = nextLevel; |
|
|
|
curLineStart = styler.LineStart(++curLine); |
|
} while (static_cast<int>(startPos) + length > curLineStart); |
|
} |
|
|
|
|
|
static void ColourisePropsLine( |
|
char *lineBuffer, |
|
unsigned int lengthLine, |
|
unsigned int startLine, |
|
unsigned int endPos, |
|
Accessor &styler) { |
|
|
|
unsigned int i = 0; |
|
while ((i < lengthLine) && isspacechar(lineBuffer[i])) // Skip initial spaces |
|
i++; |
|
if (i < lengthLine) { |
|
if (lineBuffer[i] == '#' || lineBuffer[i] == '!' || lineBuffer[i] == ';') { |
|
styler.ColourTo(endPos, SCE_PROPS_COMMENT); |
|
} else if (lineBuffer[i] == '[') { |
|
styler.ColourTo(endPos, SCE_PROPS_SECTION); |
|
} else if (lineBuffer[i] == '@') { |
|
styler.ColourTo(startLine + i, SCE_PROPS_DEFVAL); |
|
if (lineBuffer[++i] == '=') |
|
styler.ColourTo(startLine + i, SCE_PROPS_ASSIGNMENT); |
|
styler.ColourTo(endPos, SCE_PROPS_DEFAULT); |
|
} else { |
|
// Search for the '=' character |
|
while ((i < lengthLine) && (lineBuffer[i] != '=')) |
|
i++; |
|
if ((i < lengthLine) && (lineBuffer[i] == '=')) { |
|
styler.ColourTo(startLine + i - 1, SCE_PROPS_KEY); |
|
styler.ColourTo(startLine + i, SCE_PROPS_ASSIGNMENT); |
|
styler.ColourTo(endPos, SCE_PROPS_DEFAULT); |
|
} else { |
|
styler.ColourTo(endPos, SCE_PROPS_DEFAULT); |
|
} |
|
} |
|
} else { |
|
styler.ColourTo(endPos, SCE_PROPS_DEFAULT); |
|
} |
|
} |
|
|
|
static void ColourisePropsDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { |
|
char lineBuffer[1024]; |
|
styler.StartAt(startPos); |
|
styler.StartSegment(startPos); |
|
unsigned int linePos = 0; |
|
unsigned int startLine = startPos; |
|
for (unsigned int i = startPos; i < startPos + length; i++) { |
|
lineBuffer[linePos++] = styler[i]; |
|
if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) { |
|
// End of line (or of line buffer) met, colourise it |
|
lineBuffer[linePos] = '\0'; |
|
ColourisePropsLine(lineBuffer, linePos, startLine, i, styler); |
|
linePos = 0; |
|
startLine = i + 1; |
|
} |
|
} |
|
if (linePos > 0) { // Last line does not have ending characters |
|
ColourisePropsLine(lineBuffer, linePos, startLine, startPos + length - 1, styler); |
|
} |
|
} |
|
|
|
// adaption by ksc, using the "} else {" trick of 1.53 |
|
// 030721 |
|
static void FoldPropsDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { |
|
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; |
|
|
|
unsigned int endPos = startPos + length; |
|
int visibleChars = 0; |
|
int lineCurrent = styler.GetLine(startPos); |
|
|
|
char chNext = styler[startPos]; |
|
int styleNext = styler.StyleAt(startPos); |
|
bool headerPoint = false; |
|
int lev; |
|
|
|
for (unsigned int i = startPos; i < endPos; i++) { |
|
char ch = chNext; |
|
chNext = styler[i+1]; |
|
|
|
int style = styleNext; |
|
styleNext = styler.StyleAt(i + 1); |
|
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); |
|
|
|
if (style == SCE_PROPS_SECTION) { |
|
headerPoint = true; |
|
} |
|
|
|
if (atEOL) { |
|
lev = SC_FOLDLEVELBASE; |
|
|
|
if (lineCurrent > 0) { |
|
int levelPrevious = styler.LevelAt(lineCurrent - 1); |
|
|
|
if (levelPrevious & SC_FOLDLEVELHEADERFLAG) { |
|
lev = SC_FOLDLEVELBASE + 1; |
|
} else { |
|
lev = levelPrevious & SC_FOLDLEVELNUMBERMASK; |
|
} |
|
} |
|
|
|
if (headerPoint) { |
|
lev = SC_FOLDLEVELBASE; |
|
} |
|
if (visibleChars == 0 && foldCompact) |
|
lev |= SC_FOLDLEVELWHITEFLAG; |
|
|
|
if (headerPoint) { |
|
lev |= SC_FOLDLEVELHEADERFLAG; |
|
} |
|
if (lev != styler.LevelAt(lineCurrent)) { |
|
styler.SetLevel(lineCurrent, lev); |
|
} |
|
|
|
lineCurrent++; |
|
visibleChars = 0; |
|
headerPoint = false; |
|
} |
|
if (!isspacechar(ch)) |
|
visibleChars++; |
|
} |
|
|
|
if (lineCurrent > 0) { |
|
int levelPrevious = styler.LevelAt(lineCurrent - 1); |
|
if (levelPrevious & SC_FOLDLEVELHEADERFLAG) { |
|
lev = SC_FOLDLEVELBASE + 1; |
|
} else { |
|
lev = levelPrevious & SC_FOLDLEVELNUMBERMASK; |
|
} |
|
} else { |
|
lev = SC_FOLDLEVELBASE; |
|
} |
|
int flagsNext = styler.LevelAt(lineCurrent); |
|
styler.SetLevel(lineCurrent, lev | flagsNext & ~SC_FOLDLEVELNUMBERMASK); |
|
} |
|
|
|
static void ColouriseMakeLine( |
|
char *lineBuffer, |
|
unsigned int lengthLine, |
|
unsigned int startLine, |
|
unsigned int endPos, |
|
Accessor &styler) { |
|
|
|
unsigned int i = 0; |
|
int lastNonSpace = -1; |
|
unsigned int state = SCE_MAKE_DEFAULT; |
|
bool bSpecial = false; |
|
// Skip initial spaces |
|
while ((i < lengthLine) && isspacechar(lineBuffer[i])) { |
|
i++; |
|
} |
|
if (lineBuffer[i] == '#') { // Comment |
|
styler.ColourTo(endPos, SCE_MAKE_COMMENT); |
|
return; |
|
} |
|
if (lineBuffer[i] == '!') { // Special directive |
|
styler.ColourTo(endPos, SCE_MAKE_PREPROCESSOR); |
|
return; |
|
} |
|
while (i < lengthLine) { |
|
if (lineBuffer[i] == '$' && lineBuffer[i + 1] == '(') { |
|
styler.ColourTo(startLine + i - 1, state); |
|
state = SCE_MAKE_IDENTIFIER; |
|
} else if (state == SCE_MAKE_IDENTIFIER && lineBuffer[i] == ')') { |
|
styler.ColourTo(startLine + i, state); |
|
state = SCE_MAKE_DEFAULT; |
|
} |
|
if (!bSpecial) { |
|
if (lineBuffer[i] == ':') { |
|
// We should check that no colouring was made since the beginning of the line, |
|
// to avoid colouring stuff like /OUT:file |
|
if (lastNonSpace >= 0) |
|
styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_TARGET); |
|
styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT); |
|
styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR); |
|
bSpecial = true; // Only react to the first ':' of the line |
|
state = SCE_MAKE_DEFAULT; |
|
} else if (lineBuffer[i] == '=') { |
|
if (lastNonSpace >= 0) |
|
styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER); |
|
styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT); |
|
styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR); |
|
bSpecial = true; // Only react to the first '=' of the line |
|
state = SCE_MAKE_DEFAULT; |
|
} |
|
} |
|
if (!isspacechar(lineBuffer[i])) { |
|
lastNonSpace = i; |
|
} |
|
i++; |
|
} |
|
if (state == SCE_MAKE_IDENTIFIER) { |
|
styler.ColourTo(endPos, SCE_MAKE_IDEOL); // Error, variable reference not ended |
|
} else { |
|
styler.ColourTo(endPos, SCE_MAKE_DEFAULT); |
|
} |
|
} |
|
|
|
static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { |
|
char lineBuffer[1024]; |
|
styler.StartAt(startPos); |
|
styler.StartSegment(startPos); |
|
unsigned int linePos = 0; |
|
unsigned int startLine = startPos; |
|
for (unsigned int i = startPos; i < startPos + length; i++) { |
|
lineBuffer[linePos++] = styler[i]; |
|
if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) { |
|
// End of line (or of line buffer) met, colourise it |
|
lineBuffer[linePos] = '\0'; |
|
ColouriseMakeLine(lineBuffer, linePos, startLine, i, styler); |
|
linePos = 0; |
|
startLine = i + 1; |
|
} |
|
} |
|
if (linePos > 0) { // Last line does not have ending characters |
|
ColouriseMakeLine(lineBuffer, linePos, startLine, startPos + length - 1, styler); |
|
} |
|
} |
|
|
|
static bool strstart(const char *haystack, const char *needle) { |
|
return strncmp(haystack, needle, strlen(needle)) == 0; |
|
} |
|
|
|
static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLine) { |
|
if (lineBuffer[0] == '>') { |
|
// Command or return status |
|
return SCE_ERR_CMD; |
|
} else if (lineBuffer[0] == '<') { |
|
// Diff removal, but not interested. Trapped to avoid hitting CTAG cases. |
|
return SCE_ERR_DEFAULT; |
|
} else if (lineBuffer[0] == '!') { |
|
return SCE_ERR_DIFF_CHANGED; |
|
} else if (lineBuffer[0] == '+') { |
|
if (strstart(lineBuffer, "+++ ")) { |
|
return SCE_ERR_DIFF_MESSAGE; |
|
} else { |
|
return SCE_ERR_DIFF_ADDITION; |
|
} |
|
} else if (lineBuffer[0] == '-') { |
|
if (strstart(lineBuffer, "--- ")) { |
|
return SCE_ERR_DIFF_MESSAGE; |
|
} else { |
|
return SCE_ERR_DIFF_DELETION; |
|
} |
|
} else if (strstart(lineBuffer, "cf90-")) { |
|
// Absoft Pro Fortran 90/95 v8.2 error and/or warning message |
|
return SCE_ERR_ABSF; |
|
} else if (strstart(lineBuffer, "fortcom:")) { |
|
// Intel Fortran Compiler v8.0 error/warning message |
|
return SCE_ERR_IFORT; |
|
} else if (strstr(lineBuffer, "File \"") && strstr(lineBuffer, ", line ")) { |
|
return SCE_ERR_PYTHON; |
|
} else if (strstr(lineBuffer, " in ") && strstr(lineBuffer, " on line ")) { |
|
return SCE_ERR_PHP; |
|
} else if ((strstart(lineBuffer, "Error ") || |
|
strstart(lineBuffer, "Warning ")) && |
|
strstr(lineBuffer, " at (") && |
|
strstr(lineBuffer, ") : ") && |
|
(strstr(lineBuffer, " at (") < strstr(lineBuffer, ") : "))) { |
|
// Intel Fortran Compiler error/warning message |
|
return SCE_ERR_IFC; |
|
} else if (strstart(lineBuffer, "Error ")) { |
|
// Borland error message |
|
return SCE_ERR_BORLAND; |
|
} else if (strstart(lineBuffer, "Warning ")) { |
|
// Borland warning message |
|
return SCE_ERR_BORLAND; |
|
} else if (strstr(lineBuffer, "at line " ) && |
|
(strstr(lineBuffer, "at line " ) < (lineBuffer + lengthLine)) && |
|
strstr(lineBuffer, "file ") && |
|
(strstr(lineBuffer, "file ") < (lineBuffer + lengthLine))) { |
|
// Lua 4 error message |
|
return SCE_ERR_LUA; |
|
} else if (strstr(lineBuffer, " at " ) && |
|
(strstr(lineBuffer, " at " ) < (lineBuffer + lengthLine)) && |
|
strstr(lineBuffer, " line ") && |
|
(strstr(lineBuffer, " line ") < (lineBuffer + lengthLine)) && |
|
(strstr(lineBuffer, " at " ) < (strstr(lineBuffer, " line ")))) { |
|
// perl error message |
|
return SCE_ERR_PERL; |
|
} else if ((memcmp(lineBuffer, " at ", 6) == 0) && |
|
strstr(lineBuffer, ":line ")) { |
|
// A .NET traceback |
|
return SCE_ERR_NET; |
|
} else if (strstart(lineBuffer, "Line ") && |
|
strstr(lineBuffer, ", file ")) { |
|
// Essential Lahey Fortran error message |
|
return SCE_ERR_ELF; |
|
} else if (strstart(lineBuffer, "line ") && |
|
strstr(lineBuffer, " column ")) { |
|
// HTML tidy style: line 42 column 1 |
|
return SCE_ERR_TIDY; |
|
} else if (strstart(lineBuffer, "\tat ") && |
|
strstr(lineBuffer, "(") && |
|
strstr(lineBuffer, ".java:")) { |
|
// Java stack back trace |
|
return SCE_ERR_JAVA_STACK; |
|
} else { |
|
// Look for one of the following formats: |
|
// GCC: <filename>:<line>:<message> |
|
// Microsoft: <filename>(<line>) :<message> |
|
// Common: <filename>(<line>): warning|error|note|remark|catastrophic|fatal |
|
// Common: <filename>(<line>) warning|error|note|remark|catastrophic|fatal |
|
// Microsoft: <filename>(<line>,<column>)<message> |
|
// CTags: \t<message> |
|
// Lua 5 traceback: \t<filename>:<line>:<message> |
|
bool initialTab = (lineBuffer[0] == '\t'); |
|
enum { stInitial, |
|
stGccStart, stGccDigit, stGcc, |
|
stMsStart, stMsDigit, stMsBracket, stMsVc, stMsDigitComma, stMsDotNet, |
|
stCtagsStart, stCtagsStartString, stCtagsStringDollar, stCtags, |
|
stUnrecognized |
|
} state = stInitial; |
|
for (unsigned int i = 0; i < lengthLine; i++) { |
|
char ch = lineBuffer[i]; |
|
char chNext = ' '; |
|
if ((i + 1) < lengthLine) |
|
chNext = lineBuffer[i + 1]; |
|
if (state == stInitial) { |
|
if (ch == ':') { |
|
// May be GCC, or might be Lua 5 (Lua traceback same but with tab prefix) |
|
if ((chNext != '\\') && (chNext != '/')) { |
|
// This check is not completely accurate as may be on |
|
// GTK+ with a file name that includes ':'. |
|
state = stGccStart; |
|
} |
|
} else if ((ch == '(') && Is1To9(chNext) && (!initialTab)) { |
|
// May be Microsoft |
|
// Check against '0' often removes phone numbers |
|
state = stMsStart; |
|
} else if ((ch == '\t') && (!initialTab)) { |
|
// May be CTags |
|
state = stCtagsStart; |
|
} |
|
} else if (state == stGccStart) { // <filename>: |
|
state = Is1To9(ch) ? stGccDigit : stUnrecognized; |
|
} else if (state == stGccDigit) { // <filename>:<line> |
|
if (ch == ':') { |
|
state = stGcc; // :9.*: is GCC |
|
break; |
|
} else if (!Is0To9(ch)) { |
|
state = stUnrecognized; |
|
} |
|
} else if (state == stMsStart) { // <filename>( |
|
state = Is0To9(ch) ? stMsDigit : stUnrecognized; |
|
} else if (state == stMsDigit) { // <filename>(<line> |
|
if (ch == ',') { |
|
state = stMsDigitComma; |
|
} else if (ch == ')') { |
|
state = stMsBracket; |
|
} else if ((ch != ' ') && !Is0To9(ch)) { |
|
state = stUnrecognized; |
|
} |
|
} else if (state == stMsBracket) { // <filename>(<line>) |
|
if ((ch == ' ') && (chNext == ':')) { |
|
state = stMsVc; |
|
} else if ((ch == ':' && chNext == ' ') || (ch == ' ')) { |
|
// Possibly Delphi.. don't test against chNext as it's one of the strings below. |
|
char word[512]; |
|
unsigned int j, chPos; |
|
unsigned numstep; |
|
chPos = 0; |
|
if (ch == ' ') |
|
numstep = 1; // ch was ' ', handle as if it's a delphi errorline, only add 1 to i. |
|
else |
|
numstep = 2; // otherwise add 2. |
|
for (j = i + numstep; j < lengthLine && isalpha(lineBuffer[j]) && chPos < sizeof(word) - 1; j++) |
|
word[chPos++] = lineBuffer[j]; |
|
word[chPos] = 0; |
|
if (!CompareCaseInsensitive(word, "error") || !CompareCaseInsensitive(word, "warning") || |
|
!CompareCaseInsensitive(word, "fatal") || !CompareCaseInsensitive(word, "catastrophic") || |
|
!CompareCaseInsensitive(word, "note") || !CompareCaseInsensitive(word, "remark")) { |
|
state = stMsVc; |
|
} else |
|
state = stUnrecognized; |
|
} else { |
|
state = stUnrecognized; |
|
} |
|
} else if (state == stMsDigitComma) { // <filename>(<line>, |
|
if (ch == ')') { |
|
state = stMsDotNet; |
|
break; |
|
} else if ((ch != ' ') && !Is0To9(ch)) { |
|
state = stUnrecognized; |
|
} |
|
} else if (state == stCtagsStart) { |
|
if ((lineBuffer[i - 1] == '\t') && |
|
((ch == '/' && lineBuffer[i + 1] == '^') || Is0To9(ch))) { |
|
state = stCtags; |
|
break; |
|
} else if ((ch == '/') && (lineBuffer[i + 1] == '^')) { |
|
state = stCtagsStartString; |
|
} |
|
} else if ((state == stCtagsStartString) && ((lineBuffer[i] == '$') && (lineBuffer[i + 1] == '/'))) { |
|
state = stCtagsStringDollar; |
|
break; |
|
} |
|
} |
|
if (state == stGcc) { |
|
return SCE_ERR_GCC; |
|
} else if ((state == stMsVc) || (state == stMsDotNet)) { |
|
return SCE_ERR_MS; |
|
} else if ((state == stCtagsStringDollar) || (state == stCtags)) { |
|
return SCE_ERR_CTAG; |
|
} else { |
|
return SCE_ERR_DEFAULT; |
|
} |
|
} |
|
} |
|
|
|
static void ColouriseErrorListLine( |
|
char *lineBuffer, |
|
unsigned int lengthLine, |
|
unsigned int endPos, |
|
Accessor &styler) { |
|
styler.ColourTo(endPos, RecogniseErrorListLine(lineBuffer, lengthLine)); |
|
} |
|
|
|
static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { |
|
char lineBuffer[10000]; |
|
styler.StartAt(startPos); |
|
styler.StartSegment(startPos); |
|
unsigned int linePos = 0; |
|
for (unsigned int i = startPos; i < startPos + length; i++) { |
|
lineBuffer[linePos++] = styler[i]; |
|
if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) { |
|
// End of line (or of line buffer) met, colourise it |
|
lineBuffer[linePos] = '\0'; |
|
ColouriseErrorListLine(lineBuffer, linePos, i, styler); |
|
linePos = 0; |
|
} |
|
} |
|
if (linePos > 0) { // Last line does not have ending characters |
|
ColouriseErrorListLine(lineBuffer, linePos, startPos + length - 1, styler); |
|
} |
|
} |
|
|
|
static int isSpecial(char s) { |
|
return (s == '\\') || (s == ',') || (s == ';') || (s == '\'') || (s == ' ') || |
|
(s == '\"') || (s == '`') || (s == '^') || (s == '~'); |
|
} |
|
|
|
static int isTag(int start, Accessor &styler) { |
|
char s[6]; |
|
unsigned int i = 0, e = 1; |
|
while (i < 5 && e) { |
|
s[i] = styler[start + i]; |
|
i++; |
|
e = styler[start + i] != '{'; |
|
} |
|
s[i] = '\0'; |
|
return (strcmp(s, "begin") == 0) || (strcmp(s, "end") == 0); |
|
} |
|
|
|
static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle, |
|
WordList *[], Accessor &styler) { |
|
|
|
styler.StartAt(startPos); |
|
|
|
int state = initStyle; |
|
char chNext = styler[startPos]; |
|
styler.StartSegment(startPos); |
|
int lengthDoc = startPos + length; |
|
|
|
for (int i = startPos; i < lengthDoc; i++) { |
|
char ch = chNext; |
|
chNext = styler.SafeGetCharAt(i + 1); |
|
|
|
if (styler.IsLeadByte(ch)) { |
|
chNext = styler.SafeGetCharAt(i + 2); |
|
i++; |
|
continue; |
|
} |
|
switch (state) { |
|
case SCE_L_DEFAULT : |
|
switch (ch) { |
|
case '\\' : |
|
styler.ColourTo(i - 1, state); |
|
if (isSpecial(styler[i + 1])) { |
|
styler.ColourTo(i + 1, SCE_L_COMMAND); |
|
i++; |
|
chNext = styler.SafeGetCharAt(i + 1); |
|
} else { |
|
if (isTag(i + 1, styler)) |
|
state = SCE_L_TAG; |
|
else |
|
state = SCE_L_COMMAND; |
|
} |
|
break; |
|
case '$' : |
|
styler.ColourTo(i - 1, state); |
|
state = SCE_L_MATH; |
|
if (chNext == '$') { |
|
i++; |
|
chNext = styler.SafeGetCharAt(i + 1); |
|
} |
|
break; |
|
case '%' : |
|
styler.ColourTo(i - 1, state); |
|
state = SCE_L_COMMENT; |
|
break; |
|
} |
|
break; |
|
case SCE_L_COMMAND : |
|
if (chNext == '[' || chNext == '{' || chNext == '}' || |
|
chNext == ' ' || chNext == '\r' || chNext == '\n') { |
|
styler.ColourTo(i, state); |
|
state = SCE_L_DEFAULT; |
|
i++; |
|
chNext = styler.SafeGetCharAt(i + 1); |
|
} |
|
break; |
|
case SCE_L_TAG : |
|
if (ch == '}') { |
|
styler.ColourTo(i, state); |
|
state = SCE_L_DEFAULT; |
|
} |
|
break; |
|
case SCE_L_MATH : |
|
if (ch == '$') { |
|
if (chNext == '$') { |
|
i++; |
|
chNext = styler.SafeGetCharAt(i + 1); |
|
} |
|
styler.ColourTo(i, state); |
|
state = SCE_L_DEFAULT; |
|
} |
|
break; |
|
case SCE_L_COMMENT : |
|
if (ch == '\r' || ch == '\n') { |
|
styler.ColourTo(i - 1, state); |
|
state = SCE_L_DEFAULT; |
|
} |
|
} |
|
} |
|
styler.ColourTo(lengthDoc-1, state); |
|
} |
|
|
|
static const char * const batchWordListDesc[] = { |
|
"Internal Commands", |
|
"External Commands", |
|
0 |
|
}; |
|
|
|
static const char * const emptyWordListDesc[] = { |
|
0 |
|
}; |
|
|
|
static void ColouriseNullDoc(unsigned int startPos, int length, int, WordList *[], |
|
Accessor &styler) { |
|
// Null language means all style bytes are 0 so just mark the end - no need to fill in. |
|
if (length > 0) { |
|
styler.StartAt(startPos + length - 1); |
|
styler.StartSegment(startPos + length - 1); |
|
styler.ColourTo(startPos + length - 1, 0); |
|
} |
|
} |
|
|
|
LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch", 0, batchWordListDesc); |
|
LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff", FoldDiffDoc, emptyWordListDesc); |
|
LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, "props", FoldPropsDoc, emptyWordListDesc); |
|
LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile", 0, emptyWordListDesc); |
|
LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist", 0, emptyWordListDesc); |
|
LexerModule lmLatex(SCLEX_LATEX, ColouriseLatexDoc, "latex", 0, emptyWordListDesc); |
|
LexerModule lmNull(SCLEX_NULL, ColouriseNullDoc, "null");
|
|
|