-// SciTE - Scintilla based Text Editor
-// KeyWords.cxx - colourise for particular languages
-// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
+// Scintilla source code edit control
+/** @file KeyWords.cxx
+ ** Colourise for particular languages.
+ **/
+// 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 <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
#include "Platform.h"
#include "Scintilla.h"
#include "SciLexer.h"
-inline bool IsLeadByte(int codePage, char ch) {
-#if PLAT_GTK
- // TODO: support DBCS under GTK+
- return false;
-#elif PLAT_WIN
- return codePage && IsDBCSLeadByteEx(codePage, ch);
-#elif PLAT_WX
- return false;
-#endif
-}
-
-inline bool iswordchar(char ch) {
- return isalnum(ch) || ch == '.' || ch == '_';
-}
-
-inline bool iswordstart(char ch) {
- return isalnum(ch) || ch == '_';
-}
-
-enum { wsSpace = 1, wsTab = 2, wsSpaceTab = 4, wsInconsistent=8};
-
-static int IndentAmount(StylingContext &styler, int line, int *flags) {
- int end = styler.Length();
- int spaceFlags = 0;
-
- // Determines the indentation level of the current line and also checks for consistent
- // indentation compared to the previous line.
- // Indentation is judged consistent when the indentation whitespace of each line lines
- // the same or the indentation of one line is a prefix of the other.
-
- int pos = styler.LineStart(line);
- char ch = styler[pos];
- int indent = 0;
- bool inPrevPrefix = line > 0;
- int posPrev = inPrevPrefix ? styler.LineStart(line-1) : 0;
- while ((ch == ' ' || ch == '\t') && (pos < end)) {
- if (inPrevPrefix) {
- char chPrev = styler[posPrev++];
- if (chPrev == ' ' || chPrev == '\t') {
- if (chPrev != ch)
- spaceFlags |= wsInconsistent;
- } else {
- inPrevPrefix = false;
- }
- }
- if (ch == ' ') {
- spaceFlags |= wsSpace;
- indent++;
- } else { // Tab
- spaceFlags |= wsTab;
- if (spaceFlags & wsSpace)
- spaceFlags |= wsSpaceTab;
- indent = (indent / 8 + 1) * 8;
- }
- ch = styler[++pos];
- }
-
- *flags = spaceFlags;
- indent += SC_FOLDLEVELBASE;
- if (isspace(ch)) // Completely empty line
- return indent | SC_FOLDLEVELWHITEFLAG;
- else
- return indent;
-}
-
-inline bool isoperator(char ch) {
- if (isalnum(ch))
- return false;
- // '.' left out as it is used to make up numbers
- if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
- ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
- ch == '=' || ch == '|' || ch == '{' || ch == '}' ||
- ch == '[' || ch == ']' || ch == ':' || ch == ';' ||
- ch == '<' || ch == '>' || ch == ',' || ch == '/' ||
- ch == '?' || ch == '!' || ch == '.' || ch == '~')
- return true;
- return false;
-}
-
-static void classifyWordCpp(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) {
- char s[100];
- bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
- for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
- s[i] = styler[start + i];
- s[i + 1] = '\0';
- }
- char chAttr = SCE_C_IDENTIFIER;
- if (wordIsNumber)
- chAttr = SCE_C_NUMBER;
- else {
- if (keywords.InList(s))
- chAttr = SCE_C_WORD;
- }
- styler.ColourSegment(start, end, chAttr);
-}
-
-static void ColouriseCppDoc(int codePage, int startPos, int length,
- int initStyle, WordList &keywords, StylingContext &styler) {
-
- bool fold = styler.GetPropSet().GetInt("fold");
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
-
- int state = initStyle;
- char chPrev = ' ';
- char chNext = styler[startPos];
- int startSeg = startPos;
- int lengthDoc = startPos + length;
- int visChars = 0;
- for (unsigned int i = startPos; i <= lengthDoc; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
-
- if ((fold) && ((ch == '\r' && chNext != '\n') || (ch == '\n'))) {
- int lev = levelPrev;
- if (visChars == 0)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev) && (visChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- styler.SetLevel(lineCurrent, lev);
- lineCurrent++;
- visChars = 0;
- levelPrev = levelCurrent;
- }
- if (!isspace(ch))
- visChars++;
-
- if (IsLeadByte(codePage, ch)) { // dbcs
- chNext = styler.SafeGetCharAt(i + 2);
- chPrev = ' ';
- i += 1;
- continue;
- }
-
- if (state == SCE_C_STRINGEOL) {
- if (ch != '\r' && ch != '\n') {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_C_DEFAULT;
- startSeg = i;
- }
- }
- if (state == SCE_C_DEFAULT) {
- if (iswordstart(ch)) {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_C_WORD;
- startSeg = i;
- } else if (ch == '/' && chNext == '*') {
- styler.ColourSegment(startSeg, i - 1, state);
- if (styler.SafeGetCharAt(i + 2) == '*')
- state = SCE_C_COMMENTDOC;
- else
- state = SCE_C_COMMENT;
- startSeg = i;
- } else if (ch == '/' && chNext == '/') {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_C_COMMENTLINE;
- startSeg = i;
- } else if (ch == '\"') {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_C_STRING;
- startSeg = i;
- } else if (ch == '\'') {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_C_CHARACTER;
- startSeg = i;
- } else if (ch == '#') {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_C_PREPROCESSOR;
- startSeg = i;
- } else if (isoperator(ch)) {
- styler.ColourSegment(startSeg, i - 1, state);
- styler.ColourSegment(i, i, SCE_C_OPERATOR);
- startSeg = i + 1;
- if ((ch == '{') || (ch == '}')) {
- levelCurrent += (ch == '{') ? 1 : -1;
- }
- }
- } else if (state == SCE_C_WORD) {
- if (!iswordchar(ch)) {
- classifyWordCpp(startSeg, i - 1, keywords, styler);
- state = SCE_C_DEFAULT;
- startSeg = i;
- if (ch == '/' && chNext == '*') {
- if (styler.SafeGetCharAt(i + 2) == '*')
- state = SCE_C_COMMENTDOC;
- else
- state = SCE_C_COMMENT;
- } else if (ch == '/' && chNext == '/') {
- state = SCE_C_COMMENTLINE;
- } else if (ch == '\"') {
- state = SCE_C_STRING;
- } else if (ch == '\'') {
- state = SCE_C_CHARACTER;
- } else if (ch == '#') {
- state = SCE_C_PREPROCESSOR;
- } else if (isoperator(ch)) {
- styler.ColourSegment(startSeg, i, SCE_C_OPERATOR);
- startSeg = i + 1;
- if ((ch == '{') || (ch == '}')) {
- levelCurrent += (ch == '{') ? 1 : -1;
- }
- }
- }
- } else {
- if (state == SCE_C_PREPROCESSOR) {
- if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_C_DEFAULT;
- startSeg = i;
- }
- } else if (state == SCE_C_COMMENT) {
- if (ch == '/' && chPrev == '*' && (
- (i > startSeg + 2) || ((initStyle == SCE_C_COMMENT) && (startSeg == startPos)))) {
- styler.ColourSegment(startSeg, i, state);
- state = SCE_C_DEFAULT;
- startSeg = i + 1;
- }
- } else if (state == SCE_C_COMMENTDOC) {
- if (ch == '/' && chPrev == '*' && (
- (i > startSeg + 3) || ((initStyle == SCE_C_COMMENTDOC) && (startSeg == startPos)))) {
- styler.ColourSegment(startSeg, i, state);
- state = SCE_C_DEFAULT;
- startSeg = i + 1;
- }
- } else if (state == SCE_C_COMMENTLINE) {
- if (ch == '\r' || ch == '\n') {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_C_DEFAULT;
- startSeg = i;
- }
- } else if (state == SCE_C_STRING) {
- if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_C_STRINGEOL;
- startSeg = i;
- } else if (ch == '\\') {
- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- } else if (ch == '\"') {
- styler.ColourSegment(startSeg, i, state);
- state = SCE_C_DEFAULT;
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- startSeg = i;
- }
- } else if (state == SCE_C_CHARACTER) {
- if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_C_STRINGEOL;
- startSeg = i;
- } else if (ch == '\\') {
- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- } else if (ch == '\'') {
- styler.ColourSegment(startSeg, i, state);
- state = SCE_C_DEFAULT;
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- startSeg = i;
- }
- }
- if (state == SCE_C_DEFAULT) { // One of the above succeeded
- if (ch == '/' && chNext == '*') {
- if (styler.SafeGetCharAt(i + 2) == '*')
- state = SCE_C_COMMENTDOC;
- else
- state = SCE_C_COMMENT;
- } else if (ch == '/' && chNext == '/') {
- state = SCE_C_COMMENTLINE;
- } else if (ch == '\"') {
- state = SCE_C_STRING;
- } else if (ch == '\'') {
- state = SCE_C_CHARACTER;
- } else if (ch == '#') {
- state = SCE_C_PREPROCESSOR;
- } else if (iswordstart(ch)) {
- state = SCE_C_WORD;
- } else if (isoperator(ch)) {
- styler.ColourSegment(startSeg, i, SCE_C_OPERATOR);
- startSeg = i + 1;
- if ((ch == '{') || (ch == '}')) {
- levelCurrent += (ch == '{') ? 1 : -1;
- }
- }
- }
- }
- chPrev = ch;
- }
- if (startSeg < lengthDoc)
- styler.ColourSegment(startSeg, lengthDoc - 1, state);
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- if (fold) {
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- //styler.SetLevel(lineCurrent, levelCurrent | flagsNext);
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-
- }
-}
-
-inline bool isPerlOperator(char ch) {
- if (isalnum(ch))
- return false;
- // '.' left out as it is used to make up numbers
- if (ch == '%' || ch == '^' || ch == '&' || ch == '*' || ch == '\\' ||
- ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
- ch == '=' || ch == '|' || ch == '{' || ch == '}' ||
- ch == '[' || ch == ']' || ch == ':' || ch == ';' ||
- ch == '<' || ch == '>' || ch == ',' || ch == '/' ||
- ch == '?' || ch == '!' || ch == '.' || ch == '~')
- return true;
- return false;
-}
-
-static int classifyWordPerl(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) {
- char s[100];
- bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
- for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
- s[i] = styler[start + i];
- s[i + 1] = '\0';
- }
- char chAttr = SCE_PL_IDENTIFIER;
- if (wordIsNumber)
- chAttr = SCE_PL_NUMBER;
- else {
- if (keywords.InList(s))
- chAttr = SCE_PL_WORD;
- }
- styler.ColourSegment(start, end, chAttr);
- return chAttr;
-}
-
-static bool isEndVar(char ch) {
- return !isalnum(ch) && ch != '#' && ch != '$' &&
- ch != '_' && ch != '\'';
-}
-
-static bool isMatch(StylingContext &styler, int lengthDoc, int pos, const char *val) {
- if ((pos + static_cast<int>(strlen(val))) >= lengthDoc) {
- return false;
- }
- while (*val) {
- if (*val != styler[pos++]) {
- return false;
- }
- val++;
- }
- return true;
-}
-
-static bool isOKQuote(char ch) {
- if (isalnum(ch))
- return false;
- if (isspace(ch))
- return false;
- if (iscntrl(ch))
- return false;
- return true;
-}
-
-static char opposite(char ch) {
- if (ch == '(')
- return ')';
- if (ch == '[')
- return ']';
- if (ch == '{')
- return '}';
- if (ch == '<')
- return '>';
- return ch;
-}
-
-static void ColourisePerlDoc(int codePage, int startPos, int length, int initStyle,
- WordList &keywords, StylingContext &styler) {
- char sooked[100];
- int quotes = 0;
- char quoteDown = 'd';
- char quoteUp = 'd';
- int quoteRep = 1;
- int sookedpos = 0;
- bool preferRE = true;
- sooked[sookedpos] = '\0';
- int state = initStyle;
- int lengthDoc = startPos + length;
- // If in a long distance lexical state, seek to the beginning to find quote characters
- if (state == SCE_PL_HERE || state == SCE_PL_REGEX ||
- state == SCE_PL_REGSUBST || state == SCE_PL_LONGQUOTE) {
- while ((startPos > 1) && (styler.StyleAt(startPos - 1) == state)) {
- startPos--;
- }
- state = SCE_PL_DEFAULT;
- }
- styler.StartAt(startPos);
- char chPrev = ' ';
- char chNext = styler[startPos];
- int startSeg = startPos;
- for (int i = startPos; i <= lengthDoc; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- char chNext2 = styler.SafeGetCharAt(i + 2);
-
- if (IsLeadByte(codePage, ch)) { // dbcs
- chNext = styler.SafeGetCharAt(i + 2);
- chPrev = ' ';
- i += 1;
- continue;
- }
-
- if (state == SCE_PL_DEFAULT) {
- if (iswordstart(ch)) {
- styler.ColourSegment(startSeg, i - 1, state);
- if (ch == 's' && !isalnum(chNext)) {
- state = SCE_PL_REGSUBST;
- quotes = 0;
- quoteUp = '\0';
- quoteDown = '\0';
- quoteRep = 2;
- startSeg = i;
- } else if (ch == 'm' && !isalnum(chNext)) {
- state = SCE_PL_REGEX;
- quotes = 0;
- quoteUp = '\0';
- quoteDown = '\0';
- quoteRep = 1;
- startSeg = i;
- } else if (ch == 't' && chNext == 'r' && !isalnum(chNext2)) {
- state = SCE_PL_REGSUBST;
- quotes = 0;
- quoteUp = '\0';
- quoteDown = '\0';
- quoteRep = 2;
- startSeg = i;
- i++;
- chNext = chNext2;
- } else if (ch == 'q' && (chNext == 'q' || chNext == 'r' || chNext == 'w' || chNext == 'x') && !isalnum(chNext2)) {
- state = SCE_PL_LONGQUOTE;
- startSeg = i;
- i++;
- chNext = chNext2;
- quotes = 0;
- quoteUp = '\0';
- quoteDown = '\0';
- quoteRep = 1;
- } else {
- state = SCE_PL_WORD;
- startSeg = i;
- preferRE = false;
- }
- } else if (ch == '#') {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_PL_COMMENTLINE;
- startSeg = i;
- } else if (ch == '\"') {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_PL_STRING;
- startSeg = i;
- } else if (ch == '\'') {
- if (chPrev == '&') {
- // Archaic call
- styler.ColourSegment(i, i, state);
- startSeg = i + 1;
- } else {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_PL_CHARACTER;
- startSeg = i;
- }
- } else if (ch == '`') {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_PL_BACKTICKS;
- startSeg = i;
- } else if (ch == '$') {
- preferRE = false;
- styler.ColourSegment(startSeg, i - 1, state);
- if (isalnum(chNext) || chNext == '#' || chNext == '$' || chNext == '_') {
- state = SCE_PL_SCALAR;
- startSeg = i;
- } else if (chNext != '{' && chNext != '[') {
- styler.ColourSegment(i - 1, i, SCE_PL_SCALAR);
- i++;
- startSeg = i + 1;
- ch = ' ';
- chNext = ' ';
- } else {
- styler.ColourSegment(i, i, SCE_PL_SCALAR);
- startSeg = i + 1;
- }
- } else if (ch == '@') {
- preferRE = false;
- styler.ColourSegment(startSeg, i - 1, state);
- if (isalpha(chNext) || chNext == '#' || chNext == '$' || chNext == '_') {
- state = SCE_PL_ARRAY;
- startSeg = i;
- } else if (chNext != '{' && chNext != '[') {
- styler.ColourSegment(i - 1, i, SCE_PL_ARRAY);
- i++;
- startSeg = i + 1;
- ch = ' ';
- } else {
- styler.ColourSegment(i, i, SCE_PL_ARRAY);
- startSeg = i + 1;
- }
- } else if (ch == '%') {
- preferRE = false;
- styler.ColourSegment(startSeg, i - 1, state);
- if (isalpha(chNext) || chNext == '#' || chNext == '$' || chNext == '_') {
- state = SCE_PL_HASH;
- startSeg = i;
- } else if (chNext != '{' && chNext != '[') {
- styler.ColourSegment(i - 1, i, SCE_PL_HASH);
- i++;
- startSeg = i + 1;
- ch = ' ';
- } else {
- styler.ColourSegment(i, i, SCE_PL_HASH);
- startSeg = i + 1;
- }
- } else if (ch == '*') {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_PL_SYMBOLTABLE;
- startSeg = i;
- } else if (ch == '/' && preferRE) {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_PL_REGEX;
- quoteUp = '/';
- quoteDown = '/';
- quotes = 1;
- quoteRep = 1;
- startSeg = i;
- } else if (ch == '<' && chNext == '<') {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_PL_HERE;
- startSeg = i;
- i++;
- ch = chNext;
- chNext = chNext2;
- quotes = 0;
- sookedpos = 0;
- sooked[sookedpos] = '\0';
- } else if (ch == '=' && isalpha(chNext)) {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_PL_POD;
- startSeg = i;
- quotes = 0;
- sookedpos = 0;
- sooked[sookedpos] = '\0';
- } else if (isPerlOperator(ch)) {
- if (ch == ')' || ch == ']')
- preferRE = false;
- else
- preferRE = true;
- styler.ColourSegment(startSeg, i - 1, state);
- styler.ColourSegment(i, i, SCE_PL_OPERATOR);
- startSeg = i + 1;
- }
- } else if (state == SCE_PL_WORD) {
- if (!iswordchar(ch) && ch != '\'') { // Archaic Perl has quotes inside names
- if (isMatch(styler, lengthDoc, startSeg, "__DATA__")) {
- styler.ColourSegment(startSeg, i, SCE_PL_DATASECTION);
- state = SCE_PL_DATASECTION;
- } else if (isMatch(styler, lengthDoc, startSeg, "__END__")) {
- styler.ColourSegment(startSeg, i, SCE_PL_DATASECTION);
- state = SCE_PL_DATASECTION;
- } else {
- if (classifyWordPerl(startSeg, i - 1, keywords, styler) == SCE_PL_WORD)
- preferRE = true;
- state = SCE_PL_DEFAULT;
- startSeg = i;
- if (ch == '#') {
- state = SCE_PL_COMMENTLINE;
- } else if (ch == '\"') {
- state = SCE_PL_STRING;
- } else if (ch == '\'') {
- state = SCE_PL_CHARACTER;
- } else if (ch == '<' && chNext == '<') {
- state = SCE_PL_HERE;
- quotes = 0;
- startSeg = i;
- sookedpos = 0;
- sooked[sookedpos] = '\0';
- } else if (isPerlOperator(ch)) {
- if (ch == ')' || ch == ']')
- preferRE = false;
- else
- preferRE = true;
- styler.ColourSegment(startSeg, i, SCE_PL_OPERATOR);
- state = SCE_PL_DEFAULT;
- startSeg = i + 1;
- }
- }
- }
- } else {
- if (state == SCE_PL_COMMENTLINE) {
- if (ch == '\r' || ch == '\n') {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_PL_DEFAULT;
- startSeg = i;
- }
- } else if (state == SCE_PL_HERE) {
- if (isalnum(ch) && quotes < 2) {
- sooked[sookedpos++] = ch;
- sooked[sookedpos] = '\0';
- if (quotes == 0)
- quotes = 1;
- } else {
- quotes++;
- }
-
- if (quotes > 1 && isMatch(styler, lengthDoc, i, sooked)) {
- styler.ColourSegment(startSeg, i + sookedpos - 1, SCE_PL_HERE);
- state = SCE_PL_DEFAULT;
- i += sookedpos;
- startSeg = i;
- chNext = ' ';
- }
- } else if (state == SCE_PL_STRING) {
- if (ch == '\\') {
- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- } else if (ch == '\"') {
- styler.ColourSegment(startSeg, i, state);
- state = SCE_PL_DEFAULT;
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- startSeg = i;
- }
- } else if (state == SCE_PL_CHARACTER) {
- if (ch == '\\') {
- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- } else if (ch == '\'') {
- styler.ColourSegment(startSeg, i, state);
- state = SCE_PL_DEFAULT;
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- startSeg = i;
- }
- } else if (state == SCE_PL_BACKTICKS) {
- if (ch == '`') {
- styler.ColourSegment(startSeg, i, state);
- state = SCE_PL_DEFAULT;
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- startSeg = i;
- }
- } else if (state == SCE_PL_POD) {
- if (ch == '=') {
- if (isMatch(styler, lengthDoc, i, "=cut")) {
- styler.ColourSegment(startSeg, i - 1 + 4, state);
- i += 4;
- startSeg = i;
- state = SCE_PL_DEFAULT;
- chNext = ' ';
- ch = ' ';
- }
- }
- } else if (state == SCE_PL_SCALAR) {
- if (isEndVar(ch)) {
- styler.ColourSegment(startSeg, i - 1, state);
- startSeg = i;
- state = SCE_PL_DEFAULT;
- }
- } else if (state == SCE_PL_ARRAY) {
- if (isEndVar(ch)) {
- styler.ColourSegment(startSeg, i - 1, state);
- startSeg = i;
- state = SCE_PL_DEFAULT;
- }
- } else if (state == SCE_PL_HASH) {
- if (isEndVar(ch)) {
- styler.ColourSegment(startSeg, i - 1, state);
- startSeg = i;
- state = SCE_PL_DEFAULT;
- }
- } else if (state == SCE_PL_SYMBOLTABLE) {
- if (isEndVar(ch)) {
- styler.ColourSegment(startSeg, i - 1, state);
- startSeg = i;
- state = SCE_PL_DEFAULT;
- }
- } else if (state == SCE_PL_REF) {
- if (isEndVar(ch)) {
- styler.ColourSegment(startSeg, i - 1, state);
- startSeg = i;
- state = SCE_PL_DEFAULT;
- }
- } else if (state == SCE_PL_REGEX) {
- if (!quoteUp && !isspace(ch)) {
- quoteUp = ch;
- quoteDown = opposite(ch);
- quotes++;
- } else {
- if (ch == quoteDown && chPrev != '\\') {
- quotes--;
- if (quotes == 0) {
- quoteRep--;
- if (quoteUp == quoteDown) {
- quotes++;
- }
- }
- if (!isalpha(chNext)) {
- if (quoteRep <= 0) {
- styler.ColourSegment(startSeg, i, state);
- startSeg = i + 1;
- state = SCE_PL_DEFAULT;
- ch = ' ';
- }
- }
- } else if (ch == quoteUp && chPrev != '\\') {
- quotes++;
- } else if (!isalpha(chNext)) {
- if (quoteRep <= 0) {
- styler.ColourSegment(startSeg, i, state);
- startSeg = i + 1;
- state = SCE_PL_DEFAULT;
- ch = ' ';
- }
- }
- }
- } else if (state == SCE_PL_REGSUBST) {
- if (!quoteUp && !isspace(ch)) {
- quoteUp = ch;
- quoteDown = opposite(ch);
- quotes++;
- } else {
- if (ch == quoteDown && chPrev != '\\') {
- quotes--;
- if (quotes == 0) {
- quoteRep--;
- }
- if (!isalpha(chNext)) {
- if (quoteRep <= 0) {
- styler.ColourSegment(startSeg, i, state);
- startSeg = i + 1;
- state = SCE_PL_DEFAULT;
- ch = ' ';
- }
- }
- if (quoteUp == quoteDown) {
- quotes++;
- }
- } else if (ch == quoteUp && chPrev != '\\') {
- quotes++;
- } else if (!isalpha(chNext)) {
- if (quoteRep <= 0) {
- styler.ColourSegment(startSeg, i, state);
- startSeg = i + 1;
- state = SCE_PL_DEFAULT;
- ch = ' ';
- }
- }
- }
- } else if (state == SCE_PL_LONGQUOTE) {
- if (!quoteDown && !isspace(ch)) {
- quoteUp = ch;
- quoteDown = opposite(quoteUp);
- quotes++;
- } else if (ch == quoteDown) {
- quotes--;
- if (quotes == 0) {
- quoteRep--;
- if (quoteRep <= 0) {
- styler.ColourSegment(startSeg, i, state);
- startSeg = i + 1;
- state = SCE_PL_DEFAULT;
- ch = ' ';
- }
- if (quoteUp == quoteDown) {
- quotes++;
- }
- }
- } else if (ch == quoteUp) {
- quotes++;
- }
- }
-
- if (state == SCE_PL_DEFAULT) { // One of the above succeeded
- if (ch == '#') {
- state = SCE_PL_COMMENTLINE;
- } else if (ch == '\"') {
- state = SCE_PL_STRING;
- } else if (ch == '\'') {
- state = SCE_PL_CHARACTER;
- } else if (iswordstart(ch)) {
- state = SCE_PL_WORD;
- preferRE = false;
- } else if (isoperator(ch)) {
- styler.ColourSegment(startSeg, i, SCE_PL_OPERATOR);
- startSeg = i + 1;
- }
- }
- }
- chPrev = ch;
- }
- if (startSeg < lengthDoc)
- styler.ColourSegment(startSeg, lengthDoc, state);
-}
-
-
-static int classifyWordVB(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) {
- char s[100];
- bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
- for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
- s[i] = tolower(styler[start + i]);
- s[i + 1] = '\0';
- }
- char chAttr = SCE_C_DEFAULT;
- if (wordIsNumber)
- chAttr = SCE_C_NUMBER;
- else {
- if (keywords.InList(s)) {
- chAttr = SCE_C_WORD;
- if (strcmp(s, "rem") == 0)
- chAttr = SCE_C_COMMENTLINE;
- }
- }
- styler.ColourSegment(start, end, chAttr);
- if (chAttr == SCE_C_COMMENTLINE)
- return SCE_C_COMMENTLINE;
- else
- return SCE_C_DEFAULT;
-}
-
-static void ColouriseVBDoc(int codePage, int startPos, int length, int initStyle,
- WordList &keywords, StylingContext &styler) {
- int state = initStyle;
- char chNext = styler[startPos];
- int startSeg = startPos;
- int lengthDoc = startPos + length;
- for (int i = startPos; i < lengthDoc; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
-
- if (IsLeadByte(codePage, ch)) { // dbcs
- chNext = styler.SafeGetCharAt(i + 2);
- i += 1;
- continue;
- }
-
- if (state == SCE_C_DEFAULT) {
- if (iswordstart(ch)) {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_C_WORD;
- startSeg = i;
- } else if (ch == '\'') {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_C_COMMENTLINE;
- startSeg = i;
- } else if (ch == '\"') {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_C_STRING;
- startSeg = i;
- }
- } else if (state == SCE_C_WORD) {
- if (!iswordchar(ch)) {
- state = classifyWordVB(startSeg, i - 1, keywords, styler);
- if (state == SCE_C_DEFAULT) {
- startSeg = i;
- if (ch == '\'') {
- state = SCE_C_COMMENTLINE;
- } else if (ch == '\"') {
- state = SCE_C_STRING;
- }
- }
- }
- } else {
- if (state == SCE_C_COMMENTLINE) {
- if (ch == '\r' || ch == '\n') {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_C_DEFAULT;
- startSeg = i;
- }
- } else if (state == SCE_C_STRING) {
- // VB doubles quotes to preserve them
- if (ch == '\"') {
- styler.ColourSegment(startSeg, i, state);
- state = SCE_C_DEFAULT;
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- startSeg = i;
- }
- }
- if (state == SCE_C_DEFAULT) { // One of the above succeeded
- if (ch == '\'') {
- state = SCE_C_COMMENTLINE;
- } else if (ch == '\"') {
- state = SCE_C_STRING;
- } else if (iswordstart(ch)) {
- state = SCE_C_WORD;
- }
- }
- }
- }
- if (startSeg < lengthDoc)
- styler.ColourSegment(startSeg, lengthDoc, state);
-}
-
-static void classifyWordPy(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler, char *prevWord) {
- char s[100];
- bool wordIsNumber = isdigit(styler[start]);
- for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
- s[i] = styler[start + i];
- s[i + 1] = '\0';
- }
- char chAttr = SCE_P_IDENTIFIER;
- if (0 == strcmp(prevWord, "class"))
- chAttr = SCE_P_CLASSNAME;
- else if (0 == strcmp(prevWord, "def"))
- chAttr = SCE_P_DEFNAME;
- else if (wordIsNumber)
- chAttr = SCE_P_NUMBER;
- else if (keywords.InList(s))
- chAttr = SCE_P_WORD;
- styler.ColourSegment(start, end, chAttr);
- strcpy(prevWord, s);
-}
-
-static void ColourisePyDoc(int codePage, int startPos, int length, int initStyle, WordList &keywords, StylingContext &styler) {
- //Platform::DebugPrintf("Python coloured\n");
- bool fold = styler.GetPropSet().GetInt("fold");
- int whingeLevel = styler.GetPropSet().GetInt("tab.timmy.whinge.level");
- char prevWord[200];
- prevWord[0] = '\0';
- if (length == 0)
- return ;
- int lineCurrent = styler.GetLine(startPos);
- int spaceFlags = 0;
- // TODO: Need to check previous line for indentation for both folding and bad indentation
- int indentCurrent = IndentAmount(styler, lineCurrent, &spaceFlags);
-
- int state = initStyle & 31;
- char chPrev = ' ';
- char chPrev2 = ' ';
- char chNext = styler[startPos];
- char chNext2 = styler[startPos];
- int startSeg = startPos;
- int lengthDoc = startPos + length;
- bool atStartLine = true;
- for (int i = startPos; i <= lengthDoc; i++) {
-
- if (atStartLine) {
- if (whingeLevel == 1) {
- styler.SetFlags((spaceFlags & wsInconsistent) ? 64 : 0, state);
- } else if (whingeLevel == 2) {
- styler.SetFlags((spaceFlags & wsSpaceTab) ? 64 : 0, state);
- } else if (whingeLevel == 3) {
- styler.SetFlags((spaceFlags & wsSpace) ? 64 : 0, state);
- } else if (whingeLevel == 4) {
- styler.SetFlags((spaceFlags & wsTab) ? 64 : 0, state);
- }
- atStartLine = false;
- }
-
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- chNext2 = styler.SafeGetCharAt(i + 2);
-
- if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
- if ((state == SCE_P_DEFAULT) || (state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE)) {
- // Perform colourisation of white space and triple quoted strings at end of each line to allow
- // tab marking to work inside white space and triple quoted strings
- styler.ColourSegment(startSeg, i, state);
- startSeg = i + 1;
- }
-
- int lev = indentCurrent;
- int indentNext = IndentAmount(styler, lineCurrent + 1, &spaceFlags);
- if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
- // Only non whitespace lines can be headers
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- }
- }
- indentCurrent = indentNext;
- if (fold) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- atStartLine = true;
- }
-
- if (IsLeadByte(codePage, ch)) { // dbcs
- chNext = styler.SafeGetCharAt(i + 2);
- chPrev = ' ';
- chPrev2 = ' ';
- i += 1;
- continue;
- }
-
- if (state == SCE_P_DEFAULT) {
- if (iswordstart(ch)) {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_P_WORD;
- startSeg = i;
- } else if (ch == '#') {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_P_COMMENTLINE;
- startSeg = i;
- } else if (ch == '\"') {
- styler.ColourSegment(startSeg, i - 1, state);
- startSeg = i;
- if (chNext == '\"' && chNext2 == '\"') {
- i += 2;
- state = SCE_P_TRIPLEDOUBLE;
- ch = ' ';
- chPrev = ' ';
- chNext = styler.SafeGetCharAt(i + 1);
- } else {
- state = SCE_P_STRING;
- }
- } else if (ch == '\'') {
- styler.ColourSegment(startSeg, i - 1, state);
- startSeg = i;
- if (chNext == '\'' && chNext2 == '\'') {
- i += 2;
- state = SCE_P_TRIPLE;
- ch = ' ';
- chPrev = ' ';
- chNext = styler.SafeGetCharAt(i + 1);
- } else {
- state = SCE_P_CHARACTER;
- }
- } else if (isoperator(ch)) {
- styler.ColourSegment(startSeg, i - 1, state);
- styler.ColourSegment(i, i, SCE_P_OPERATOR);
- startSeg = i + 1;
- }
- } else if (state == SCE_P_WORD) {
- if (!iswordchar(ch)) {
- classifyWordPy(startSeg, i - 1, keywords, styler, prevWord);
- state = SCE_P_DEFAULT;
- startSeg = i;
- if (ch == '#') {
- state = SCE_P_COMMENTLINE;
- } else if (ch == '\"') {
- if (chNext == '\"' && chNext2 == '\"') {
- i += 2;
- state = SCE_P_TRIPLEDOUBLE;
- ch = ' ';
- chPrev = ' ';
- chNext = styler.SafeGetCharAt(i + 1);
- } else {
- state = SCE_P_STRING;
- }
- } else if (ch == '\'') {
- if (chNext == '\'' && chNext2 == '\'') {
- i += 2;
- state = SCE_P_TRIPLE;
- ch = ' ';
- chPrev = ' ';
- chNext = styler.SafeGetCharAt(i + 1);
- } else {
- state = SCE_P_CHARACTER;
- }
- } else if (isoperator(ch)) {
- styler.ColourSegment(startSeg, i, SCE_P_OPERATOR);
- startSeg = i + 1;
- }
- }
- } else {
- if (state == SCE_P_COMMENTLINE) {
- if (ch == '\r' || ch == '\n') {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_P_DEFAULT;
- startSeg = i;
- }
- } else if (state == SCE_P_STRING) {
- if (ch == '\\') {
- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- } else if (ch == '\"') {
- styler.ColourSegment(startSeg, i, state);
- state = SCE_P_DEFAULT;
- startSeg = i + 1;
- }
- } else if (state == SCE_P_CHARACTER) {
- if (ch == '\\') {
- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- } else if (ch == '\'') {
- styler.ColourSegment(startSeg, i, state);
- state = SCE_P_DEFAULT;
- startSeg = i + 1;
- }
- } else if (state == SCE_P_TRIPLE) {
- if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') {
- styler.ColourSegment(startSeg, i, state);
- state = SCE_P_DEFAULT;
- startSeg = i + 1;
- }
- } else if (state == SCE_P_TRIPLEDOUBLE) {
- if (ch == '\"' && chPrev == '\"' && chPrev2 == '\"') {
- styler.ColourSegment(startSeg, i, state);
- state = SCE_P_DEFAULT;
- startSeg = i + 1;
- }
- }
- }
- chPrev2 = chPrev;
- chPrev = ch;
- }
- if (startSeg <= lengthDoc) {
- if (state == SCE_P_DEFAULT) {
- styler.ColourSegment(startSeg, lengthDoc, state);
- } else if (state == SCE_P_WORD) {
- classifyWordPy(startSeg, lengthDoc, keywords, styler, prevWord);
- } else if (state == SCE_P_COMMENTLINE) {
- styler.ColourSegment(startSeg, lengthDoc, state);
- } else if (state == SCE_P_STRING) {
- styler.ColourSegment(startSeg, lengthDoc, state);
- } else if (state == SCE_P_CHARACTER) {
- styler.ColourSegment(startSeg, lengthDoc, state);
- } else if (state == SCE_P_TRIPLE) {
- styler.ColourSegment(startSeg, lengthDoc, state);
- } else if (state == SCE_P_TRIPLEDOUBLE) {
- styler.ColourSegment(startSeg, lengthDoc, state);
- }
- }
-}
-
-static void ColouriseBatchLine(char *lineBuffer, int lengthLine, StylingContext &styler) {
- if (0 == strncmp(lineBuffer, "REM", 3)) {
- styler.ColourSegment(0, lengthLine - 1, 1);
- } else if (0 == strncmp(lineBuffer, "rem", 3)) {
- styler.ColourSegment(0, lengthLine - 1, 1);
- } else if (0 == strncmp(lineBuffer, "SET", 3)) {
- styler.ColourSegment(0, lengthLine - 1, 2);
- } else if (0 == strncmp(lineBuffer, "set", 3)) {
- styler.ColourSegment(0, lengthLine - 1, 2);
- } else if (lineBuffer[0] == ':') {
- styler.ColourSegment(0, lengthLine - 1, 3);
- } else {
- styler.ColourSegment(0, lengthLine - 1, 0);
- }
-}
-
-static void ColouriseBatchDoc(int startPos, int length, int, StylingContext &styler) {
- char lineBuffer[1024];
- unsigned int linePos = 0;
- for (int i = startPos; i < startPos + length; i++) {
- lineBuffer[linePos++] = styler[i];
- if (styler[i] == '\r' || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) {
- ColouriseBatchLine(lineBuffer, linePos, styler);
- linePos = 0;
- }
- }
- if (linePos > 0)
- ColouriseBatchLine(lineBuffer, linePos, styler);
-}
-
-enum { eScriptNone, eScriptJS, eScriptVBS, eScriptPython };
-static int segIsScriptingIndicator(StylingContext &styler, unsigned int start, unsigned int end, int prevValue) {
- char s[100];
- s[0] = '\0';
- for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
- s[i] = tolower(styler[start + i]);
- s[i + 1] = '\0';
- }
-Platform::DebugPrintf("Scripting indicator [%s]\n", s);
- if (strstr(s, "vbs"))
- return eScriptVBS;
- if (strstr(s, "pyth"))
- return eScriptPython;
- if (strstr(s, "javas"))
- return eScriptJS;
- if (strstr(s, "jscr"))
- return eScriptJS;
-
- return prevValue;
-}
-
-static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) {
- bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.') ||
- (styler[start] == '-') || (styler[start] == '#');
- char chAttr = SCE_H_ATTRIBUTEUNKNOWN;
- if (wordIsNumber) {
- chAttr = SCE_H_NUMBER;
- } else {
- char s[100];
- s[0] = '\0';
- for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
- s[i] = tolower(styler[start + i]);
- s[i + 1] = '\0';
- }
- if (keywords.InList(s))
- chAttr = SCE_H_ATTRIBUTE;
- }
- styler.ColourTo(end, chAttr);
-}
-
-static int classifyTagHTML(unsigned int start, unsigned int end,
- WordList &keywords, StylingContext &styler) {
- char s[100];
- // Copy after the '<'
- unsigned int i = 0;
- for (int cPos=start; cPos <= end && i < 30; cPos++) {
- char ch = styler[cPos];
- if (ch != '<')
- s[i++] = tolower(ch);
- }
- s[i] = '\0';
- char chAttr = SCE_H_TAGUNKNOWN;
- if (s[0] == '!' && s[1] == '-' && s[2] == '-') { //Comment
- chAttr = SCE_H_COMMENT;
- } else if (s[0] == '/') { // Closing tag
- if (keywords.InList(s + 1))
- chAttr = SCE_H_TAG;
- } else {
- if (keywords.InList(s)) {
- chAttr = SCE_H_TAG;
- if (0 == strcmp(s, "script"))
- chAttr = SCE_H_SCRIPT;
- }
- }
- styler.ColourTo(end, chAttr);
- return chAttr;
-}
-
-static void classifyWordHTJS(unsigned int start, unsigned int end,
- WordList &keywords, StylingContext &styler) {
- char s[100];
- bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
- for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
- s[i] = styler[start + i];
- s[i + 1] = '\0';
- }
- char chAttr = SCE_HJ_WORD;
- if (wordIsNumber)
- chAttr = SCE_HJ_NUMBER;
- else {
- if (keywords.InList(s))
- chAttr = SCE_HJ_KEYWORD;
- }
- styler.ColourTo(end, chAttr);
-}
-
-static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) {
- char s[100];
- bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
- for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
- s[i] = tolower(styler[start + i]);
- s[i + 1] = '\0';
- }
- char chAttr = SCE_HB_IDENTIFIER;
- if (wordIsNumber)
- chAttr = SCE_HB_NUMBER;
- else {
- if (keywords.InList(s)) {
- chAttr = SCE_HB_WORD;
- if (strcmp(s, "rem") == 0)
- chAttr = SCE_HB_COMMENTLINE;
- }
- }
- styler.ColourTo(end, chAttr);
- if (chAttr == SCE_HB_COMMENTLINE)
- return SCE_HB_COMMENTLINE;
- else
- return SCE_HB_DEFAULT;
-}
+LexerModule *LexerModule::base = 0;
+int LexerModule::nextLanguage = SCLEX_AUTOMATIC+1;
-static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler, char *prevWord) {
- char s[100];
- bool wordIsNumber = isdigit(styler[start]);
- for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
- s[i] = styler[start + i];
- s[i + 1] = '\0';
+LexerModule::LexerModule(int language_, LexerFunction fnLexer_,
+ const char *languageName_, LexerFunction fnFolder_) :
+ language(language_),
+ languageName(languageName_),
+ fnLexer(fnLexer_),
+ fnFolder(fnFolder_) {
+ next = base;
+ base = this;
+ if (language == SCLEX_AUTOMATIC) {
+ language = nextLanguage;
+ nextLanguage++;
}
- char chAttr = SCE_HP_IDENTIFIER;
- if (0 == strcmp(prevWord, "class"))
- chAttr = SCE_HP_CLASSNAME;
- else if (0 == strcmp(prevWord, "def"))
- chAttr = SCE_HP_DEFNAME;
- else if (wordIsNumber)
- chAttr = SCE_HP_NUMBER;
- else if (keywords.InList(s))
- chAttr = SCE_HP_WORD;
- styler.ColourTo(end, chAttr);
- strcpy(prevWord, s);
-}
-
-inline bool ishtmlwordchar(char ch) {
- return isalnum(ch) || ch == '.' || ch == '-' || ch == '_' || ch == ':' || ch == '!' || ch == '#';
-}
-
-static bool InTagState(int state) {
- return state == SCE_H_TAG || state == SCE_H_TAGUNKNOWN ||
- state == SCE_H_SCRIPT ||
- state == SCE_H_ATTRIBUTE || state == SCE_H_ATTRIBUTEUNKNOWN ||
- state == SCE_H_NUMBER || state == SCE_H_OTHER ||
- state == SCE_H_DOUBLESTRING || state == SCE_H_SINGLESTRING;
}
-static bool isLineEnd(char ch) {
- return ch == '\r' || ch == '\n';
-}
-
-static void ColouriseHyperTextDoc(int codePage, int startPos, int length,
- int initStyle, WordList &keywords, WordList &keywords2, WordList &keywords3, WordList &keywords4,
- StylingContext &styler) {
-
- styler.StartAt(startPos, 63);
- bool lastTagWasScript = false;
- char prevWord[200];
- prevWord[0] = '\0';
- int scriptLanguage = eScriptJS;
- int state = initStyle;
- // If inside a tag, it may be a script tage, so reread from the start to ensure any language tas are seen
- if (InTagState(state)) {
- while ((startPos > 1) && (InTagState(styler.StyleAt(startPos - 1)))) {
- startPos--;
- }
- state = SCE_H_DEFAULT;
- }
- styler.StartAt(startPos, 63);
-
- int lineState = eScriptVBS;
- int lineCurrent = styler.GetLine(startPos);
- if (lineCurrent > 0)
- lineState = styler.GetLineState(lineCurrent);
- int defaultScript = lineState &0xff;
- int beforeASP = (lineState >> 8) &0xff;
- int inASP = (lineState >> 16) &0xff;
-
- char chPrev = ' ';
- char chPrev2 = ' ';
- styler.StartSegment(startPos);
- int lengthDoc = startPos + length;
- for (int i = startPos; i <= lengthDoc; i++) {
- char ch = styler[i];
- char chNext = styler.SafeGetCharAt(i + 1);
- char chNext2 = styler.SafeGetCharAt(i + 2);
-
- if (IsLeadByte(codePage, ch)) { // dbcs
- chPrev2 = ' ';
- chPrev = ' ';
- i += 1;
- continue;
- }
-
- if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
- // New line -> record any line state onto /next/ line
- lineCurrent++;
- styler.SetLineState(lineCurrent,
- defaultScript | (beforeASP << 8) | (inASP << 16));
- }
-
- // Handle ASP even within other constructs as it is a preprocessor
- if ((ch == '<') && (chNext == '%')) {
- beforeASP = state;
- styler.ColourTo(i - 1, state);
- if (chNext2 == '@') {
- styler.ColourTo(i + 2, SCE_H_ASP);
- state = SCE_H_ASPAT;
- i+=2;
- } else {
- if (defaultScript == eScriptVBS)
- state = SCE_HB_START;
- else if (defaultScript == eScriptPython)
- state = SCE_HP_START;
- else
- state = SCE_HJ_START;
- if (chNext2 == '=') {
- styler.ColourTo(i + 2, SCE_H_ASP);
- i+=2;
- } else {
- styler.ColourTo(i + 1, SCE_H_ASP);
- i++;
- }
- }
- inASP = 1;
- continue;
- }
- if (inASP && (ch == '%') && (chNext == '>')) {
- if (state == SCE_H_ASPAT)
- defaultScript = segIsScriptingIndicator(styler, styler.GetStartSegment(), i-1, defaultScript);
- // Bounce out of any ASP mode
- styler.ColourTo(i - 1, state);
- //if (state == SCE_H_ASPAT)
- // styler.ColourTo(i+1, SCE_H_ASPAT);
- //else
- styler.ColourTo(i+1, SCE_H_ASP);
- i++;
- state = beforeASP;
- beforeASP = SCE_H_DEFAULT;
- inASP = 0;
- continue;
- }
-
- if (state == SCE_H_DEFAULT) {
- if (ch == '<') {
- styler.ColourTo(i - 1, state);
- state = SCE_H_TAGUNKNOWN;
- if (chNext == '?') {
- styler.ColourTo(i + 1, SCE_H_XMLSTART);
- i++;
- ch = chNext;
- }
- } else if (ch == '&') {
- styler.ColourTo(i - 1, SCE_H_DEFAULT);
- state = SCE_H_ENTITY;
- }
- } else if (state == SCE_H_COMMENT) {
- if ((ch == '>') && (chPrev == '-')) {
- styler.ColourTo(i, state);
- state = SCE_H_DEFAULT;
- }
- } else if (state == SCE_H_ENTITY) {
- if (ch == ';') {
- styler.ColourTo(i, state);
- state = SCE_H_DEFAULT;
- }
- } else if (state == SCE_H_TAGUNKNOWN) {
- if (!ishtmlwordchar(ch) && ch != '/' && ch != '-') {
- int eClass = classifyTagHTML(styler.GetStartSegment(), i - 1, keywords, styler);
- lastTagWasScript = eClass == SCE_H_SCRIPT;
- if (lastTagWasScript) {
- scriptLanguage = eScriptJS;
- eClass = SCE_H_TAG;
- }
- if (ch == '>') {
- styler.ColourTo(i, SCE_H_TAG);
- if (lastTagWasScript) {
- if (scriptLanguage == eScriptVBS)
- state = SCE_HB_START;
- else if (scriptLanguage == eScriptPython)
- state = SCE_HP_START;
- else
- state = SCE_HJ_START;
- } else {
- state = SCE_H_DEFAULT;
- }
- } else {
- if (eClass == SCE_H_COMMENT) {
- state = SCE_H_COMMENT;
- } else {
- state = SCE_H_OTHER;
- }
- }
- }
- } else if (state == SCE_H_ATTRIBUTE) {
- if (!ishtmlwordchar(ch) && ch != '/' && ch != '-') {
- if (lastTagWasScript)
- scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i-1, scriptLanguage);
- classifyAttribHTML(styler.GetStartSegment(), i - 1, keywords, styler);
- if (ch == '>') {
- styler.ColourTo(i, SCE_H_TAG);
- if (lastTagWasScript) {
- if (scriptLanguage == eScriptVBS)
- state = SCE_HB_START;
- else if (scriptLanguage == eScriptPython)
- state = SCE_HP_START;
- else
- state = SCE_HJ_START;
- } else {
- state = SCE_H_DEFAULT;
- }
- } else {
- state = SCE_H_OTHER;
- }
- }
- } else if (state == SCE_H_ASP) {
- if ((ch == '>') && (chPrev == '%')) {
- styler.ColourTo(i, state);
- state = SCE_H_DEFAULT;
- }
- } else if (state == SCE_H_ASPAT) {
- if ((ch == '>') && (chPrev == '%')) {
- styler.ColourTo(i, state);
- state = SCE_H_DEFAULT;
- }
- } else if (state == SCE_H_OTHER) {
- if (ch == '>') {
- styler.ColourTo(i - 1, state);
- styler.ColourTo(i, SCE_H_TAG);
- if (lastTagWasScript) {
- if (scriptLanguage == eScriptVBS)
- state = SCE_HB_START;
- else if (scriptLanguage == eScriptPython)
- state = SCE_HP_START;
- else
- state = SCE_HJ_START;
- } else {
- state = SCE_H_DEFAULT;
- }
- } else if (ch == '\"') {
- styler.ColourTo(i - 1, state);
- state = SCE_H_DOUBLESTRING;
- } else if (ch == '\'') {
- styler.ColourTo(i - 1, state);
- state = SCE_H_SINGLESTRING;
- } else if (ch == '/' && chNext == '>') {
- styler.ColourTo(i - 1, state);
- styler.ColourTo(i + 1, SCE_H_TAGEND);
- i++;
- ch = chNext;
- state = SCE_H_DEFAULT;
- } else if (ch == '?' && chNext == '>') {
- styler.ColourTo(i - 1, state);
- styler.ColourTo(i + 1, SCE_H_XMLEND);
- i++;
- ch = chNext;
- state = SCE_H_DEFAULT;
- } else if (ishtmlwordchar(ch)) {
- styler.ColourTo(i - 1, state);
- state = SCE_H_ATTRIBUTE;
- }
- } else if (state == SCE_H_DOUBLESTRING) {
- if (ch == '\"') {
- if (lastTagWasScript)
- scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage);
- styler.ColourTo(i, SCE_H_DOUBLESTRING);
- state = SCE_H_OTHER;
- }
- } else if (state == SCE_H_SINGLESTRING) {
- if (ch == '\'') {
- if (lastTagWasScript)
- scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage);
- styler.ColourTo(i, SCE_H_SINGLESTRING);
- state = SCE_H_OTHER;
- }
- } else if (state == SCE_HJ_DEFAULT || state == SCE_HJ_START) {
- if (iswordstart(ch)) {
- styler.ColourTo(i - 1, state);
- state = SCE_HJ_WORD;
- } else if (ch == '/' && chNext == '*') {
- styler.ColourTo(i - 1, state);
- if (chNext2 == '*')
- state = SCE_HJ_COMMENTDOC;
- else
- state = SCE_HJ_COMMENT;
- } else if (ch == '/' && chNext == '/') {
- styler.ColourTo(i - 1, state);
- state = SCE_HJ_COMMENTLINE;
- } else if (ch == '\"') {
- styler.ColourTo(i - 1, state);
- state = SCE_HJ_DOUBLESTRING;
- } else if (ch == '\'') {
- styler.ColourTo(i - 1, state);
- state = SCE_HJ_SINGLESTRING;
- } else if ((ch == '<') && (chNext == '/')) {
- styler.ColourTo(i - 1, state);
- state = SCE_H_TAGUNKNOWN;
- } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') &&
- styler.SafeGetCharAt(i + 3) == '-') {
- styler.ColourTo(i - 1, state);
- state = SCE_HJ_COMMENTLINE;
- } else if (isoperator(ch)) {
- styler.ColourTo(i - 1, state);
- styler.ColourTo(i, SCE_HJ_SYMBOLS);
- state = SCE_HJ_DEFAULT;
- } else if ((ch == ' ') || (ch == '\t')) {
- if (state == SCE_HJ_START) {
- styler.ColourTo(i - 1, state);
- state = SCE_HJ_DEFAULT;
- }
- }
- } else if (state == SCE_HJ_WORD) {
- if (!iswordchar(ch)) {
- classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler);
- //styler.ColourTo(i - 1, eHTJSKeyword);
- state = SCE_HJ_DEFAULT;
- if (ch == '/' && chNext == '*') {
- if (chNext2 == '*')
- state = SCE_HJ_COMMENTDOC;
- else
- state = SCE_HJ_COMMENT;
- } else if (ch == '/' && chNext == '/') {
- state = SCE_HJ_COMMENTLINE;
- } else if (ch == '\"') {
- state = SCE_HJ_DOUBLESTRING;
- } else if (ch == '\'') {
- state = SCE_HJ_SINGLESTRING;
- } else if (isoperator(ch)) {
- styler.ColourTo(i, SCE_HJ_SYMBOLS);
- state = SCE_HJ_DEFAULT;
- }
- }
- } else if (state == SCE_HJ_COMMENT) {
- if (ch == '/' && chPrev == '*') {
- state = SCE_HJ_DEFAULT;
- styler.ColourTo(i, SCE_HJ_COMMENT);
- } else if ((ch == '<') && (chNext == '/')) {
- styler.ColourTo(i - 1, state);
- styler.ColourTo(i + 1, SCE_H_TAGEND);
- i++;
- ch = chNext;
- state = SCE_H_DEFAULT;
- }
- } else if (state == SCE_HJ_COMMENTDOC) {
- if (ch == '/' && chPrev == '*') {
- state = SCE_HJ_DEFAULT;
- styler.ColourTo(i, SCE_HJ_COMMENTDOC);
- } else if ((ch == '<') && (chNext == '/')) {
- styler.ColourTo(i - 1, state);
- styler.ColourTo(i + 1, SCE_H_TAGEND);
- i++;
- ch = chNext;
- state = SCE_H_DEFAULT;
- }
- } else if (state == SCE_HJ_COMMENTLINE) {
- if (ch == '\r' || ch == '\n') {
- styler.ColourTo(i - 1, SCE_HJ_COMMENTLINE);
- state = SCE_HJ_DEFAULT;
- } else if ((ch == '<') && (chNext == '/')) {
- // Common to hide end script tag in comment
- styler.ColourTo(i - 1, SCE_HJ_COMMENTLINE);
- state = SCE_H_TAGUNKNOWN;
- }
- } else if (state == SCE_HJ_DOUBLESTRING) {
- if (ch == '\\') {
- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
- i++;
- }
- } else if (ch == '\"') {
- styler.ColourTo(i, SCE_HJ_DOUBLESTRING);
- state = SCE_HJ_DEFAULT;
- i++;
- ch = chNext;
- } else if (isLineEnd(ch)) {
- styler.ColourTo(i-1, state);
- state = SCE_HJ_STRINGEOL;
- }
- } else if (state == SCE_HJ_SINGLESTRING) {
- if (ch == '\\') {
- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
- i++;
- }
- } else if (ch == '\'') {
- styler.ColourTo(i, SCE_HJ_SINGLESTRING);
- state = SCE_HJ_DEFAULT;
- i++;
- ch = chNext;
- } else if (isLineEnd(ch)) {
- styler.ColourTo(i-1, state);
- state = SCE_HJ_STRINGEOL;
- }
- } else if (state == SCE_HJ_STRINGEOL) {
- if (!isLineEnd(ch)) {
- styler.ColourTo(i - 1, state);
- state = SCE_HJ_DEFAULT;
- }
- } else if (state == SCE_HB_DEFAULT || state == SCE_HB_START) {
- if (iswordstart(ch)) {
- styler.ColourTo(i - 1, state);
- state = SCE_HB_WORD;
- } else if (ch == '\'') {
- styler.ColourTo(i - 1, state);
- state = SCE_HB_COMMENTLINE;
- } else if (ch == '\"') {
- styler.ColourTo(i - 1, state);
- state = SCE_HB_STRING;
- } else if ((ch == '<') && (chNext == '/')) {
- styler.ColourTo(i - 1, state);
- state = SCE_H_TAGUNKNOWN;
- } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') &&
- styler.SafeGetCharAt(i + 3) == '-') {
- styler.ColourTo(i - 1, state);
- state = SCE_HB_COMMENTLINE;
- } else if (isoperator(ch)) {
- styler.ColourTo(i - 1, state);
- styler.ColourTo(i, SCE_HB_DEFAULT);
- state = SCE_HB_DEFAULT;
- } else if ((ch == ' ') || (ch == '\t')) {
- if (state == SCE_HB_START) {
- styler.ColourTo(i - 1, state);
- state = SCE_HB_DEFAULT;
- }
- }
- } else if (state == SCE_HB_WORD) {
- if (!iswordchar(ch)) {
- state = classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler);
- if (state == SCE_HB_DEFAULT) {
- if (ch == '\"') {
- state = SCE_HB_STRING;
- } else if (ch == '\'') {
- state = SCE_HB_COMMENTLINE;
- } else if (isoperator(ch)) {
- styler.ColourTo(i, SCE_HB_DEFAULT);
- state = SCE_HB_DEFAULT;
- }
- }
- }
- } else if (state == SCE_HB_STRING) {
- if (ch == '\"') {
- styler.ColourTo(i, state);
- state = SCE_HB_DEFAULT;
- i++;
- ch = chNext;
- } else if (ch == '\r' || ch == '\n') {
- styler.ColourTo(i-1, state);
- state = SCE_HB_STRINGEOL;
- }
- } else if (state == SCE_HB_COMMENTLINE) {
- if (ch == '\r' || ch == '\n') {
- styler.ColourTo(i - 1, state);
- state = SCE_HB_DEFAULT;
- } else if ((ch == '<') && (chNext == '/')) {
- // Common to hide end script tag in comment
- styler.ColourTo(i - 1, state);
- state = SCE_H_TAGUNKNOWN;
- }
- } else if (state == SCE_HB_STRINGEOL) {
- if (!isLineEnd(ch)) {
- styler.ColourTo(i - 1, state);
- state = SCE_HB_DEFAULT;
- }
- } else if (state == SCE_HP_DEFAULT || state == SCE_HP_START) {
- if (iswordstart(ch)) {
- styler.ColourTo(i - 1, state);
- state = SCE_HP_WORD;
- } else if ((ch == '<') && (chNext == '/')) {
- styler.ColourTo(i - 1, state);
- state = SCE_H_TAGUNKNOWN;
- } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') &&
- styler.SafeGetCharAt(i + 3) == '-') {
- styler.ColourTo(i - 1, state);
- state = SCE_HP_COMMENTLINE;
- } else if (ch == '#') {
- styler.ColourTo(i - 1, state);
- state = SCE_HP_COMMENTLINE;
- } else if (ch == '\"') {
- styler.ColourTo(i - 1, state);
- if (chNext == '\"' && chNext2 == '\"') {
- i += 2;
- state = SCE_HP_TRIPLEDOUBLE;
- ch = ' ';
- chPrev = ' ';
- chNext = styler.SafeGetCharAt(i + 1);
- } else {
- state = SCE_HP_STRING;
- }
- } else if (ch == '\'') {
- styler.ColourTo(i - 1, state);
- if (chNext == '\'' && chNext2 == '\'') {
- i += 2;
- state = SCE_HP_TRIPLE;
- ch = ' ';
- chPrev = ' ';
- chNext = styler.SafeGetCharAt(i + 1);
- } else {
- state = SCE_HP_CHARACTER;
- }
- } else if (isoperator(ch)) {
- styler.ColourTo(i - 1, state);
- styler.ColourTo(i, SCE_HP_OPERATOR);
- } else if ((ch == ' ') || (ch == '\t')) {
- if (state == SCE_HP_START) {
- styler.ColourTo(i - 1, state);
- state = SCE_HP_DEFAULT;
- }
- }
- } else if (state == SCE_HP_WORD) {
- if (!iswordchar(ch)) {
- classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord);
- state = SCE_HP_DEFAULT;
- if (ch == '#') {
- state = SCE_HP_COMMENTLINE;
- } else if (ch == '\"') {
- if (chNext == '\"' && chNext2 == '\"') {
- i += 2;
- state = SCE_HP_TRIPLEDOUBLE;
- ch = ' ';
- chPrev = ' ';
- chNext = styler.SafeGetCharAt(i + 1);
- } else {
- state = SCE_HP_STRING;
- }
- } else if (ch == '\'') {
- if (chNext == '\'' && chNext2 == '\'') {
- i += 2;
- state = SCE_HP_TRIPLE;
- ch = ' ';
- chPrev = ' ';
- chNext = styler.SafeGetCharAt(i + 1);
- } else {
- state = SCE_HP_CHARACTER;
- }
- } else if (isoperator(ch)) {
- styler.ColourTo(i, SCE_HP_OPERATOR);
- }
- }
- } else {
- if (state == SCE_HP_COMMENTLINE) {
- if (ch == '\r' || ch == '\n') {
- styler.ColourTo(i - 1, state);
- state = SCE_HP_DEFAULT;
- }
- } else if (state == SCE_HP_STRING) {
- if (ch == '\\') {
- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- } else if (ch == '\"') {
- styler.ColourTo(i, state);
- state = SCE_HP_DEFAULT;
- }
- } else if (state == SCE_HP_CHARACTER) {
- if (ch == '\\') {
- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- } else if (ch == '\'') {
- styler.ColourTo(i, state);
- state = SCE_HP_DEFAULT;
- }
- } else if (state == SCE_HP_TRIPLE) {
- if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') {
- styler.ColourTo(i, state);
- state = SCE_HP_DEFAULT;
- }
- } else if (state == SCE_HP_TRIPLEDOUBLE) {
- if (ch == '\"' && chPrev == '\"' && chPrev2 == '\"') {
- styler.ColourTo(i, state);
- state = SCE_HP_DEFAULT;
- }
- }
- }
- if (state == SCE_HB_DEFAULT) { // One of the above succeeded
- if (ch == '\"') {
- state = SCE_HB_STRING;
- } else if (ch == '\'') {
- state = SCE_HB_COMMENTLINE;
- } else if (iswordstart(ch)) {
- state = SCE_HB_WORD;
- } else if (isoperator(ch)) {
- styler.ColourTo(i, SCE_HB_DEFAULT);
- }
- }
- if (state == SCE_HJ_DEFAULT) { // One of the above succeeded
- if (ch == '/' && chNext == '*') {
- if (styler.SafeGetCharAt(i + 2) == '*')
- state = SCE_HJ_COMMENTDOC;
- else
- state = SCE_HJ_COMMENT;
- } else if (ch == '/' && chNext == '/') {
- state = SCE_HJ_COMMENTLINE;
- } else if (ch == '\"') {
- state = SCE_HJ_DOUBLESTRING;
- } else if (ch == '\'') {
- state = SCE_HJ_SINGLESTRING;
- } else if (iswordstart(ch)) {
- state = SCE_HJ_WORD;
- } else if (isoperator(ch)) {
- styler.ColourTo(i, SCE_HJ_SYMBOLS);
- }
- }
- chPrev2 = chPrev;
- chPrev = ch;
- }
- styler.ColourTo(lengthDoc - 1, state);
-}
-
-static void ColourisePropsLine(char *lineBuffer, int lengthLine, StylingContext &styler) {
- int i = 0;
- while (isspace(lineBuffer[i]) && (i < lengthLine)) // Skip initial spaces
- i++;
- if (lineBuffer[i] == '#' || lineBuffer[i] == '!' || lineBuffer[i] == ';') {
- styler.ColourSegment(0, lengthLine - 1, 1);
- } else if (lineBuffer[i] == '[') {
- styler.ColourSegment(0, lengthLine - 1, 2);
- } else if (lineBuffer[i] == '@') {
- styler.ColourSegment(0, i, 4);
- if (lineBuffer[++i] == '=')
- styler.ColourSegment(i, i, 3);
- if (++i < lengthLine)
- styler.ColourSegment(i, lengthLine - 1, 0);
- } else {
- while (lineBuffer[i] != '=' && (i < lengthLine)) // Search the '=' character
- i++;
- if (lineBuffer[i] == '=') {
- styler.ColourSegment(0, i - 1, 0);
- styler.ColourSegment(i, i, 3);
- if (++i < lengthLine)
- styler.ColourSegment(i, lengthLine - 1, 0);
- } else
- styler.ColourSegment(0, lengthLine - 1, 0);
- }
-}
-
-static void ColourisePropsDoc(int startPos, int length, int, StylingContext &styler) {
- char lineBuffer[1024];
- unsigned int linePos = 0;
- for (int i = startPos; i <= startPos + length; i++) {
- lineBuffer[linePos++] = styler[i];
- if (styler[i] == '\r' || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) {
- lineBuffer[linePos] = '\0';
- ColourisePropsLine(lineBuffer, linePos, styler);
- linePos = 0;
- }
- }
- if (linePos > 0)
- ColourisePropsLine(lineBuffer, linePos, styler);
-}
-
-static void ColouriseMakeLine(char *lineBuffer, int lengthLine, StylingContext &styler) {
- int i = 0;
- while (isspace(lineBuffer[i]) && (i < lengthLine))
- i++;
- if (lineBuffer[i] == '#' || lineBuffer[i] == '!') {
- styler.ColourSegment(0, lengthLine - 1, 1);
- } else {
- styler.ColourSegment(0, lengthLine - 1, 0);
- }
-}
-
-static void ColouriseMakeDoc(int startPos, int length, int, StylingContext &styler) {
- char lineBuffer[1024];
- unsigned int linePos = 0;
- for (int i = startPos; i <= startPos + length; i++) {
- lineBuffer[linePos++] = styler[i];
- if (styler[i] == '\r' || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) {
- ColouriseMakeLine(lineBuffer, linePos, styler);
- linePos = 0;
- }
- }
- if (linePos > 0)
- ColouriseMakeLine(lineBuffer, linePos, styler);
-}
-
-static void ColouriseErrorListLine(char *lineBuffer, int lengthLine, StylingContext &styler) {
- if (lineBuffer[0] == '>') {
- // Command or return status
- styler.ColourSegment(0, lengthLine - 1, 4);
- } else if (strstr(lineBuffer, "File \"") && strstr(lineBuffer, ", line ")) {
- styler.ColourSegment(0, lengthLine - 1, 1);
- } else if (0 == strncmp(lineBuffer, "Error ", strlen("Error "))) {
- // Borland error message
- styler.ColourSegment(0, lengthLine - 1, 5);
- } else if (0 == strncmp(lineBuffer, "Warning ", strlen("Warning "))) {
- // Borland warning message
- styler.ColourSegment(0, lengthLine - 1, 5);
- } else {
- // Look for <filename>:<line>:message
- // Look for <filename>(line)message
- // Look for <filename>(line,pos)message
- int state = 0;
- for (int i = 0; i < lengthLine; i++) {
- if (state == 0 && lineBuffer[i] == ':' && isdigit(lineBuffer[i + 1])) {
- state = 1;
- } else if (state == 0 && lineBuffer[i] == '(') {
- state = 10;
- } else if (state == 1 && isdigit(lineBuffer[i])) {
- state = 2;
- } else if (state == 2 && lineBuffer[i] == ':') {
- state = 3;
- break;
- } else if (state == 2 && !isdigit(lineBuffer[i])) {
- state = 99;
- } else if (state == 10 && isdigit(lineBuffer[i])) {
- state = 11;
- } else if (state == 11 && lineBuffer[i] == ',') {
- state = 14;
- } else if (state == 11 && lineBuffer[i] == ')') {
- state = 12;
- break;
- } else if (state == 12 && lineBuffer[i] == ':') {
- state = 13;
- } else if (state == 14 && lineBuffer[i] == ')') {
- state = 15;
- break;
- } else if (((state == 11) || (state == 14)) && !((lineBuffer[i] == ' ') || isdigit(lineBuffer[i]))) {
- state = 99;
- }
- }
- if (state == 3) {
- styler.ColourSegment(0, lengthLine - 1, 2);
- } else if ((state == 14) || (state == 15)) {
- styler.ColourSegment(0, lengthLine - 1, 3);
- } else {
- styler.ColourSegment(0, lengthLine - 1, 0);
- }
- }
-}
-
-static void ColouriseErrorListDoc(int startPos, int length, int, StylingContext &styler) {
- char lineBuffer[1024];
- unsigned int linePos = 0;
- for (int i = startPos; i <= startPos + length; i++) {
- lineBuffer[linePos++] = styler[i];
- if (styler[i] == '\r' || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) {
- ColouriseErrorListLine(lineBuffer, linePos, styler);
- linePos = 0;
- }
- }
- if (linePos > 0)
- ColouriseErrorListLine(lineBuffer, linePos, styler);
-}
-
-static void classifyWordSQL(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) {
- char s[100];
- bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
- for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
- s[i] = toupper(styler[start + i]);
- s[i + 1] = '\0';
- }
- char chAttr = SCE_C_IDENTIFIER;
- if (wordIsNumber)
- chAttr = SCE_C_NUMBER;
- else {
- if (keywords.InList(s))
- chAttr = SCE_C_WORD;
- }
- styler.ColourSegment(start, end, chAttr);
-}
-
-static void ColouriseSQLDoc(int codePage, int startPos, int length,
- int initStyle, WordList &keywords, StylingContext &styler) {
-
- bool fold = styler.GetPropSet().GetInt("fold");
- int lineCurrent = styler.GetLine(startPos);
- int spaceFlags = 0;
- int indentCurrent = 0;
-
- int state = initStyle;
- char chPrev = ' ';
- char chNext = styler[startPos];
- int startSeg = startPos;
- int lengthDoc = startPos + length;
- bool prevCr = false;
- for (int i = startPos; i <= lengthDoc; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
-
- if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
- indentCurrent = IndentAmount(styler, lineCurrent, &spaceFlags);
- int lev = indentCurrent;
- if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
- // Only non whitespace lines can be headers
- int indentNext = IndentAmount(styler, lineCurrent + 1, &spaceFlags);
- if (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- }
- }
- if (fold) {
- styler.SetLevel(lineCurrent, lev);
- }
- }
-
- if (IsLeadByte(codePage, ch)) { // dbcs
- chNext = styler.SafeGetCharAt(i + 2);
- chPrev = ' ';
- i += 1;
- continue;
- }
-
- if (state == SCE_C_DEFAULT) {
- if (iswordstart(ch)) {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_C_WORD;
- startSeg = i;
- } else if (ch == '/' && chNext == '*') {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_C_COMMENT;
- startSeg = i;
- } else if (ch == '-' && chNext == '-') {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_C_COMMENTLINE;
- startSeg = i;
- } else if (ch == '\'') {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_C_STRING;
- startSeg = i;
- } else if (isoperator(ch)) {
- styler.ColourSegment(startSeg, i - 1, state);
- styler.ColourSegment(i, i, SCE_C_OPERATOR);
- startSeg = i + 1;
- }
- } else if (state == SCE_C_WORD) {
- if (!iswordchar(ch)) {
- classifyWordSQL(startSeg, i - 1, keywords, styler);
- state = SCE_C_DEFAULT;
- startSeg = i;
- if (ch == '/' && chNext == '*') {
- state = SCE_C_COMMENT;
- } else if (ch == '-' && chNext == '-') {
- state = SCE_C_COMMENTLINE;
- } else if (ch == '\'') {
- state = SCE_C_STRING;
- } else if (isoperator(ch)) {
- styler.ColourSegment(startSeg, i, SCE_C_OPERATOR);
- startSeg = i + 1;
- }
- }
- } else {
- if (state == SCE_C_COMMENT) {
- if (ch == '/' && chPrev == '*' && (
- (i > startSeg + 2) || ((initStyle == SCE_C_COMMENT) && (startSeg == startPos)))) {
- state = SCE_C_DEFAULT;
- styler.ColourSegment(startSeg, i, state);
- startSeg = i + 1;
- }
- } else if (state == SCE_C_COMMENTLINE) {
- if (ch == '\r' || ch == '\n') {
- styler.ColourSegment(startSeg, i - 1, state);
- state = SCE_C_DEFAULT;
- startSeg = i;
- }
- } else if (state == SCE_C_STRING) {
- if (ch == '\'') {
- if ( chNext == '\'' ) {
- i++;
- } else {
- styler.ColourSegment(startSeg, i, state);
- state = SCE_C_DEFAULT;
- i++;
- startSeg = i;
- }
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- }
- if (state == SCE_C_DEFAULT) { // One of the above succeeded
- if (ch == '/' && chNext == '*') {
- state = SCE_C_COMMENT;
- } else if (ch == '-' && chNext == '-') {
- state = SCE_C_COMMENTLINE;
- } else if (ch == '\'') {
- state = SCE_C_STRING;
- } else if (iswordstart(ch)) {
- state = SCE_C_WORD;
- } else if (isoperator(ch)) {
- styler.ColourSegment(startSeg, i, SCE_C_OPERATOR);
- startSeg = i + 1;
- }
- }
- }
- chPrev = ch;
- }
- if (startSeg < lengthDoc)
- styler.ColourSegment(startSeg, lengthDoc - 1, state);
-}
-
-void ColouriseDoc(int codePage, int startPos, int lengthDoc, int initStyle,
- int language, WordList *keywordlists[], StylingContext &styler) {
- //Platform::DebugPrintf("ColouriseDoc <%s>\n", language);
- if (language == SCLEX_PYTHON) {
- // Python uses a different mask because bad indentation is marked by oring with 32
- styler.StartAt(startPos, 127);
- ColourisePyDoc(codePage, startPos, lengthDoc, initStyle, *keywordlists[0], styler);
- } else if (language == SCLEX_PERL) {
- // Lexer for perl often has to backtrack to start of current style to determine
- // which characters are being used as quotes, how deeply nested is the
- // start position and what the termination string is for here documents
- ColourisePerlDoc(codePage, startPos, lengthDoc, initStyle, *keywordlists[0], styler);
- } else if ((language == SCLEX_HTML) || (language == SCLEX_XML)) {
- // Lexer for HTML requires more lexical states (6 bits worth) than most lexers
- ColouriseHyperTextDoc(codePage, startPos, lengthDoc, initStyle,
- *keywordlists[0], *keywordlists[1], *keywordlists[2], *keywordlists[3], styler);
- } else {
- styler.StartAt(startPos);
- if (language == SCLEX_CPP) {
- ColouriseCppDoc(codePage, startPos, lengthDoc, initStyle, *keywordlists[0], styler);
- } else if (language == SCLEX_SQL) {
- ColouriseSQLDoc(codePage, startPos, lengthDoc, initStyle, *keywordlists[0], styler);
- } else if (language == SCLEX_VB) {
- ColouriseVBDoc(codePage, startPos, lengthDoc, initStyle, *keywordlists[0], styler);
- } else if (language == SCLEX_PROPERTIES) {
- ColourisePropsDoc(startPos, lengthDoc, initStyle, styler);
- } else if (language == SCLEX_ERRORLIST) {
- ColouriseErrorListDoc(startPos, lengthDoc, initStyle, styler);
- } else if (language == SCLEX_MAKEFILE) {
- ColouriseMakeDoc(startPos, lengthDoc, initStyle, styler);
- } else if (language == SCLEX_BATCH) {
- ColouriseBatchDoc(startPos, lengthDoc, initStyle, styler);
- } else {
- // Null language means all style bytes are 0 so just mark the end - no need to fill in.
- styler.StartAt(startPos + lengthDoc - 1);
- styler.ColourSegment(0, 0, 0);
- }
- }
-}
+LexerModule *LexerModule::Find(int language) {
+ LexerModule *lm = base;
+ while (lm) {
+ if (lm->language == language) {
+ return lm;
+ }
+ lm = lm->next;
+ }
+ return 0;
+}
+
+LexerModule *LexerModule::Find(const char *languageName) {
+ if (languageName) {
+ LexerModule *lm = base;
+ while (lm) {
+ if (lm->languageName && 0 == strcmp(lm->languageName, languageName)) {
+ return lm;
+ }
+ lm = lm->next;
+ }
+ }
+ return 0;
+}
+
+void LexerModule::Lex(unsigned int startPos, int lengthDoc, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+ if (fnLexer)
+ fnLexer(startPos, lengthDoc, initStyle, keywordlists, styler);
+}
+
+void LexerModule::Fold(unsigned int startPos, int lengthDoc, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+ if (fnFolder) {
+ int lineCurrent = styler.GetLine(startPos);
+ // Move back one line in case deletion wrecked current line fold state
+ if (lineCurrent > 0) {
+ lineCurrent--;
+ int newStartPos = styler.LineStart(lineCurrent);
+ lengthDoc += startPos - newStartPos;
+ startPos = newStartPos;
+ initStyle = 0;
+ if (startPos > 0) {
+ initStyle = styler.StyleAt(startPos - 1);
+ }
+ }
+ fnFolder(startPos, lengthDoc, initStyle, keywordlists, styler);
+ }
+}
+
+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 lmNull(SCLEX_NULL, ColouriseNullDoc, "null");
+
+#ifdef __vms
+
+// The following code forces a reference to all of the Scintilla lexers.
+// If we don't do something like this, then the linker tends to "optimize"
+// them away. (eric@sourcegear.com)
+
+// Taken from wxWindow's stc.cpp. Walter.
+
+int wxForceScintillaLexers(void) {
+ extern LexerModule lmAda;
+ extern LexerModule lmAVE;
+ extern LexerModule lmBatch;
+ extern LexerModule lmConf;
+ extern LexerModule lmCPP;
+ extern LexerModule lmDiff;
+ extern LexerModule lmEiffel;
+ extern LexerModule lmEiffelkw;
+ extern LexerModule lmErrorList;
+ extern LexerModule lmHTML;
+ extern LexerModule lmLatex;
+ extern LexerModule lmLISP;
+ extern LexerModule lmLua;
+ extern LexerModule lmMake;
+ extern LexerModule lmPascal;
+ extern LexerModule lmPerl;
+ extern LexerModule lmProps;
+ extern LexerModule lmPython;
+ extern LexerModule lmRuby;
+ extern LexerModule lmSQL;
+ extern LexerModule lmVB;
+ extern LexerModule lmXML;
+
+ if (
+ &lmAda
+ && &lmAVE
+ && &lmConf
+ && &lmDiff
+ && &lmLatex
+ && &lmPascal
+ && &lmCPP
+ && &lmHTML
+ && &lmXML
+ && &lmProps
+ && &lmErrorList
+ && &lmMake
+ && &lmBatch
+ && &lmPerl
+ && &lmPython
+ && &lmSQL
+ && &lmVB
+ && &lmRuby
+ && &lmEiffel
+ && &lmEiffelkw
+ && &lmLISP
+ && &lmLua
+ && &lmNull
+ )
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+#endif