// 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 // The License.txt file describes the conditions under which this software may be distributed. #include #include #include #include #include #include "Platform.h" #include "PropSet.h" #include "Accessor.h" #include "KeyWords.h" #include "Scintilla.h" #include "SciLexer.h" static void ColouriseBatchLine( char *lineBuffer, unsigned int lengthLine, unsigned int startLine, unsigned int endPos, WordList &keywords, Accessor &styler) { unsigned int i = 0; unsigned int state = SCE_BAT_DEFAULT; while (isspacechar(lineBuffer[i]) && (i < lengthLine)) { // Skip initial spaces i++; } if (lineBuffer[i] == '@') { // Hide command (ECHO OFF) styler.ColourTo(startLine + i, SCE_BAT_HIDE); i++; while (isspacechar(lineBuffer[i]) && (i < lengthLine)) { // Skip next spaces i++; } } if (lineBuffer[i] == ':') { // Label if (lineBuffer[i + 1] == ':') { // :: is a fake label, similar to REM, see http://www.winmag.com/columns/explorer/2000/21.htm styler.ColourTo(endPos, SCE_BAT_COMMENT); } else { // Real label styler.ColourTo(endPos, SCE_BAT_LABEL); } } else { // Check if initial word is a keyword char wordBuffer[21]; unsigned int wbl = 0, offset = i; // Copy word in buffer for (; offset < lengthLine && wbl < 20 && !isspacechar(lineBuffer[offset]); wbl++, offset++) { wordBuffer[wbl] = static_cast(tolower(lineBuffer[offset])); } wordBuffer[wbl] = '\0'; // Check if it is a comment if (CompareCaseInsensitive(wordBuffer, "rem") == 0) { styler.ColourTo(endPos, SCE_BAT_COMMENT); return ; } // Check if it is in the list if (keywords.InList(wordBuffer)) { styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD); // Regular keyword } else { // Search end of word (can be a long path) while (offset < lengthLine && !isspacechar(lineBuffer[offset])) { offset++; } styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); // External command / program } // Remainder of the line: colourise the variables. while (offset < lengthLine) { if (state == SCE_BAT_DEFAULT && lineBuffer[offset] == '%') { styler.ColourTo(startLine + offset - 1, state); if (isdigit(lineBuffer[offset + 1])) { styler.ColourTo(startLine + offset + 1, SCE_BAT_IDENTIFIER); offset += 2; } else if (lineBuffer[offset + 1] == '%' && !isspacechar(lineBuffer[offset + 2])) { // Should be safe, as there is CRLF at the end of the line... styler.ColourTo(startLine + offset + 2, SCE_BAT_IDENTIFIER); offset += 3; } else { state = SCE_BAT_IDENTIFIER; } } else if (state == SCE_BAT_IDENTIFIER && lineBuffer[offset] == '%') { styler.ColourTo(startLine + offset, state); state = SCE_BAT_DEFAULT; } else if (state == SCE_BAT_DEFAULT && (lineBuffer[offset] == '*' || lineBuffer[offset] == '?' || lineBuffer[offset] == '=' || lineBuffer[offset] == '<' || lineBuffer[offset] == '>' || lineBuffer[offset] == '|')) { styler.ColourTo(startLine + offset - 1, state); styler.ColourTo(startLine + offset, SCE_BAT_OPERATOR); } offset++; } // if (endPos > startLine + offset - 1) { styler.ColourTo(endPos, SCE_BAT_DEFAULT); // Remainder of line, currently not lexed // } } } // ToDo: (not necessarily at beginning of line) GOTO, [IF] NOT, ERRORLEVEL // IF [NO] (test) (command) -- test is EXIST (filename) | (string1)==(string2) | ERRORLEVEL (number) // FOR %%(variable) IN (set) DO (command) -- variable is [a-zA-Z] -- eg for %%X in (*.txt) do type %%X // ToDo: %n (parameters), %EnvironmentVariable% colourising // ToDo: Colourise = > >> < | " static void ColouriseBatchDoc( unsigned int startPos, int length, int /*initStyle*/, WordList *keywordlists[], Accessor &styler) { char lineBuffer[1024]; WordList &keywords = *keywordlists[0]; styler.StartAt(startPos); styler.StartSegment(startPos); unsigned int linePos = 0, startLine = startPos; for (unsigned int i = startPos; i <= startPos + length; i++) { lineBuffer[linePos++] = styler[i]; if (styler[i] == '\r' || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) { // End of line (or of line buffer) met, colourise it if (styler[i + 1] == '\n') { lineBuffer[linePos++] = styler[++i]; } lineBuffer[linePos] = '\0'; ColouriseBatchLine(lineBuffer, linePos, startLine, i, keywords, styler); linePos = 0; startLine = i + 1; } } if (linePos > 0) { ColouriseBatchLine(lineBuffer, linePos, startLine, startPos + length, keywords, 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 ", 3)) { styler.ColourTo(endLine, 2); } else if (0 == strncmp(lineBuffer, "--- ", 3)) { styler.ColourTo(endLine, 3); } else if (0 == strncmp(lineBuffer, "+++ ", 3)) { styler.ColourTo(endLine, 3); } else if (lineBuffer[0] == '@') { styler.ColourTo(endLine, 4); } else if (lineBuffer[0] == '-') { styler.ColourTo(endLine, 5); } else if (lineBuffer[0] == '+') { styler.ColourTo(endLine, 6); } else if (lineBuffer[0] != ' ') { styler.ColourTo(endLine, 1); } else { styler.ColourTo(endLine, 0); } } 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 (styler[i] == '\r' || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) { ColouriseDiffLine(lineBuffer, i, styler); linePos = 0; } } if (linePos > 0) ColouriseDiffLine(lineBuffer, startPos + length, styler); } static void ColourisePropsLine( char *lineBuffer, unsigned int lengthLine, unsigned int startLine, unsigned int endPos, Accessor &styler) { unsigned int i = 0; while (isspacechar(lineBuffer[i]) && (i < lengthLine)) // Skip initial spaces i++; if (lineBuffer[i] == '#' || lineBuffer[i] == '!' || lineBuffer[i] == ';') { styler.ColourTo(endPos, 1); } else if (lineBuffer[i] == '[') { styler.ColourTo(endPos, 2); } else if (lineBuffer[i] == '@') { styler.ColourTo(startLine + i, 4); if (lineBuffer[++i] == '=') styler.ColourTo(startLine + i, 3); styler.ColourTo(endPos, 0); } else { // Search for the '=' character while (lineBuffer[i] != '=' && (i < lengthLine - 1)) i++; if (lineBuffer[i] == '=') { styler.ColourTo(startLine + i - 1, 0); styler.ColourTo(startLine + i, 3); styler.ColourTo(endPos, 0); } else { styler.ColourTo(endPos, 0); } } } 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, startLine = startPos; for (unsigned int i = startPos; i <= startPos + length; i++) { lineBuffer[linePos++] = styler[i]; if ((styler[i] == '\r' && styler.SafeGetCharAt(i + 1) != '\n') || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) { lineBuffer[linePos] = '\0'; ColourisePropsLine(lineBuffer, linePos, startLine, i, styler); linePos = 0; startLine = i + 1; } } if (linePos > 0) ColourisePropsLine(lineBuffer, linePos, startLine, startPos + length, styler); } static void ColouriseMakeLine( char *lineBuffer, unsigned int lengthLine, unsigned int startLiHTTP/1.1 200 OK Connection: keep-alive Connection: keep-alive Connection: keep-alive Content-Disposition: inline; filename="LexOthers.cxx" Content-Disposition: inline; filename="LexOthers.cxx" Content-Disposition: inline; filename="LexOthers.cxx" Content-Length: 16032 Content-Length: 16032 Content-Length: 16032 Content-Security-Policy: default-src 'none' Content-Security-Policy: default-src 'none' Content-Security-Policy: default-src 'none' Content-Type: text/plain; charset=UTF-8 Content-Type: text/plain; charset=UTF-8 Content-Type: text/plain; charset=UTF-8 Date: Fri, 17 Oct 2025 12:54:18 UTC ETag: "7ca6f5dfb7416b441aca4298c790563e3c18433c" ETag: "7ca6f5dfb7416b441aca4298c790563e3c18433c" ETag: "7ca6f5dfb7416b441aca4298c790563e3c18433c" Expires: Mon, 15 Oct 2035 12:54:18 GMT Expires: Mon, 15 Oct 2035 12:54:18 GMT Expires: Mon, 15 Oct 2035 12:54:18 GMT Last-Modified: Fri, 17 Oct 2025 12:54:18 GMT Last-Modified: Fri, 17 Oct 2025 12:54:18 GMT Last-Modified: Fri, 17 Oct 2025 12:54:18 GMT Server: OpenBSD httpd Server: OpenBSD httpd Server: OpenBSD httpd X-Content-Type-Options: nosniff X-Content-Type-Options: nosniff X-Content-Type-Options: nosniff // 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 // The License.txt file describes the conditions under which this software may be distributed. #include #include #include #include #include #include "Platform.h" #include "PropSet.h" #include "Accessor.h" #include "KeyWords.h" #include "Scintilla.h" #include "SciLexer.h" static void ColouriseBatchLine( char *lineBuffer, unsigned int lengthLine, unsigned int startLine, unsigned int endPos, WordList &keywords, Accessor &styler) { unsigned int i = 0; unsigned int state = SCE_BAT_DEFAULT; while (isspacechar(lineBuffer[i]) && (i < lengthLine)) { // Skip initial spaces i++; } if (lineBuffer[i] == '@') { // Hide command (ECHO OFF) styler.ColourTo(startLine + i, SCE_BAT_HIDE); i++; while (isspacechar(lineBuffer[i]) && (i < lengthLine)) { // Skip next spaces i++; } } if (lineBuffer[i] == ':') { // Label if (lineBuffer[i + 1] == ':') { // :: is a fake label, similar to REM, see http://www.winmag.com/columns/explorer/2000/21.htm styler.ColourTo(endPos, SCE_BAT_COMMENT); } else { // Real label styler.ColourTo(endPos, SCE_BAT_LABEL); } } else { // Check if initial word is a keyword char wordBuffer[21]; unsigned int wbl = 0, offset = i; // Copy word in buffer for (; offset < lengthLine && wbl < 20 && !isspacechar(lineBuffer[offset]); wbl++, offset++) { wordBuffer[wbl] = static_cast(tolower(lineBuffer[offset])); } wordBuffer[wbl] = '\0'; // Check if it is a comment if (CompareCaseInsensitive(wordBuffer, "rem") == 0) { styler.ColourTo(endPos, SCE_BAT_COMMENT); return ; } // Check if it is in the list if (keywords.InList(wordBuffer)) { styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD); // Regular keyword } else { // Search end of word (can be a long path) while (offset < lengthLine && !isspacechar(lineBuffer[offset])) { offset++; } styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); // External command / program } // Remainder of the line: colourise the variables. while (offset < lengthLine) { if (state == SCE_BAT_DEFAULT && lineBuffer[offset] == '%') { styler.ColourTo(startLine + offset - 1, state); if (isdigit(lineBuffer[offset + 1])) { styler.ColourTo(startLine + offset + 1, SCE_BAT_IDENTIFIER); offset += 2; } else if (lineBuffer[offset + 1] == '%' && !isspacechar(lineBuffer[offset + 2])) { // Should be safe, as there is CRLF at the end of the line... styler.ColourTo(startLine + offset + 2, SCE_BAT_IDENTIFIER); offset += 3; } else { state = SCE_BAT_IDENTIFIER; } } else if (state == SCE_BAT_IDENTIFIER && lineBuffer[offset] == '%') { styler.ColourTo(startLine + offset, state); state = SCE_BAT_DEFAULT; } else if (state == SCE_BAT_DEFAULT && (lineBuffer[offset] == '*' || lineBuffer[offset] == '?' || lineBuffer[offset] == '=' || lineBuffer[offset] == '<' || lineBuffer[offset] == '>' || lineBuffer[offset] == '|')) { styler.ColourTo(startLine + offset - 1, state); styler.ColourTo(startLine + offset, SCE_BAT_OPERATOR); } offset++; } // if (endPos > startLine + offset - 1) { styler.ColourTo(endPos, SCE_BAT_DEFAULT); // Remainder of line, currently not lexed // } } } // ToDo: (not necessarily at beginning of line) GOTO, [IF] NOT, ERRORLEVEL // IF [NO] (test) (command) -- test is EXIST (filename) | (string1)==(string2) | ERRORLEVEL (number) // FOR %%(variable) IN (set) DO (command) -- variable is [a-zA-Z] -- eg for %%X in (*.txt) do type %%X // ToDo: %n (parameters), %EnvironmentVariable% colourising // ToDo: Colourise = > >> < | " static void ColouriseBatchDoc( unsigned int startPos, int length, int /*initStyle*/, WordList *keywordlists[], Accessor &styler) { char lineBuffer[1024]; WordList &keywords = *keywordlists[0]; styler.StartAt(startPos); styler.StartSegment(startPos); unsigned int linePos = 0, startLine = startPos; for (unsigned int i = startPos; i <= startPos + length; i++) { lineBuffer[linePos++] = styler[i]; if (styler[i] == '\r' || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) { // End of line (or of line buffer) met, colourise it if (styler[i + 1] == '\n') { lineBuffer[linePos++] = styler[++i]; } lineBuffer[linePos] = '\0'; ColouriseBatchLine(lineBuffer, linePos, startLine, i, keywords, styler); linePos = 0; startLine = i + 1; } } if (linePos > 0) { ColouriseBatchLine(lineBuffer, linePos, startLine, startPos + length, keywords, 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 ", 3)) { styler.ColourTo(endLine, 2); } else if (0 == strncmp(lineBuffer, "--- ", 3)) { styler.ColourTo(endLine, 3); } else if (0 == strncmp(lineBuffer, "+++ ", 3)) { styler.ColourTo(endLine, 3); } else if (lineBuffer[0] == '@') { styler.ColourTo(endLine, 4); } else if (lineBuffer[0] == '-') { styler.ColourTo(endLine, 5); } else if (lineBuffer[0] == '+') { styler.ColourTo(endLine, 6); } else if (lineBuffer[0] != ' ') { styler.ColourTo(endLine, 1); } else { styler.ColourTo(endLine, 0); } } 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 (styler[i] == '\r' || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) { ColouriseDiffLine(lineBuffer, i, styler); linePos = 0; } } if (linePos > 0) ColouriseDiffLine(lineBuffer, startPos + length, styler); } static void ColourisePropsLine( char *lineBuffer, unsigned int lengthLine, unsigned int startLine, unsigned int endPos, Accessor &styler) { unsigned int i = 0; while (isspacech