// // ColouriseDocument // static void ColouriseDocument( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; StyleContext sc(startPos, length, initStyle, styler); int lineCurrent = styler.GetLine(startPos); bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0; while (sc.More()) { if (sc.atLineEnd) { // Go to the next line sc.Forward(); lineCurrent++; // Remember the line state for future incremental lexing styler.SetLineState(lineCurrent, apostropheStartsAttribute); // Don't continue any styles on the next line sc.SetState(SCE_SPICE_DEFAULT); } // Comments if ((sc.Match('*') && sc.atLineStart) || sc.Match('*','~')) { ColouriseComment(sc, apostropheStartsAttribute); // Whitespace } else if (IsASpace(sc.ch)) { ColouriseWhiteSpace(sc, apostropheStartsAttribute); // Delimiters } else if (IsDelimiterCharacter(sc.ch)) { ColouriseDelimiter(sc, apostropheStartsAttribute); // Numbers } else if (IsADigit(sc.ch) || sc.ch == '#') { ColouriseNumber(sc, apostropheStartsAttribute); // Keywords or identifiers } else { ColouriseWord(sc, keywords, keywords2, keywords3, apostropheStartsAttribute); } } sc.Complete(); }
static void ColouriseLuaDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; WordList &keywords4 = *keywordlists[3]; WordList &keywords5 = *keywordlists[4]; WordList &keywords6 = *keywordlists[5]; WordList &keywords7 = *keywordlists[6]; WordList &keywords8 = *keywordlists[7]; // Accepts accented characters CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true); CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true); // Not exactly following number definition (several dots are seen as OK, etc.) // but probably enough in most cases. [pP] is for hex floats. CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefpABCDEFP"); CharacterSet setExponent(CharacterSet::setNone, "eEpP"); CharacterSet setLuaOperator(CharacterSet::setNone, "*/-+()={}~[];<>,.^%:#"); CharacterSet setEscapeSkip(CharacterSet::setNone, "\"'\\"); int currentLine = styler.GetLine(startPos); // Initialize long string [[ ... ]] or block comment --[[ ... ]] nesting level, // if we are inside such a string. Block comment was introduced in Lua 5.0, // blocks with separators [=[ ... ]=] in Lua 5.1. // Continuation of a string (\z whitespace escaping) is controlled by stringWs. int nestLevel = 0; int sepCount = 0; int stringWs = 0; if (initStyle == SCE_LUA_LITERALSTRING || initStyle == SCE_LUA_COMMENT || initStyle == SCE_LUA_STRING || initStyle == SCE_LUA_CHARACTER) { int lineState = styler.GetLineState(currentLine - 1); nestLevel = lineState >> 9; sepCount = lineState & 0xFF; stringWs = lineState & 0x100; }
static void ColouriseYAMLLine( char *lineBuffer, unsigned int currentLine, unsigned int lengthLine, unsigned int startLine, unsigned int endPos, WordList &keywords, Accessor &styler) { unsigned int i = 0; bool bInQuotes = false; unsigned int indentAmount = SpaceCount(lineBuffer); if (currentLine > 0) { int parentLineState = styler.GetLineState(currentLine - 1); if ((parentLineState&YAML_STATE_MASK) == YAML_STATE_TEXT || (parentLineState&YAML_STATE_MASK) == YAML_STATE_TEXT_PARENT) { unsigned int parentIndentAmount = parentLineState&(~YAML_STATE_MASK); if (indentAmount > parentIndentAmount) { styler.SetLineState(currentLine, YAML_STATE_TEXT | parentIndentAmount); styler.ColourTo(endPos, SCE_YAML_TEXT); return; } } } styler.SetLineState(currentLine, 0); if (strncmp(lineBuffer, "---", 3) == 0) { // Document marker styler.SetLineState(currentLine, YAML_STATE_DOCUMENT); styler.ColourTo(endPos, SCE_YAML_DOCUMENT); return; } // Skip initial spaces while ((i < lengthLine) && lineBuffer[i] == ' ') { // YAML always uses space, never TABS or anything else i++; } if (lineBuffer[i] == '\t') { // if we skipped all spaces, and we are NOT inside a text block, this is wrong styler.ColourTo(endPos, SCE_YAML_ERROR); return; } if (lineBuffer[i] == '#') { // Comment styler.SetLineState(currentLine, YAML_STATE_COMMENT); styler.ColourTo(endPos, SCE_YAML_COMMENT); return; } while (i < lengthLine) { if (lineBuffer[i] == '\'' || lineBuffer[i] == '\"') { bInQuotes = !bInQuotes; } else if (lineBuffer[i] == ':' && !bInQuotes) { styler.ColourTo(startLine + i - 1, SCE_YAML_IDENTIFIER); styler.ColourTo(startLine + i, SCE_YAML_OPERATOR); // Non-folding scalar i++; while ((i < lengthLine) && isspacechar(lineBuffer[i])) i++; unsigned int endValue = lengthLine - 1; while ((endValue >= i) && isspacechar(lineBuffer[endValue])) endValue--; lineBuffer[endValue + 1] = '\0'; if (lineBuffer[i] == '|' || lineBuffer[i] == '>') { i++; if (lineBuffer[i] == '+' || lineBuffer[i] == '-') i++; while ((i < lengthLine) && isspacechar(lineBuffer[i])) i++; if (lineBuffer[i] == '\0') { styler.SetLineState(currentLine, YAML_STATE_TEXT_PARENT | indentAmount); styler.ColourTo(endPos, SCE_YAML_DEFAULT); return; } else if (lineBuffer[i] == '#') { styler.SetLineState(currentLine, YAML_STATE_TEXT_PARENT | indentAmount); styler.ColourTo(startLine + i - 1, SCE_YAML_DEFAULT); styler.ColourTo(endPos, SCE_YAML_COMMENT); return; } else { styler.ColourTo(endPos, SCE_YAML_ERROR); return; } } else if (lineBuffer[i] == '#') { styler.ColourTo(startLine + i - 1, SCE_YAML_DEFAULT); styler.ColourTo(endPos, SCE_YAML_COMMENT); return; } styler.SetLineState(currentLine, YAML_STATE_VALUE); if (lineBuffer[i] == '&' || lineBuffer[i] == '*') { styler.ColourTo(endPos, SCE_YAML_REFERENCE); return; } if (keywords.InList(&lineBuffer[i])) { // Convertible value (true/false, etc.) styler.ColourTo(endPos, SCE_YAML_KEYWORD); return; } else { unsigned int i2 = i; while ((i < lengthLine) && lineBuffer[i]) { if (!(isascii(lineBuffer[i]) && isdigit(lineBuffer[i])) && lineBuffer[i] != '-' && lineBuffer[i] != '.' && lineBuffer[i] != ',') { styler.ColourTo(endPos, SCE_YAML_DEFAULT); return; } i++; } if (i > i2) { styler.ColourTo(endPos, SCE_YAML_NUMBER); return; } } break; // shouldn't get here, but just in case, the rest of the line is coloured the default } i++; } styler.ColourTo(endPos, SCE_YAML_DEFAULT); }
// <--- Colourise ---> void Colourise_Doc(unsigned int startPos, unsigned int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords0 = *keywordlists[0]; WordList &keywords1 = *keywordlists[1]; WordList &keywords2 = *keywordlists[2]; WordList &keywords3 = *keywordlists[3]; WordList &keywords4 = *keywordlists[4]; WordList &keywords5 = *keywordlists[5]; WordList &keywords6 = *keywordlists[6]; WordList &keywords7 = *keywordlists[7]; WordList &keywords8 = *keywordlists[8]; int currentLine = styler.GetLine(startPos); int sepCount = 0; if (initStyle == LITERALSTRING || initStyle == LUA_COMMENT) { sepCount = styler.GetLineState(currentLine - 1) & 0xFF; } // Do not leak onto next line if (initStyle == STRINGEOL || initStyle == LUA_COMMENTLINE || initStyle == CPP_COMMENTLINE) { initStyle = DEFAULT; } StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { if (sc.atLineEnd) { // Update the line state, so it can be seen by next line currentLine = styler.GetLine(sc.currentPos); switch (sc.state) { case LITERALSTRING: case LUA_COMMENT: // Inside a literal string or block comment, we set the line state styler.SetLineState(currentLine, sepCount); break; default: // Reset the line state styler.SetLineState(currentLine, 0); break; } } // Handle string line continuation if ((sc.state == STRING || sc.state == CHARACTER) && sc.ch == '\\') { if (sc.chNext == '\n' || sc.chNext == '\r') { sc.Forward(); if (sc.ch == '\r' && sc.chNext == '\n') { sc.Forward(); } continue; } } // Determine if the current state should terminate. if (sc.state == OPERATOR || sc.state == NUMBER) { sc.SetState(DEFAULT); } else if (sc.state == IDENTIFIER) { if (!IsAWordChar(sc.ch) || (sc.currentPos+1 == startPos + length)) { if (IsAWordChar(sc.ch)) { sc.Forward(); // Checks words at the end of the document. } char s[100]; sc.GetCurrent(s, sizeof(s)); if (keywords0.InList(s)) { sc.ChangeState(WORD0); } else if (keywords1.InList(s)) { sc.ChangeState(WORD1); } else if (keywords2.InList(s)) { sc.ChangeState(WORD2); } else if (keywords5.InList(s)) { sc.ChangeState(WORD5); } else if (keywords8.InList(s)) { sc.ChangeState(WORD8); } sc.SetState(DEFAULT); } } else if (sc.state == LUA_COMMENTLINE || sc.state == CPP_COMMENTLINE) { if (sc.atLineEnd) { sc.ForwardSetState(DEFAULT); } } else if (sc.state == STRING) { if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\"') { sc.ForwardSetState(DEFAULT); } else if (sc.atLineEnd) { sc.ChangeState(STRINGEOL); sc.ForwardSetState(DEFAULT); } } else if (sc.state == CHARACTER) { if (sc.ch == '\\') { if (sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\'') { sc.ForwardSetState(DEFAULT); } else if (sc.atLineEnd) { sc.ChangeState(STRINGEOL); sc.ForwardSetState(DEFAULT); } } else if (sc.state == LITERALSTRING || sc.state == LUA_COMMENT) { if (sc.ch == ']') { int sep = LongDelimCheck(sc); if (sep == sepCount) { sc.Forward(sep); sc.ForwardSetState(DEFAULT); } } } else if (sc.state == CPP_COMMENT) { if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(DEFAULT); } } else { sc.SetState(DEFAULT); } // Determine if a new state should be entered. if (sc.state == DEFAULT) { if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(NUMBER); if (sc.ch == '0' && (sc.chNext == 'x' || sc.chNext == 'X')) { int j = 1; while (IsADigit(sc.GetRelative(j+1), 16)) { j++; } sc.Forward(j); } else { int j = 0; bool hitDot(false); bool hitE(false); int ch = sc.ch; int chNext = sc.chNext; while (IsADigit(ch) || (ch == '.' && !hitDot && !hitE) || ((ch == 'e' || ch == 'E') && !hitE && (IsADigit(chNext) || ((chNext == '-' || chNext == '+') && IsADigit(sc.GetRelative(j+2)))))) { if (ch == '.') { hitDot = true; } else if (ch == 'e' || ch == 'E') { hitE = true; j++; if (chNext == '-' || chNext == '+') { j++; } chNext = sc.GetRelative(j+1); } j++; ch = chNext; chNext = sc.GetRelative(j+1); } sc.Forward(j-1); } } else if (sc.ch == ':' || sc.ch == '.') { sc.SetState(OPERATOR); if (IsAWordChar(sc.chNext) || isspace(sc.chNext)) { int j = 1; int ch = sc.chNext; while((sc.currentPos + j < startPos + length) && isspace(ch)) { ch = sc.GetRelative(++j); } if (IsAWordChar(ch)) { int i = 0; char s[101]; while (i < 100 && IsAWordChar(ch)) { s[i++] = ch; ch = sc.GetRelative(++j); } s[i++] = '\0'; if (keywords7.InList(s)) { sc.Forward(j-i+1); sc.SetState(WORD7); } if (sc.state != OPERATOR) { sc.Forward(i-2); } } } } else if (IsAWordChar(sc.ch)) { sc.SetState(IDENTIFIER); int j = 0; int i = 0; char s[101]; bool finished = false; int ch = sc.ch; while (i < 100 && (sc.currentPos + j < startPos + length) && !finished && (IsAWordChar(ch) || isspace(ch) || (ch == '.' || ch == ':'))) { if (!IsAWordChar(ch)) { while((sc.currentPos + j < startPos + length) && isspace(ch)) { ch = sc.GetRelative(++j); } if (i < 100 && (ch == '.' || ch == ':')) { s[i++] = ch; ch = sc.GetRelative(++j); while((sc.currentPos + j < startPos + length) && isspace(ch)) { ch = sc.GetRelative(++j); } while(i < 100 && IsAWordChar(ch)) { s[i++] = ch; ch = sc.GetRelative(++j); } s[i++] = '\0'; if (keywords3.InList(s)) { sc.ChangeState(WORD3); } else if (keywords4.InList(s)) { sc.ChangeState(WORD4); } else if (keywords6.InList(s)) { sc.ChangeState(WORD6); } if (sc.state != IDENTIFIER) { sc.Forward(j-1); } } finished = true; } else { s[i++] = ch; ch = sc.GetRelative(++j); } } } else if (sc.ch == '\"') { sc.SetState(STRING); } else if (sc.ch == '\'') { sc.SetState(CHARACTER); } else if (sc.ch == '[') { sepCount = LongDelimCheck(sc); if (sepCount == 0) { sc.SetState(OPERATOR); } else { sc.SetState(LITERALSTRING); sc.Forward(sepCount); } } else if (sc.Match('-', '-')) { sc.SetState(LUA_COMMENTLINE); if (sc.Match("--[")) { sc.Forward(2); sepCount = LongDelimCheck(sc); if (sepCount > 0) { sc.ChangeState(LUA_COMMENT); sc.Forward(sepCount); } } else { sc.Forward(); } } else if (sc.Match('/', '/')) { sc.SetState(CPP_COMMENTLINE); sc.Forward(); } else if (sc.Match('/', '*')) { sc.SetState(CPP_COMMENT); sc.Forward(); } else if (IsLuaOperator(sc.ch)) { sc.SetState(OPERATOR); } } } sc.Complete(); }
static void ColouriseEclDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords0 = *keywordlists[0]; WordList &keywords1 = *keywordlists[1]; WordList &keywords2 = *keywordlists[2]; WordList &keywords3 = *keywordlists[3]; //Value Types WordList &keywords4 = *keywordlists[4]; WordList &keywords5 = *keywordlists[5]; WordList &keywords6 = *keywordlists[6]; //Javadoc Tags WordList cplusplus; cplusplus.Set("beginc endc"); bool stylingWithinPreprocessor = false; CharacterSet setOKBeforeRE(CharacterSet::setNone, "(=,"); CharacterSet setDoxygen(CharacterSet::setLower, "$@\\&<>#{}[]"); CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true); CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true); CharacterSet setQualified(CharacterSet::setNone, "uUxX"); int chPrevNonWhite = ' '; int visibleChars = 0; bool lastWordWasUUID = false; int styleBeforeDCKeyword = SCE_ECL_DEFAULT; bool continuationLine = false; if (initStyle == SCE_ECL_PREPROCESSOR) { // Set continuationLine if last character of previous line is '\' Sci_Position lineCurrent = styler.GetLine(startPos); if (lineCurrent > 0) { int chBack = styler.SafeGetCharAt(startPos-1, 0); int chBack2 = styler.SafeGetCharAt(startPos-2, 0); int lineEndChar = '!'; if (chBack2 == '\r' && chBack == '\n') { lineEndChar = styler.SafeGetCharAt(startPos-3, 0); } else if (chBack == '\n' || chBack == '\r') { lineEndChar = chBack2; } continuationLine = lineEndChar == '\\'; } } // look back to set chPrevNonWhite properly for better regex colouring if (startPos > 0) { Sci_Position back = startPos; while (--back && IsSpaceEquiv(styler.StyleAt(back))) ; if (styler.StyleAt(back) == SCE_ECL_OPERATOR) { chPrevNonWhite = styler.SafeGetCharAt(back); } } StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { if (sc.atLineStart) { if (sc.state == SCE_ECL_STRING) { // Prevent SCE_ECL_STRINGEOL from leaking back to previous line which // ends with a line continuation by locking in the state upto this position. sc.SetState(SCE_ECL_STRING); } // Reset states to begining of colourise so no surprises // if different sets of lines lexed. visibleChars = 0; lastWordWasUUID = false; } // Handle line continuation generically. if (sc.ch == '\\') { if (sc.chNext == '\n' || sc.chNext == '\r') { sc.Forward(); if (sc.ch == '\r' && sc.chNext == '\n') { sc.Forward(); } continuationLine = true; continue; } } // Determine if the current state should terminate. switch (sc.state) { case SCE_ECL_ADDED: case SCE_ECL_DELETED: case SCE_ECL_CHANGED: case SCE_ECL_MOVED: if (sc.atLineStart) sc.SetState(SCE_ECL_DEFAULT); break; case SCE_ECL_OPERATOR: sc.SetState(SCE_ECL_DEFAULT); break; case SCE_ECL_NUMBER: // We accept almost anything because of hex. and number suffixes if (!setWord.Contains(sc.ch)) { sc.SetState(SCE_ECL_DEFAULT); } break; case SCE_ECL_IDENTIFIER: if (!setWord.Contains(sc.ch) || (sc.ch == '.')) { char s[1000]; sc.GetCurrentLowered(s, sizeof(s)); if (keywords0.InList(s)) { lastWordWasUUID = strcmp(s, "uuid") == 0; sc.ChangeState(SCE_ECL_WORD0); } else if (keywords1.InList(s)) { sc.ChangeState(SCE_ECL_WORD1); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_ECL_WORD2); } else if (keywords4.InList(s)) { sc.ChangeState(SCE_ECL_WORD4); } else if (keywords5.InList(s)) { sc.ChangeState(SCE_ECL_WORD5); } else //Data types are of from KEYWORD## { int i = static_cast<int>(strlen(s)) - 1; while(i >= 0 && (isdigit(s[i]) || s[i] == '_')) --i; char s2[1000]; strncpy(s2, s, i + 1); s2[i + 1] = 0; if (keywords3.InList(s2)) { sc.ChangeState(SCE_ECL_WORD3); } } sc.SetState(SCE_ECL_DEFAULT); } break; case SCE_ECL_PREPROCESSOR: if (sc.atLineStart && !continuationLine) { sc.SetState(SCE_ECL_DEFAULT); } else if (stylingWithinPreprocessor) { if (IsASpace(sc.ch)) { sc.SetState(SCE_ECL_DEFAULT); } } else { if (sc.Match('/', '*') || sc.Match('/', '/')) { sc.SetState(SCE_ECL_DEFAULT); } } break; case SCE_ECL_COMMENT: if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(SCE_ECL_DEFAULT); } break; case SCE_ECL_COMMENTDOC: if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(SCE_ECL_DEFAULT); } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support // Verify that we have the conditions to mark a comment-doc-keyword if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) { styleBeforeDCKeyword = SCE_ECL_COMMENTDOC; sc.SetState(SCE_ECL_COMMENTDOCKEYWORD); } } break; case SCE_ECL_COMMENTLINE: if (sc.atLineStart) { sc.SetState(SCE_ECL_DEFAULT); } break; case SCE_ECL_COMMENTLINEDOC: if (sc.atLineStart) { sc.SetState(SCE_ECL_DEFAULT); } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support // Verify that we have the conditions to mark a comment-doc-keyword if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) { styleBeforeDCKeyword = SCE_ECL_COMMENTLINEDOC; sc.SetState(SCE_ECL_COMMENTDOCKEYWORD); } } break; case SCE_ECL_COMMENTDOCKEYWORD: if ((styleBeforeDCKeyword == SCE_ECL_COMMENTDOC) && sc.Match('*', '/')) { sc.ChangeState(SCE_ECL_COMMENTDOCKEYWORDERROR); sc.Forward(); sc.ForwardSetState(SCE_ECL_DEFAULT); } else if (!setDoxygen.Contains(sc.ch)) { char s[1000]; sc.GetCurrentLowered(s, sizeof(s)); if (!IsASpace(sc.ch) || !keywords6.InList(s+1)) { sc.ChangeState(SCE_ECL_COMMENTDOCKEYWORDERROR); } sc.SetState(styleBeforeDCKeyword); } break; case SCE_ECL_STRING: if (sc.atLineEnd) { sc.ChangeState(SCE_ECL_STRINGEOL); } else if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\"') { sc.ForwardSetState(SCE_ECL_DEFAULT); } break; case SCE_ECL_CHARACTER: if (sc.atLineEnd) { sc.ChangeState(SCE_ECL_STRINGEOL); } else if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\'') { sc.ForwardSetState(SCE_ECL_DEFAULT); } break; case SCE_ECL_REGEX: if (sc.atLineStart) { sc.SetState(SCE_ECL_DEFAULT); } else if (sc.ch == '/') { sc.Forward(); while ((sc.ch < 0x80) && islower(sc.ch)) sc.Forward(); // gobble regex flags sc.SetState(SCE_ECL_DEFAULT); } else if (sc.ch == '\\') { // Gobble up the quoted character if (sc.chNext == '\\' || sc.chNext == '/') { sc.Forward(); } } break; case SCE_ECL_STRINGEOL: if (sc.atLineStart) { sc.SetState(SCE_ECL_DEFAULT); } break; case SCE_ECL_VERBATIM: if (sc.ch == '\"') { if (sc.chNext == '\"') { sc.Forward(); } else { sc.ForwardSetState(SCE_ECL_DEFAULT); } } break; case SCE_ECL_UUID: if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') { sc.SetState(SCE_ECL_DEFAULT); } break; } // Determine if a new state should be entered. Sci_Position lineCurrent = styler.GetLine(sc.currentPos); int lineState = styler.GetLineState(lineCurrent); if (sc.state == SCE_ECL_DEFAULT) { if (lineState) { sc.SetState(lineState); } else if (sc.Match('@', '\"')) { sc.SetState(SCE_ECL_VERBATIM); sc.Forward(); } else if (setQualified.Contains(sc.ch) && sc.chNext == '\'') { sc.SetState(SCE_ECL_CHARACTER); sc.Forward(); } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { if (lastWordWasUUID) { sc.SetState(SCE_ECL_UUID); lastWordWasUUID = false; } else { sc.SetState(SCE_ECL_NUMBER); } } else if (setWordStart.Contains(sc.ch) || (sc.ch == '@')) { if (lastWordWasUUID) { sc.SetState(SCE_ECL_UUID); lastWordWasUUID = false; } else { sc.SetState(SCE_ECL_IDENTIFIER); } } else if (sc.Match('/', '*')) { if (sc.Match("/**") || sc.Match("/*!")) { // Support of Qt/Doxygen doc. style sc.SetState(SCE_ECL_COMMENTDOC); } else { sc.SetState(SCE_ECL_COMMENT); } sc.Forward(); // Eat the * so it isn't used for the end of the comment } else if (sc.Match('/', '/')) { if ((sc.Match("///") && !sc.Match("////")) || sc.Match("//!")) // Support of Qt/Doxygen doc. style sc.SetState(SCE_ECL_COMMENTLINEDOC); else sc.SetState(SCE_ECL_COMMENTLINE); } else if (sc.ch == '/' && setOKBeforeRE.Contains(chPrevNonWhite)) { sc.SetState(SCE_ECL_REGEX); // JavaScript's RegEx // } else if (sc.ch == '\"') { // sc.SetState(SCE_ECL_STRING); } else if (sc.ch == '\'') { sc.SetState(SCE_ECL_CHARACTER); } else if (sc.ch == '#' && visibleChars == 0) { // Preprocessor commands are alone on their line sc.SetState(SCE_ECL_PREPROCESSOR); // Skip whitespace between # and preprocessor word do { sc.Forward(); } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More()); if (sc.atLineEnd) { sc.SetState(SCE_ECL_DEFAULT); } } else if (isoperator(static_cast<char>(sc.ch))) { sc.SetState(SCE_ECL_OPERATOR); } } if (!IsASpace(sc.ch) && !IsSpaceEquiv(sc.state)) { chPrevNonWhite = sc.ch; visibleChars++; } continuationLine = false; } sc.Complete(); }
static void ColouriseTALDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { styler.StartAt(startPos); int state = initStyle; if (state == SCE_C_CHARACTER) // Does not leak onto next line state = SCE_C_DEFAULT; char chPrev = ' '; char chNext = styler[startPos]; unsigned int lengthDoc = startPos + length; bool bInClassDefinition; int currentLine = styler.GetLine(startPos); if (currentLine > 0) { styler.SetLineState(currentLine, styler.GetLineState(currentLine-1)); bInClassDefinition = (styler.GetLineState(currentLine) == 1); } else { styler.SetLineState(currentLine, 0); bInClassDefinition = false; } bool bInAsm = (state == SCE_C_REGEX); if (bInAsm) state = SCE_C_DEFAULT; styler.StartSegment(startPos); int visibleChars = 0; for (unsigned int i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix) // Avoid triggering two times on Dos/Win // End of line if (state == SCE_C_CHARACTER) { ColourTo(styler, i, state, bInAsm); state = SCE_C_DEFAULT; } visibleChars = 0; currentLine++; styler.SetLineState(currentLine, (bInClassDefinition ? 1 : 0)); } if (styler.IsLeadByte(ch)) { chNext = styler.SafeGetCharAt(i + 2); chPrev = ' '; i += 1; continue; } if (state == SCE_C_DEFAULT) { if (isTALwordstart(ch)) { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_IDENTIFIER; } else if (ch == '!' && chNext != '*') { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_COMMENT; } else if (ch == '!' && chNext == '*') { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_COMMENTDOC; } else if (ch == '-' && chNext == '-') { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_COMMENTLINE; } else if (ch == '"') { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_STRING; } else if (ch == '?' && visibleChars == 0) { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_PREPROCESSOR; } else if (isTALoperator(ch)) { ColourTo(styler, i-1, state, bInAsm); ColourTo(styler, i, SCE_C_OPERATOR, bInAsm); } } else if (state == SCE_C_IDENTIFIER) { if (!isTALwordchar(ch)) { int lStateChange = classifyWordTAL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm); if(lStateChange == 1) { styler.SetLineState(currentLine, 1); bInClassDefinition = true; } else if(lStateChange == 2) { bInAsm = true; } else if(lStateChange == -1) { styler.SetLineState(currentLine, 0); bInClassDefinition = false; bInAsm = false; } state = SCE_C_DEFAULT; chNext = styler.SafeGetCharAt(i + 1); if (ch == '!' && chNext != '*') { state = SCE_C_COMMENT; } else if (ch == '!' && chNext == '*') { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_COMMENTDOC; } else if (ch == '-' && chNext == '-') { state = SCE_C_COMMENTLINE; } else if (ch == '"') { state = SCE_C_STRING; } else if (isTALoperator(ch)) { ColourTo(styler, i, SCE_C_OPERATOR, bInAsm); } } } else { if (state == SCE_C_PREPROCESSOR) { if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_DEFAULT; } } else if (state == SCE_C_COMMENT) { if (ch == '!' || (ch == '\r' || ch == '\n') ) { ColourTo(styler, i, state, bInAsm); state = SCE_C_DEFAULT; } } else if (state == SCE_C_COMMENTDOC) { if (ch == '!' || (ch == '\r' || ch == '\n')) { if (((i > styler.GetStartSegment() + 2) || ( (initStyle == SCE_C_COMMENTDOC) && (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) { ColourTo(styler, i, state, bInAsm); state = SCE_C_DEFAULT; } } } else if (state == SCE_C_COMMENTLINE) { if (ch == '\r' || ch == '\n') { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_DEFAULT; } } else if (state == SCE_C_STRING) { if (ch == '"') { ColourTo(styler, i, state, bInAsm); state = SCE_C_DEFAULT; } } } if (!isspacechar(ch)) visibleChars++; chPrev = ch; } ColourTo(styler, lengthDoc - 1, state, bInAsm); }
static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; int lineFoldStateCurrent = lineCurrent > 0 ? styler.GetLineState(lineCurrent - 1) & stateFoldMaskAll : 0; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; int lastStart = 0; CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true); for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (foldComment && IsStreamCommentStyle(style)) { if (!IsStreamCommentStyle(stylePrev)) { levelCurrent++; } else if (!IsStreamCommentStyle(styleNext) && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. levelCurrent--; } } if (foldComment && atEOL && IsCommentLine(lineCurrent, styler)) { if (!IsCommentLine(lineCurrent - 1, styler) && IsCommentLine(lineCurrent + 1, styler)) levelCurrent++; else if (IsCommentLine(lineCurrent - 1, styler) && !IsCommentLine(lineCurrent+1, styler)) levelCurrent--; } if (foldPreprocessor) { if (style == SCE_PAS_PREPROCESSOR && ch == '{' && chNext == '$') { ClassifyPascalPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 2, styler); } else if (style == SCE_PAS_PREPROCESSOR2 && ch == '(' && chNext == '*' && styler.SafeGetCharAt(i + 2) == '$') { ClassifyPascalPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 3, styler); } } if (stylePrev != SCE_PAS_WORD && style == SCE_PAS_WORD) { // Store last word start point. lastStart = i; } if (stylePrev == SCE_PAS_WORD && !(lineFoldStateCurrent & stateFoldInPreprocessor)) { if(setWord.Contains(ch) && !setWord.Contains(chNext)) { ClassifyPascalWordFoldPoint(levelCurrent, lineFoldStateCurrent, startPos, endPos, lastStart, i, styler); } } if (!IsASpace(ch)) visibleChars++; if (atEOL) { int lev = levelPrev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } int newLineState = (styler.GetLineState(lineCurrent) & ~stateFoldMaskAll) | lineFoldStateCurrent; styler.SetLineState(lineCurrent, newLineState); lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } } // If we didn't reach the EOL in previous loop, store line level and whitespace information. // The rest will be filled in later... int lev = levelPrev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; styler.SetLevel(lineCurrent, lev); }
static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { bool bSmartHighlighting = styler.GetPropertyInt("lexer.pascal.smart.highlighting", 1) != 0; CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true); CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true); CharacterSet setNumber(CharacterSet::setDigits, ".-+eE"); CharacterSet setHexNumber(CharacterSet::setDigits, "abcdefABCDEF"); CharacterSet setOperator(CharacterSet::setNone, "#$&'()*+,-./:;<=>@[]^{}"); int curLine = styler.GetLine(startPos); int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : 0; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { if (sc.atLineEnd) { // Update the line state, so it can be seen by next line curLine = styler.GetLine(sc.currentPos); styler.SetLineState(curLine, curLineState); } // Determine if the current state should terminate. switch (sc.state) { case SCE_PAS_NUMBER: if (!setNumber.Contains(sc.ch) || (sc.ch == '.' && sc.chNext == '.')) { sc.SetState(SCE_PAS_DEFAULT); } else if (sc.ch == '-' || sc.ch == '+') { if (sc.chPrev != 'E' && sc.chPrev != 'e') { sc.SetState(SCE_PAS_DEFAULT); } } break; case SCE_PAS_IDENTIFIER: if (!setWord.Contains(sc.ch)) { ClassifyPascalWord(keywordlists, sc, curLineState, bSmartHighlighting); } break; case SCE_PAS_HEXNUMBER: if (!setHexNumber.Contains(sc.ch)) { sc.SetState(SCE_PAS_DEFAULT); } break; case SCE_PAS_COMMENT: case SCE_PAS_PREPROCESSOR: if (sc.ch == '}') { sc.ForwardSetState(SCE_PAS_DEFAULT); } break; case SCE_PAS_COMMENT2: case SCE_PAS_PREPROCESSOR2: if (sc.Match('*', ')')) { sc.Forward(); sc.ForwardSetState(SCE_PAS_DEFAULT); } break; case SCE_PAS_COMMENTLINE: if (sc.atLineStart) { sc.SetState(SCE_PAS_DEFAULT); } break; case SCE_PAS_STRING: if (sc.atLineEnd) { sc.ChangeState(SCE_PAS_STRINGEOL); } else if (sc.ch == '\'' && sc.chNext == '\'') { sc.Forward(); } else if (sc.ch == '\'') { sc.ForwardSetState(SCE_PAS_DEFAULT); } break; case SCE_PAS_STRINGEOL: if (sc.atLineStart) { sc.SetState(SCE_PAS_DEFAULT); } break; case SCE_PAS_CHARACTER: if (!setHexNumber.Contains(sc.ch) && sc.ch != '$') { sc.SetState(SCE_PAS_DEFAULT); } break; case SCE_PAS_OPERATOR: if (bSmartHighlighting && sc.chPrev == ';') { curLineState &= ~(stateInProperty | stateInExport); } sc.SetState(SCE_PAS_DEFAULT); break; case SCE_PAS_ASM: sc.SetState(SCE_PAS_DEFAULT); break; } // Determine if a new state should be entered. if (sc.state == SCE_PAS_DEFAULT) { if (IsADigit(sc.ch) && !(curLineState & stateInAsm)) { sc.SetState(SCE_PAS_NUMBER); } else if (setWordStart.Contains(sc.ch)) { sc.SetState(SCE_PAS_IDENTIFIER); } else if (sc.ch == '$' && !(curLineState & stateInAsm)) { sc.SetState(SCE_PAS_HEXNUMBER); } else if (sc.Match('{', '$')) { sc.SetState(SCE_PAS_PREPROCESSOR); } else if (sc.ch == '{') { sc.SetState(SCE_PAS_COMMENT); } else if (sc.Match("(*$")) { sc.SetState(SCE_PAS_PREPROCESSOR2); } else if (sc.Match('(', '*')) { sc.SetState(SCE_PAS_COMMENT2); sc.Forward(); // Eat the * so it isn't used for the end of the comment } else if (sc.Match('/', '/')) { sc.SetState(SCE_PAS_COMMENTLINE); } else if (sc.ch == '\'') { sc.SetState(SCE_PAS_STRING); } else if (sc.ch == '#') { sc.SetState(SCE_PAS_CHARACTER); } else if (setOperator.Contains(sc.ch) && !(curLineState & stateInAsm)) { sc.SetState(SCE_PAS_OPERATOR); } else if (curLineState & stateInAsm) { sc.SetState(SCE_PAS_ASM); } } } if (sc.state == SCE_PAS_IDENTIFIER && setWord.Contains(sc.chPrev)) { ClassifyPascalWord(keywordlists, sc, curLineState, bSmartHighlighting); } sc.Complete(); }
static void ColorizeHaskellDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &ffi = *keywordlists[1]; StyleContext sc(startPos, length, initStyle, styler); int lineCurrent = styler.GetLine(startPos); int state = lineCurrent ? styler.GetLineState(lineCurrent-1) : HA_MODE_DEFAULT; int mode = state & 0xF; int xmode = state >> 4; while (sc.More()) { // Check for state end // Operator if (sc.state == SCE_HA_OPERATOR) { if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) { sc.Forward(); } else { styler.ColourTo(sc.currentPos - 1, sc.state); sc.ChangeState(SCE_HA_DEFAULT); } } // String else if (sc.state == SCE_HA_STRING) { if (sc.ch == '\"') { sc.Forward(); styler.ColourTo(sc.currentPos-1, sc.state); sc.ChangeState(SCE_HA_DEFAULT); } else if (sc.ch == '\\') { sc.Forward(2); } else if (sc.atLineEnd) { styler.ColourTo(sc.currentPos-1, sc.state); sc.ChangeState(SCE_HA_DEFAULT); } else { sc.Forward(); } } // Char else if (sc.state == SCE_HA_CHARACTER) { if (sc.ch == '\'') { sc.Forward(); styler.ColourTo(sc.currentPos-1, sc.state); sc.ChangeState(SCE_HA_DEFAULT); } else if (sc.ch == '\\') { sc.Forward(2); } else if (sc.atLineEnd) { styler.ColourTo(sc.currentPos-1, sc.state); sc.ChangeState(SCE_HA_DEFAULT); } else { sc.Forward(); } } // Number else if (sc.state == SCE_HA_NUMBER) { if (IsADigit(sc.ch, xmode)) { sc.Forward(); } else if ((xmode == 10) && (sc.ch == 'e' || sc.ch == 'E') && (IsADigit(sc.chNext) || sc.chNext == '+' || sc.chNext == '-')) { sc.Forward(); if (sc.ch == '+' || sc.ch == '-') sc.Forward(); } else { styler.ColourTo(sc.currentPos - 1, sc.state); sc.ChangeState(SCE_HA_DEFAULT); } } // Identifier else if (sc.state == SCE_HA_IDENTIFIER) { if (IsAWordChar(sc.ch)) { sc.Forward(); } else { char s[100]; sc.GetCurrent(s, sizeof(s)); int style = sc.state; int new_mode = 0; if (keywords.InList(s)) { style = SCE_HA_KEYWORD; } else if (isupper(s[0])) { if (mode >= HA_MODE_IMPORT1 && mode <= HA_MODE_IMPORT3) { style = SCE_HA_MODULE; new_mode = HA_MODE_IMPORT2; } else if (mode == HA_MODE_MODULE) style = SCE_HA_MODULE; else style = SCE_HA_CAPITAL; } else if (mode == HA_MODE_IMPORT1 && strcmp(s,"qualified") == 0) { style = SCE_HA_KEYWORD; new_mode = HA_MODE_IMPORT1; } else if (mode == HA_MODE_IMPORT2) { if (strcmp(s,"as") == 0) { style = SCE_HA_KEYWORD; new_mode = HA_MODE_IMPORT3; } else if (strcmp(s,"hiding") == 0) { style = SCE_HA_KEYWORD; } } else if (mode == HA_MODE_FFI) { if (ffi.InList(s)) { style = SCE_HA_KEYWORD; new_mode = HA_MODE_FFI; } } else if (mode == HA_MODE_TYPE) { if (strcmp(s,"family") == 0) style = SCE_HA_KEYWORD; } styler.ColourTo(sc.currentPos - 1, style); if (strcmp(s,"import") == 0 && mode != HA_MODE_FFI) new_mode = HA_MODE_IMPORT1; else if (strcmp(s,"module") == 0) new_mode = HA_MODE_MODULE; else if (strcmp(s,"foreign") == 0) new_mode = HA_MODE_FFI; else if (strcmp(s,"type") == 0) new_mode = HA_MODE_TYPE; sc.ChangeState(SCE_HA_DEFAULT); mode = new_mode; } } // Comments // Oneliner else if (sc.state == SCE_HA_COMMENTLINE) { if (sc.atLineEnd) { styler.ColourTo(sc.currentPos - 1, sc.state); sc.ChangeState(SCE_HA_DEFAULT); } else { sc.Forward(); } } // Nested else if (sc.state == SCE_HA_COMMENTBLOCK) { if (sc.Match("{-")) { sc.Forward(2); xmode++; } else if (sc.Match("-}")) { sc.Forward(2); xmode--; if (xmode == 0) { styler.ColourTo(sc.currentPos - 1, sc.state); sc.ChangeState(SCE_HA_DEFAULT); } } else { if (sc.atLineEnd) { // Remember the line state for future incremental lexing styler.SetLineState(lineCurrent, (xmode << 4) | mode); lineCurrent++; } sc.Forward(); } } // New state? if (sc.state == SCE_HA_DEFAULT) { // Digit if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)) || (sc.ch == '-' && IsADigit(sc.chNext))) { styler.ColourTo(sc.currentPos - 1, sc.state); sc.ChangeState(SCE_HA_NUMBER); if (sc.ch == '0' && (sc.chNext == 'X' || sc.chNext == 'x')) { // Match anything starting with "0x" or "0X", too sc.Forward(2); xmode = 16; } else if (sc.ch == '0' && (sc.chNext == 'O' || sc.chNext == 'o')) { // Match anything starting with "0x" or "0X", too sc.Forward(2); xmode = 8; } else { sc.Forward(); xmode = 10; } mode = HA_MODE_DEFAULT; } // Comment line else if (sc.Match("--")) { styler.ColourTo(sc.currentPos - 1, sc.state); sc.Forward(2); sc.ChangeState(SCE_HA_COMMENTLINE); // Comment block } else if (sc.Match("{-")) { styler.ColourTo(sc.currentPos - 1, sc.state); sc.Forward(2); sc.ChangeState(SCE_HA_COMMENTBLOCK); xmode = 1; } // String else if (sc.Match('\"')) { styler.ColourTo(sc.currentPos - 1, sc.state); sc.Forward(); sc.ChangeState(SCE_HA_STRING); } // Character else if (sc.Match('\'')) { styler.ColourTo(sc.currentPos - 1, sc.state); sc.Forward(); sc.ChangeState(SCE_HA_CHARACTER); } else if (sc.ch == '(' || sc.ch == ')' || sc.ch == '{' || sc.ch == '}' || sc.ch == '[' || sc.ch == ']') { styler.ColourTo(sc.currentPos - 1, sc.state); sc.Forward(); styler.ColourTo(sc.currentPos - 1, SCE_HA_OPERATOR); mode = HA_MODE_DEFAULT; } // Operator else if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) { styler.ColourTo(sc.currentPos - 1, sc.state); sc.Forward(); sc.ChangeState(SCE_HA_OPERATOR); mode = HA_MODE_DEFAULT; } // Keyword else if (IsAWordStart(sc.ch)) { styler.ColourTo(sc.currentPos - 1, sc.state); sc.Forward(); sc.ChangeState(SCE_HA_IDENTIFIER); } else { if (sc.atLineEnd) { // Remember the line state for future incremental lexing styler.SetLineState(lineCurrent, (xmode << 4) | mode); lineCurrent++; } sc.Forward(); } } } sc.Complete(); }
static void ColouriseRebolDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; WordList &keywords4 = *keywordlists[3]; WordList &keywords5 = *keywordlists[4]; WordList &keywords6 = *keywordlists[5]; WordList &keywords7 = *keywordlists[6]; WordList &keywords8 = *keywordlists[7]; int currentLine = styler.GetLine(startPos); // Initialize the braced string {.. { ... } ..} nesting level, if we are inside such a string. int stringLevel = 0; if (initStyle == SCE_REBOL_BRACEDSTRING || initStyle == SCE_REBOL_COMMENTBLOCK) { stringLevel = styler.GetLineState(currentLine - 1); } bool blockComment = initStyle == SCE_REBOL_COMMENTBLOCK; int dotCount = 0; // Do not leak onto next line if (initStyle == SCE_REBOL_COMMENTLINE) { initStyle = SCE_REBOL_DEFAULT; } StyleContext sc(startPos, length, initStyle, styler); if (startPos == 0) { sc.SetState(SCE_REBOL_PREFACE); } for (; sc.More(); sc.Forward()) { //--- What to do at line end ? if (sc.atLineEnd) { // Can be either inside a {} string or simply at eol if (sc.state != SCE_REBOL_BRACEDSTRING && sc.state != SCE_REBOL_COMMENTBLOCK && sc.state != SCE_REBOL_BINARY && sc.state != SCE_REBOL_PREFACE) sc.SetState(SCE_REBOL_DEFAULT); // Update the line state, so it can be seen by next line currentLine = styler.GetLine(sc.currentPos); switch (sc.state) { case SCE_REBOL_BRACEDSTRING: case SCE_REBOL_COMMENTBLOCK: // Inside a braced string, we set the line state styler.SetLineState(currentLine, stringLevel); break; default: // Reset the line state styler.SetLineState(currentLine, 0); break; } // continue with next char continue; } //--- What to do on white-space ? if (IsASpaceOrTab(sc.ch)) { // Return to default if any of these states if (sc.state == SCE_REBOL_OPERATOR || sc.state == SCE_REBOL_CHARACTER || sc.state == SCE_REBOL_NUMBER || sc.state == SCE_REBOL_PAIR || sc.state == SCE_REBOL_TUPLE || sc.state == SCE_REBOL_FILE || sc.state == SCE_REBOL_DATE || sc.state == SCE_REBOL_TIME || sc.state == SCE_REBOL_MONEY || sc.state == SCE_REBOL_ISSUE || sc.state == SCE_REBOL_URL || sc.state == SCE_REBOL_EMAIL) { sc.SetState(SCE_REBOL_DEFAULT); } } //--- Specialize state ? // URL, Email look like identifier if (sc.state == SCE_REBOL_IDENTIFIER) { if (sc.ch == ':' && !IsASpace(sc.chNext)) { sc.ChangeState(SCE_REBOL_URL); } else if (sc.ch == '@') { sc.ChangeState(SCE_REBOL_EMAIL); } else if (sc.ch == '$') { sc.ChangeState(SCE_REBOL_MONEY); } } // Words look like identifiers if (sc.state == SCE_REBOL_IDENTIFIER || (sc.state >= SCE_REBOL_WORD && sc.state <= SCE_REBOL_WORD8)) { // Keywords ? if (!IsAWordChar(sc.ch) || sc.Match('/')) { char s[100]; sc.GetCurrentLowered(s, sizeof(s)); blockComment = strcmp(s, "comment") == 0; if (keywords8.InList(s)) { sc.ChangeState(SCE_REBOL_WORD8); } else if (keywords7.InList(s)) { sc.ChangeState(SCE_REBOL_WORD7); } else if (keywords6.InList(s)) { sc.ChangeState(SCE_REBOL_WORD6); } else if (keywords5.InList(s)) { sc.ChangeState(SCE_REBOL_WORD5); } else if (keywords4.InList(s)) { sc.ChangeState(SCE_REBOL_WORD4); } else if (keywords3.InList(s)) { sc.ChangeState(SCE_REBOL_WORD3); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_REBOL_WORD2); } else if (keywords.InList(s)) { sc.ChangeState(SCE_REBOL_WORD); } // Keep same style if there are refinements if (!sc.Match('/')) { sc.SetState(SCE_REBOL_DEFAULT); } } // special numbers } else if (sc.state == SCE_REBOL_NUMBER) { switch (sc.ch) { case 'x': sc.ChangeState(SCE_REBOL_PAIR); break; case ':': sc.ChangeState(SCE_REBOL_TIME); break; case '-': case '/': sc.ChangeState(SCE_REBOL_DATE); break; case '.': if (++dotCount >= 2) sc.ChangeState(SCE_REBOL_TUPLE); break; } } //--- Determine if the current state should terminate if (sc.state == SCE_REBOL_QUOTEDSTRING || sc.state == SCE_REBOL_CHARACTER) { if (sc.ch == '^' && sc.chNext == '\"') { sc.Forward(); } else if (sc.ch == '\"') { sc.ForwardSetState(SCE_REBOL_DEFAULT); } } else if (sc.state == SCE_REBOL_BRACEDSTRING || sc.state == SCE_REBOL_COMMENTBLOCK) { if (sc.ch == '}') { if (--stringLevel == 0) { sc.ForwardSetState(SCE_REBOL_DEFAULT); } } else if (sc.ch == '{') { stringLevel++; } } else if (sc.state == SCE_REBOL_BINARY) { if (sc.ch == '}') { sc.ForwardSetState(SCE_REBOL_DEFAULT); } } else if (sc.state == SCE_REBOL_TAG) { if (sc.ch == '>') { sc.ForwardSetState(SCE_REBOL_DEFAULT); } } else if (sc.state == SCE_REBOL_PREFACE) { if (sc.MatchIgnoreCase("rebol")) { int i; for (i=5; IsASpaceOrTab(styler.SafeGetCharAt(sc.currentPos+i, 0)); i++); if (sc.GetRelative(i) == '[') sc.SetState(SCE_REBOL_DEFAULT); } } //--- Parens and bracket changes to default style when the current is a number if (sc.state == SCE_REBOL_NUMBER || sc.state == SCE_REBOL_PAIR || sc.state == SCE_REBOL_TUPLE || sc.state == SCE_REBOL_MONEY || sc.state == SCE_REBOL_ISSUE || sc.state == SCE_REBOL_EMAIL || sc.state == SCE_REBOL_URL || sc.state == SCE_REBOL_DATE || sc.state == SCE_REBOL_TIME) { if (sc.ch == '(' || sc.ch == '[' || sc.ch == ')' || sc.ch == ']') { sc.SetState(SCE_REBOL_DEFAULT); } } //--- Determine if a new state should be entered. if (sc.state == SCE_REBOL_DEFAULT) { if (IsAnOperator(sc.ch, sc.chNext, sc.GetRelative(2))) { sc.SetState(SCE_REBOL_OPERATOR); } else if (IsBinaryStart(sc.ch, sc.chNext, sc.GetRelative(2), sc.GetRelative(3))) { sc.SetState(SCE_REBOL_BINARY); } else if (IsAWordStart(sc.ch, sc.chNext)) { sc.SetState(SCE_REBOL_IDENTIFIER); } else if (IsADigit(sc.ch) || sc.ch == '+' || sc.ch == '-' || /*Decimal*/ sc.ch == '.' || sc.ch == ',') { dotCount = 0; sc.SetState(SCE_REBOL_NUMBER); } else if (sc.ch == '\"') { sc.SetState(SCE_REBOL_QUOTEDSTRING); } else if (sc.ch == '{') { sc.SetState(blockComment ? SCE_REBOL_COMMENTBLOCK : SCE_REBOL_BRACEDSTRING); ++stringLevel; } else if (sc.ch == ';') { sc.SetState(SCE_REBOL_COMMENTLINE); } else if (sc.ch == '$') { sc.SetState(SCE_REBOL_MONEY); } else if (sc.ch == '%') { sc.SetState(SCE_REBOL_FILE); } else if (sc.ch == '<') { sc.SetState(SCE_REBOL_TAG); } else if (sc.ch == '#' && sc.chNext == '"') { sc.SetState(SCE_REBOL_CHARACTER); sc.Forward(); } else if (sc.ch == '#' && sc.chNext != '"' && sc.chNext != '{' ) { sc.SetState(SCE_REBOL_ISSUE); } } } sc.Complete(); }
static void ColouriseDocument( Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; StyleContext sc(startPos, length, initStyle, styler); Sci_Position lineCurrent = styler.GetLine(startPos); bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0; while (sc.More()) { if (sc.atLineEnd) { // Go to the next line sc.Forward(); lineCurrent++; // Remember the line state for future incremental lexing styler.SetLineState(lineCurrent, apostropheStartsAttribute); // Don't continue any styles on the next line sc.SetState(SCE_ADA_DEFAULT); } // Comments if (sc.Match('-', '-')) { ColouriseComment(sc, apostropheStartsAttribute); // Strings } else if (sc.Match('"')) { ColouriseString(sc, apostropheStartsAttribute); // Characters } else if (sc.Match('\'') && !apostropheStartsAttribute) { ColouriseCharacter(sc, apostropheStartsAttribute); // Labels } else if (sc.Match('<', '<')) { ColouriseLabel(sc, keywords, apostropheStartsAttribute); // Whitespace } else if (IsASpace(sc.ch)) { ColouriseWhiteSpace(sc, apostropheStartsAttribute); // Delimiters } else if (IsDelimiterCharacter(sc.ch)) { ColouriseDelimiter(sc, apostropheStartsAttribute); // Numbers } else if (IsADigit(sc.ch) || sc.ch == '#') { ColouriseNumber(sc, apostropheStartsAttribute); // Keywords or identifiers } else { ColouriseWord(sc, keywords, apostropheStartsAttribute); } } sc.Complete(); }
static void ColourisePSDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords1 = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; WordList &keywords4 = *keywordlists[3]; WordList &keywords5 = *keywordlists[4]; StyleContext sc(startPos, length, initStyle, styler); bool tokenizing = styler.GetPropertyInt("ps.tokenize") != 0; int pslevel = styler.GetPropertyInt("ps.level", 3); int lineCurrent = styler.GetLine(startPos); int nestTextCurrent = 0; if (lineCurrent > 0 && initStyle == SCE_PS_TEXT) nestTextCurrent = styler.GetLineState(lineCurrent - 1); int numRadix = 0; bool numHasPoint = false; bool numHasExponent = false; bool numHasSign = false; // Clear out existing tokenization if (tokenizing && length > 0) { styler.StartAt(startPos, static_cast<char>(INDIC2_MASK)); styler.ColourTo(startPos + length-1, 0); styler.Flush(); styler.StartAt(startPos); styler.StartSegment(startPos); } for (; sc.More(); sc.Forward()) { if (sc.atLineStart) lineCurrent = styler.GetLine(sc.currentPos); // Determine if the current state should terminate. if (sc.state == SCE_PS_COMMENT || sc.state == SCE_PS_DSC_VALUE) { if (sc.atLineEnd) { sc.SetState(SCE_C_DEFAULT); } } else if (sc.state == SCE_PS_DSC_COMMENT) { if (sc.ch == ':') { sc.Forward(); if (!sc.atLineEnd) sc.SetState(SCE_PS_DSC_VALUE); else sc.SetState(SCE_C_DEFAULT); } else if (sc.atLineEnd) { sc.SetState(SCE_C_DEFAULT); } else if (IsAWhitespaceChar(sc.ch) && sc.ch != '\r') { sc.ChangeState(SCE_PS_COMMENT); } } else if (sc.state == SCE_PS_NUMBER) { if (IsASelfDelimitingChar(sc.ch) || IsAWhitespaceChar(sc.ch)) { if ((sc.chPrev == '+' || sc.chPrev == '-' || sc.chPrev == 'E' || sc.chPrev == 'e') && numRadix == 0) sc.ChangeState(SCE_PS_NAME); sc.SetState(SCE_C_DEFAULT); } else if (sc.ch == '#') { if (numHasPoint || numHasExponent || numHasSign || numRadix != 0) { sc.ChangeState(SCE_PS_NAME); } else { char szradix[5]; sc.GetCurrent(szradix, 4); numRadix = atoi(szradix); if (numRadix < 2 || numRadix > 36) sc.ChangeState(SCE_PS_NAME); } } else if ((sc.ch == 'E' || sc.ch == 'e') && numRadix == 0) { if (numHasExponent) { sc.ChangeState(SCE_PS_NAME); } else { numHasExponent = true; if (sc.chNext == '+' || sc.chNext == '-') sc.Forward(); } } else if (sc.ch == '.') { if (numHasPoint || numHasExponent || numRadix != 0) { sc.ChangeState(SCE_PS_NAME); } else { numHasPoint = true; } } else if (numRadix == 0) { if (!IsABaseNDigit(sc.ch, 10)) sc.ChangeState(SCE_PS_NAME); } else { if (!IsABaseNDigit(sc.ch, numRadix)) sc.ChangeState(SCE_PS_NAME); } } else if (sc.state == SCE_PS_NAME || sc.state == SCE_PS_KEYWORD) { if (IsASelfDelimitingChar(sc.ch) || IsAWhitespaceChar(sc.ch)) { char s[100]; sc.GetCurrent(s, sizeof(s)); if ((pslevel >= 1 && keywords1.InList(s)) || (pslevel >= 2 && keywords2.InList(s)) || (pslevel >= 3 && keywords3.InList(s)) || keywords4.InList(s) || keywords5.InList(s)) { sc.ChangeState(SCE_PS_KEYWORD); } sc.SetState(SCE_C_DEFAULT); } } else if (sc.state == SCE_PS_LITERAL || sc.state == SCE_PS_IMMEVAL) { if (IsASelfDelimitingChar(sc.ch) || IsAWhitespaceChar(sc.ch)) sc.SetState(SCE_C_DEFAULT); } else if (sc.state == SCE_PS_PAREN_ARRAY || sc.state == SCE_PS_PAREN_DICT || sc.state == SCE_PS_PAREN_PROC) { sc.SetState(SCE_C_DEFAULT); } else if (sc.state == SCE_PS_TEXT) { if (sc.ch == '(') { nestTextCurrent++; } else if (sc.ch == ')') { if (--nestTextCurrent == 0) sc.ForwardSetState(SCE_PS_DEFAULT); } else if (sc.ch == '\\') { sc.Forward(); } } else if (sc.state == SCE_PS_HEXSTRING) { if (sc.ch == '>') { sc.ForwardSetState(SCE_PS_DEFAULT); } else if (!IsABaseNDigit(sc.ch, 16) && !IsAWhitespaceChar(sc.ch)) { sc.SetState(SCE_PS_HEXSTRING); styler.ColourTo(sc.currentPos, SCE_PS_BADSTRINGCHAR); } } else if (sc.state == SCE_PS_BASE85STRING) { if (sc.Match('~', '>')) { sc.Forward(); sc.ForwardSetState(SCE_PS_DEFAULT); } else if (!IsABase85Char(sc.ch) && !IsAWhitespaceChar(sc.ch)) { sc.SetState(SCE_PS_BASE85STRING); styler.ColourTo(sc.currentPos, SCE_PS_BADSTRINGCHAR); } } // Determine if a new state should be entered. if (sc.state == SCE_C_DEFAULT) { unsigned int tokenpos = sc.currentPos; if (sc.ch == '[' || sc.ch == ']') { sc.SetState(SCE_PS_PAREN_ARRAY); } else if (sc.ch == '{' || sc.ch == '}') { sc.SetState(SCE_PS_PAREN_PROC); } else if (sc.ch == '/') { if (sc.chNext == '/') { sc.SetState(SCE_PS_IMMEVAL); sc.Forward(); } else { sc.SetState(SCE_PS_LITERAL); } } else if (sc.ch == '<') { if (sc.chNext == '<') { sc.SetState(SCE_PS_PAREN_DICT); sc.Forward(); } else if (sc.chNext == '~') { sc.SetState(SCE_PS_BASE85STRING); sc.Forward(); } else { sc.SetState(SCE_PS_HEXSTRING); } } else if (sc.ch == '>' && sc.chNext == '>') { sc.SetState(SCE_PS_PAREN_DICT); sc.Forward(); } else if (sc.ch == '>' || sc.ch == ')') { sc.SetState(SCE_C_DEFAULT); styler.ColourTo(sc.currentPos, SCE_PS_BADSTRINGCHAR); } else if (sc.ch == '(') { sc.SetState(SCE_PS_TEXT); nestTextCurrent = 1; } else if (sc.ch == '%') { if (sc.chNext == '%' && sc.atLineStart) { sc.SetState(SCE_PS_DSC_COMMENT); sc.Forward(); if (sc.chNext == '+') { sc.Forward(); sc.ForwardSetState(SCE_PS_DSC_VALUE); } } else { sc.SetState(SCE_PS_COMMENT); } } else if ((sc.ch == '+' || sc.ch == '-' || sc.ch == '.') && IsABaseNDigit(sc.chNext, 10)) { sc.SetState(SCE_PS_NUMBER); numRadix = 0; numHasPoint = (sc.ch == '.'); numHasExponent = false; numHasSign = (sc.ch == '+' || sc.ch == '-'); } else if ((sc.ch == '+' || sc.ch == '-') && sc.chNext == '.' && IsABaseNDigit(sc.GetRelative(2), 10)) { sc.SetState(SCE_PS_NUMBER); numRadix = 0; numHasPoint = false; numHasExponent = false; numHasSign = true; } else if (IsABaseNDigit(sc.ch, 10)) { sc.SetState(SCE_PS_NUMBER); numRadix = 0; numHasPoint = false; numHasExponent = false; numHasSign = false; } else if (!IsAWhitespaceChar(sc.ch)) { sc.SetState(SCE_PS_NAME); } // Mark the start of tokens if (tokenizing && sc.state != SCE_C_DEFAULT && sc.state != SCE_PS_COMMENT && sc.state != SCE_PS_DSC_COMMENT && sc.state != SCE_PS_DSC_VALUE) { styler.Flush(); styler.StartAt(tokenpos, static_cast<char>(INDIC2_MASK)); styler.ColourTo(tokenpos, INDIC2_MASK); styler.Flush(); styler.StartAt(tokenpos); styler.StartSegment(tokenpos); } } if (sc.atLineEnd) styler.SetLineState(lineCurrent, nestTextCurrent); } sc.Complete(); }
static void ColouriseBashDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList cmdDelimiter, bashStruct, bashStruct_in; cmdDelimiter.Set("| || |& & && ; ;; ( ) { }"); bashStruct.Set("if elif fi while until else then do done esac eval"); bashStruct_in.Set("for case select"); CharacterSet setWordStart(CharacterSet::setAlpha, "_"); // note that [+-] are often parts of identifiers in shell scripts CharacterSet setWord(CharacterSet::setAlphaNum, "._+-"); CharacterSet setMetaCharacter(CharacterSet::setNone, "|&;()<> \t\r\n"); setMetaCharacter.Add(0); CharacterSet setBashOperator(CharacterSet::setNone, "^&%()-+=|{}[]:;>,*/<?!.~@"); CharacterSet setSingleCharOp(CharacterSet::setNone, "rwxoRWXOezsfdlpSbctugkTBMACahGLNn"); CharacterSet setParam(CharacterSet::setAlphaNum, "$_"); CharacterSet setHereDoc(CharacterSet::setAlpha, "_\\-+!%*,./:?@[]^`{}~"); CharacterSet setHereDoc2(CharacterSet::setAlphaNum, "_-+!%*,./:=?@[]^`{}~"); CharacterSet setLeftShift(CharacterSet::setDigits, "$"); class HereDocCls { // Class to manage HERE document elements public: int State; // 0: '<<' encountered // 1: collect the delimiter // 2: here doc text (lines after the delimiter) int Quote; // the char after '<<' bool Quoted; // true if Quote in ('\'','"','`') bool Indent; // indented delimiter (for <<-) int DelimiterLength; // strlen(Delimiter) char Delimiter[HERE_DELIM_MAX]; // the Delimiter HereDocCls() { State = 0; Quote = 0; Quoted = false; Indent = 0; DelimiterLength = 0; Delimiter[0] = '\0'; } void Append(int ch) { Delimiter[DelimiterLength++] = static_cast<char>(ch); Delimiter[DelimiterLength] = '\0'; } ~HereDocCls() { } }; HereDocCls HereDoc; class QuoteCls { // Class to manage quote pairs (simplified vs LexPerl) public: int Count; int Up, Down; QuoteCls() { Count = 0; Up = '\0'; Down = '\0'; } void Open(int u) { Count++; Up = u; Down = opposite(Up); } void Start(int u) { Count = 0; Open(u); } }; QuoteCls Quote; class QuoteStackCls { // Class to manage quote pairs that nest public: int Count; int Up, Down; int Style; int Depth; // levels pushed int CountStack[BASH_DELIM_STACK_MAX]; int UpStack [BASH_DELIM_STACK_MAX]; int StyleStack[BASH_DELIM_STACK_MAX]; QuoteStackCls() { Count = 0; Up = '\0'; Down = '\0'; Style = 0; Depth = 0; } void Start(int u, int s) { Count = 1; Up = u; Down = opposite(Up); Style = s; } void Push(int u, int s) { if (Depth >= BASH_DELIM_STACK_MAX) return; CountStack[Depth] = Count; UpStack [Depth] = Up; StyleStack[Depth] = Style; Depth++; Count = 1; Up = u; Down = opposite(Up); Style = s; } void Pop(void) { if (Depth <= 0) return; Depth--; Count = CountStack[Depth]; Up = UpStack [Depth]; Style = StyleStack[Depth]; Down = opposite(Up); } ~QuoteStackCls() { } }; QuoteStackCls QuoteStack; int numBase = 0; int digit; Sci_PositionU endPos = startPos + length; int cmdState = BASH_CMD_START; int testExprType = 0; // Always backtracks to the start of a line that is not a continuation // of the previous line (i.e. start of a bash command segment) Sci_Position ln = styler.GetLine(startPos); if (ln > 0 && startPos == static_cast<Sci_PositionU>(styler.LineStart(ln))) ln--; for (;;) { startPos = styler.LineStart(ln); if (ln == 0 || styler.GetLineState(ln) == BASH_CMD_START) break; ln--; } initStyle = SCE_SH_DEFAULT; StyleContext sc(startPos, endPos - startPos, initStyle, styler); for (; sc.More(); sc.Forward()) { // handle line continuation, updates per-line stored state if (sc.atLineStart) { ln = styler.GetLine(sc.currentPos); if (sc.state == SCE_SH_STRING || sc.state == SCE_SH_BACKTICKS || sc.state == SCE_SH_CHARACTER || sc.state == SCE_SH_HERE_Q || sc.state == SCE_SH_COMMENTLINE || sc.state == SCE_SH_PARAM) { // force backtrack while retaining cmdState styler.SetLineState(ln, BASH_CMD_BODY); } else { if (ln > 0) { if ((sc.GetRelative(-3) == '\\' && sc.GetRelative(-2) == '\r' && sc.chPrev == '\n') || sc.GetRelative(-2) == '\\') { // handle '\' line continuation // retain last line's state } else cmdState = BASH_CMD_START; } styler.SetLineState(ln, cmdState); } } // controls change of cmdState at the end of a non-whitespace element // states BODY|TEST|ARITH persist until the end of a command segment // state WORD persist, but ends with 'in' or 'do' construct keywords int cmdStateNew = BASH_CMD_BODY; if (cmdState == BASH_CMD_TEST || cmdState == BASH_CMD_ARITH || cmdState == BASH_CMD_WORD) cmdStateNew = cmdState; int stylePrev = sc.state; // Determine if the current state should terminate. switch (sc.state) { case SCE_SH_OPERATOR: sc.SetState(SCE_SH_DEFAULT); if (cmdState == BASH_CMD_DELIM) // if command delimiter, start new command cmdStateNew = BASH_CMD_START; else if (sc.chPrev == '\\') // propagate command state if line continued cmdStateNew = cmdState; break; case SCE_SH_WORD: // "." never used in Bash variable names but used in file names if (!setWord.Contains(sc.ch)) { char s[500]; char s2[10]; sc.GetCurrent(s, sizeof(s)); // allow keywords ending in a whitespace or command delimiter s2[0] = static_cast<char>(sc.ch); s2[1] = '\0'; bool keywordEnds = IsASpace(sc.ch) || cmdDelimiter.InList(s2); // 'in' or 'do' may be construct keywords if (cmdState == BASH_CMD_WORD) { if (strcmp(s, "in") == 0 && keywordEnds) cmdStateNew = BASH_CMD_BODY; else if (strcmp(s, "do") == 0 && keywordEnds) cmdStateNew = BASH_CMD_START; else sc.ChangeState(SCE_SH_IDENTIFIER); sc.SetState(SCE_SH_DEFAULT); break; } // a 'test' keyword starts a test expression if (strcmp(s, "test") == 0) { if (cmdState == BASH_CMD_START && keywordEnds) { cmdStateNew = BASH_CMD_TEST; testExprType = 0; } else sc.ChangeState(SCE_SH_IDENTIFIER); } // detect bash construct keywords else if (bashStruct.InList(s)) { if (cmdState == BASH_CMD_START && keywordEnds) cmdStateNew = BASH_CMD_START; else sc.ChangeState(SCE_SH_IDENTIFIER); } // 'for'|'case'|'select' needs 'in'|'do' to be highlighted later else if (bashStruct_in.InList(s)) { if (cmdState == BASH_CMD_START && keywordEnds) cmdStateNew = BASH_CMD_WORD; else sc.ChangeState(SCE_SH_IDENTIFIER); } // disambiguate option items and file test operators else if (s[0] == '-') { if (cmdState != BASH_CMD_TEST) sc.ChangeState(SCE_SH_IDENTIFIER); } // disambiguate keywords and identifiers else if (cmdState != BASH_CMD_START || !(keywords.InList(s) && keywordEnds)) { sc.ChangeState(SCE_SH_IDENTIFIER); } sc.SetState(SCE_SH_DEFAULT); } break; case SCE_SH_IDENTIFIER: if (sc.chPrev == '\\') { // for escaped chars sc.ForwardSetState(SCE_SH_DEFAULT); } else if (!setWord.Contains(sc.ch)) { sc.SetState(SCE_SH_DEFAULT); } else if (cmdState == BASH_CMD_ARITH && !setWordStart.Contains(sc.ch)) { sc.SetState(SCE_SH_DEFAULT); } break; case SCE_SH_NUMBER: digit = translateBashDigit(sc.ch); if (numBase == BASH_BASE_DECIMAL) { if (sc.ch == '#') { char s[10]; sc.GetCurrent(s, sizeof(s)); numBase = getBashNumberBase(s); if (numBase != BASH_BASE_ERROR) break; } else if (IsADigit(sc.ch)) break; } else if (numBase == BASH_BASE_HEX) { if (IsADigit(sc.ch, 16)) break; #ifdef PEDANTIC_OCTAL } else if (numBase == BASH_BASE_OCTAL || numBase == BASH_BASE_OCTAL_ERROR) { if (digit <= 7) break; if (digit <= 9) { numBase = BASH_BASE_OCTAL_ERROR; break; } #endif } else if (numBase == BASH_BASE_ERROR) { if (digit <= 9) break; } else { // DD#DDDD number style handling if (digit != BASH_BASE_ERROR) { if (numBase <= 36) { // case-insensitive if base<=36 if (digit >= 36) digit -= 26; } if (digit < numBase) break; if (digit <= 9) { numBase = BASH_BASE_ERROR; break; } } } // fallthrough when number is at an end or error if (numBase == BASH_BASE_ERROR #ifdef PEDANTIC_OCTAL || numBase == BASH_BASE_OCTAL_ERROR #endif ) { sc.ChangeState(SCE_SH_ERROR); } sc.SetState(SCE_SH_DEFAULT); break; case SCE_SH_COMMENTLINE: if (sc.atLineEnd && sc.chPrev != '\\') { sc.SetState(SCE_SH_DEFAULT); } break; case SCE_SH_HERE_DELIM: // From Bash info: // --------------- // Specifier format is: <<[-]WORD // Optional '-' is for removal of leading tabs from here-doc. // Whitespace acceptable after <<[-] operator // if (HereDoc.State == 0) { // '<<' encountered HereDoc.Quote = sc.chNext; HereDoc.Quoted = false; HereDoc.DelimiterLength = 0; HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0'; if (sc.chNext == '\'' || sc.chNext == '\"') { // a quoted here-doc delimiter (' or ") sc.Forward(); HereDoc.Quoted = true; HereDoc.State = 1; } else if (setHereDoc.Contains(sc.chNext) || (sc.chNext == '=' && cmdState != BASH_CMD_ARITH)) { // an unquoted here-doc delimiter, no special handling HereDoc.State = 1; } else if (sc.chNext == '<') { // HERE string <<< sc.Forward(); sc.ForwardSetState(SCE_SH_DEFAULT); } else if (IsASpace(sc.chNext)) { // eat whitespace } else if (setLeftShift.Contains(sc.chNext) || (sc.chNext == '=' && cmdState == BASH_CMD_ARITH)) { // left shift <<$var or <<= cases sc.ChangeState(SCE_SH_OPERATOR); sc.ForwardSetState(SCE_SH_DEFAULT); } else { // symbols terminates; deprecated zero-length delimiter HereDoc.State = 1; } } else if (HereDoc.State == 1) { // collect the delimiter // * if single quoted, there's no escape // * if double quoted, there are \\ and \" escapes if ((HereDoc.Quote == '\'' && sc.ch != HereDoc.Quote) || (HereDoc.Quoted && sc.ch != HereDoc.Quote && sc.ch != '\\') || (HereDoc.Quote != '\'' && sc.chPrev == '\\') || (setHereDoc2.Contains(sc.ch))) { HereDoc.Append(sc.ch); } else if (HereDoc.Quoted && sc.ch == HereDoc.Quote) { // closing quote => end of delimiter sc.ForwardSetState(SCE_SH_DEFAULT); } else if (sc.ch == '\\') { if (HereDoc.Quoted && sc.chNext != HereDoc.Quote && sc.chNext != '\\') { // in quoted prefixes only \ and the quote eat the escape HereDoc.Append(sc.ch); } else { // skip escape prefix } } else if (!HereDoc.Quoted) { sc.SetState(SCE_SH_DEFAULT); } if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) { // force blowup sc.SetState(SCE_SH_ERROR); HereDoc.State = 0; } } break; case SCE_SH_HERE_Q: // HereDoc.State == 2 if (sc.atLineStart) { sc.SetState(SCE_SH_HERE_Q); int prefixws = 0; while (sc.ch == '\t' && !sc.atLineEnd) { // tabulation prefix sc.Forward(); prefixws++; } if (prefixws > 0) sc.SetState(SCE_SH_HERE_Q); while (!sc.atLineEnd) { sc.Forward(); } char s[HERE_DELIM_MAX]; sc.GetCurrent(s, sizeof(s)); if (sc.LengthCurrent() == 0) { // '' or "" delimiters if ((prefixws == 0 || HereDoc.Indent) && HereDoc.Quoted && HereDoc.DelimiterLength == 0) sc.SetState(SCE_SH_DEFAULT); break; } if (s[strlen(s) - 1] == '\r') s[strlen(s) - 1] = '\0'; if (strcmp(HereDoc.Delimiter, s) == 0) { if ((prefixws == 0) || // indentation rule (prefixws > 0 && HereDoc.Indent)) { sc.SetState(SCE_SH_DEFAULT); break; } } } break; case SCE_SH_SCALAR: // variable names if (!setParam.Contains(sc.ch)) { if (sc.LengthCurrent() == 1) { // Special variable: $(, $_ etc. sc.ForwardSetState(SCE_SH_DEFAULT); } else { sc.SetState(SCE_SH_DEFAULT); } } break; case SCE_SH_STRING: // delimited styles, can nest case SCE_SH_BACKTICKS: if (sc.ch == '\\' && QuoteStack.Up != '\\') { if (QuoteStack.Style != BASH_DELIM_LITERAL) sc.Forward(); } else if (sc.ch == QuoteStack.Down) { QuoteStack.Count--; if (QuoteStack.Count == 0) { if (QuoteStack.Depth > 0) { QuoteStack.Pop(); } else sc.ForwardSetState(SCE_SH_DEFAULT); } } else if (sc.ch == QuoteStack.Up) { QuoteStack.Count++; } else { if (QuoteStack.Style == BASH_DELIM_STRING || QuoteStack.Style == BASH_DELIM_LSTRING ) { // do nesting for "string", $"locale-string" if (sc.ch == '`') { QuoteStack.Push(sc.ch, BASH_DELIM_BACKTICK); } else if (sc.ch == '$' && sc.chNext == '(') { sc.Forward(); QuoteStack.Push(sc.ch, BASH_DELIM_COMMAND); } } else if (QuoteStack.Style == BASH_DELIM_COMMAND || QuoteStack.Style == BASH_DELIM_BACKTICK ) { // do nesting for $(command), `command` if (sc.ch == '\'') { QuoteStack.Push(sc.ch, BASH_DELIM_LITERAL); } else if (sc.ch == '\"') { QuoteStack.Push(sc.ch, BASH_DELIM_STRING); } else if (sc.ch == '`') { QuoteStack.Push(sc.ch, BASH_DELIM_BACKTICK); } else if (sc.ch == '$') { if (sc.chNext == '\'') { sc.Forward(); QuoteStack.Push(sc.ch, BASH_DELIM_CSTRING); } else if (sc.chNext == '\"') { sc.Forward(); QuoteStack.Push(sc.ch, BASH_DELIM_LSTRING); } else if (sc.chNext == '(') { sc.Forward(); QuoteStack.Push(sc.ch, BASH_DELIM_COMMAND); } } } } break; case SCE_SH_PARAM: // ${parameter} if (sc.ch == '\\' && Quote.Up != '\\') { sc.Forward(); } else if (sc.ch == Quote.Down) { Quote.Count--; if (Quote.Count == 0) { sc.ForwardSetState(SCE_SH_DEFAULT); } } else if (sc.ch == Quote.Up) { Quote.Count++; } break; case SCE_SH_CHARACTER: // singly-quoted strings if (sc.ch == Quote.Down) { Quote.Count--; if (Quote.Count == 0) { sc.ForwardSetState(SCE_SH_DEFAULT); } } break; } // Must check end of HereDoc state 1 before default state is handled if (HereDoc.State == 1 && sc.atLineEnd) { // Begin of here-doc (the line after the here-doc delimiter): // Lexically, the here-doc starts from the next line after the >>, but the // first line of here-doc seem to follow the style of the last EOL sequence HereDoc.State = 2; if (HereDoc.Quoted) { if (sc.state == SCE_SH_HERE_DELIM) { // Missing quote at end of string! Syntax error in bash 4.3 // Mark this bit as an error, do not colour any here-doc sc.ChangeState(SCE_SH_ERROR); sc.SetState(SCE_SH_DEFAULT); } else { // HereDoc.Quote always == '\'' sc.SetState(SCE_SH_HERE_Q); } } else if (HereDoc.DelimiterLength == 0) { // no delimiter, illegal (but '' and "" are legal) sc.ChangeState(SCE_SH_ERROR); sc.SetState(SCE_SH_DEFAULT); } else { sc.SetState(SCE_SH_HERE_Q); } } // update cmdState about the current command segment if (stylePrev != SCE_SH_DEFAULT && sc.state == SCE_SH_DEFAULT) { cmdState = cmdStateNew; } // Determine if a new state should be entered. if (sc.state == SCE_SH_DEFAULT) { if (sc.ch == '\\') { // Bash can escape any non-newline as a literal sc.SetState(SCE_SH_IDENTIFIER); if (sc.chNext == '\r' || sc.chNext == '\n') sc.SetState(SCE_SH_OPERATOR); } else if (IsADigit(sc.ch)) { sc.SetState(SCE_SH_NUMBER); numBase = BASH_BASE_DECIMAL; if (sc.ch == '0') { // hex,octal if (sc.chNext == 'x' || sc.chNext == 'X') { numBase = BASH_BASE_HEX; sc.Forward(); } else if (IsADigit(sc.chNext)) { #ifdef PEDANTIC_OCTAL numBase = BASH_BASE_OCTAL; #else numBase = BASH_BASE_HEX; #endif } } } else if (setWordStart.Contains(sc.ch)) { sc.SetState(SCE_SH_WORD); } else if (sc.ch == '#') { if (stylePrev != SCE_SH_WORD && stylePrev != SCE_SH_IDENTIFIER && (sc.currentPos == 0 || setMetaCharacter.Contains(sc.chPrev))) { sc.SetState(SCE_SH_COMMENTLINE); } else { sc.SetState(SCE_SH_WORD); } // handle some zsh features within arithmetic expressions only if (cmdState == BASH_CMD_ARITH) { if (sc.chPrev == '[') { // [#8] [##8] output digit setting sc.SetState(SCE_SH_WORD); if (sc.chNext == '#') { sc.Forward(); } } else if (sc.Match("##^") && IsUpperCase(sc.GetRelative(3))) { // ##^A sc.SetState(SCE_SH_IDENTIFIER); sc.Forward(3); } else if (sc.chNext == '#' && !IsASpace(sc.GetRelative(2))) { // ##a sc.SetState(SCE_SH_IDENTIFIER); sc.Forward(2); } else if (setWordStart.Contains(sc.chNext)) { // #name sc.SetState(SCE_SH_IDENTIFIER); } } } else if (sc.ch == '\"') { sc.SetState(SCE_SH_STRING); QuoteStack.Start(sc.ch, BASH_DELIM_STRING); } else if (sc.ch == '\'') { sc.SetState(SCE_SH_CHARACTER); Quote.Start(sc.ch); } else if (sc.ch == '`') { sc.SetState(SCE_SH_BACKTICKS); QuoteStack.Start(sc.ch, BASH_DELIM_BACKTICK); } else if (sc.ch == '$') { if (sc.Match("$((")) { sc.SetState(SCE_SH_OPERATOR); // handle '((' later continue; } sc.SetState(SCE_SH_SCALAR); sc.Forward(); if (sc.ch == '{') { sc.ChangeState(SCE_SH_PARAM); Quote.Start(sc.ch); } else if (sc.ch == '\'') { sc.ChangeState(SCE_SH_STRING); QuoteStack.Start(sc.ch, BASH_DELIM_CSTRING); } else if (sc.ch == '"') { sc.ChangeState(SCE_SH_STRING); QuoteStack.Start(sc.ch, BASH_DELIM_LSTRING); } else if (sc.ch == '(') { sc.ChangeState(SCE_SH_BACKTICKS); QuoteStack.Start(sc.ch, BASH_DELIM_COMMAND); } else if (sc.ch == '`') { // $` seen in a configure script, valid? sc.ChangeState(SCE_SH_BACKTICKS); QuoteStack.Start(sc.ch, BASH_DELIM_BACKTICK); } else { continue; // scalar has no delimiter pair } } else if (sc.Match('<', '<')) { sc.SetState(SCE_SH_HERE_DELIM); HereDoc.State = 0; if (sc.GetRelative(2) == '-') { // <<- indent case HereDoc.Indent = true; sc.Forward(); } else { HereDoc.Indent = false; } } else if (sc.ch == '-' && // one-char file test operators setSingleCharOp.Contains(sc.chNext) && !setWord.Contains(sc.GetRelative(2)) && IsASpace(sc.chPrev)) { sc.SetState(SCE_SH_WORD); sc.Forward(); } else if (setBashOperator.Contains(sc.ch)) { char s[10]; bool isCmdDelim = false; sc.SetState(SCE_SH_OPERATOR); // globs have no whitespace, do not appear in arithmetic expressions if (cmdState != BASH_CMD_ARITH && sc.ch == '(' && sc.chNext != '(') { int i = GlobScan(sc); if (i > 1) { sc.SetState(SCE_SH_IDENTIFIER); sc.Forward(i); continue; } } // handle opening delimiters for test/arithmetic expressions - ((,[[,[ if (cmdState == BASH_CMD_START || cmdState == BASH_CMD_BODY) { if (sc.Match('(', '(')) { cmdState = BASH_CMD_ARITH; sc.Forward(); } else if (sc.Match('[', '[') && IsASpace(sc.GetRelative(2))) { cmdState = BASH_CMD_TEST; testExprType = 1; sc.Forward(); } else if (sc.ch == '[' && IsASpace(sc.chNext)) { cmdState = BASH_CMD_TEST; testExprType = 2; } } // special state -- for ((x;y;z)) in ... looping if (cmdState == BASH_CMD_WORD && sc.Match('(', '(')) { cmdState = BASH_CMD_ARITH; sc.Forward(); continue; } // handle command delimiters in command START|BODY|WORD state, also TEST if 'test' if (cmdState == BASH_CMD_START || cmdState == BASH_CMD_BODY || cmdState == BASH_CMD_WORD || (cmdState == BASH_CMD_TEST && testExprType == 0)) { s[0] = static_cast<char>(sc.ch); if (setBashOperator.Contains(sc.chNext)) { s[1] = static_cast<char>(sc.chNext); s[2] = '\0'; isCmdDelim = cmdDelimiter.InList(s); if (isCmdDelim) sc.Forward(); } if (!isCmdDelim) { s[1] = '\0'; isCmdDelim = cmdDelimiter.InList(s); } if (isCmdDelim) { cmdState = BASH_CMD_DELIM; continue; } } // handle closing delimiters for test/arithmetic expressions - )),]],] if (cmdState == BASH_CMD_ARITH && sc.Match(')', ')')) { cmdState = BASH_CMD_BODY; sc.Forward(); } else if (cmdState == BASH_CMD_TEST && IsASpace(sc.chPrev)) { if (sc.Match(']', ']') && testExprType == 1) { sc.Forward(); cmdState = BASH_CMD_BODY; } else if (sc.ch == ']' && testExprType == 2) { cmdState = BASH_CMD_BODY; } } } }// sc.state } sc.Complete(); if (sc.state == SCE_SH_HERE_Q) { styler.ChangeLexerState(sc.currentPos, styler.Length()); } sc.Complete(); }
static void ColouriseMatlabOctaveDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler, bool (*IsCommentChar)(int)) { WordList &keywords = *keywordlists[0]; styler.StartAt(startPos); // boolean for when the ' is allowed to be transpose vs the start/end // of a string bool transpose = false; // approximate position of first non space character in a line int nonSpaceColumn = -1; // approximate column position of the current character in a line int column = 0; // use the line state of each line to store the block comment depth int curLine = styler.GetLine(startPos); int commentDepth = curLine > 0 ? styler.GetLineState(curLine-1) : 0; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward(), column++) { if(sc.atLineStart) { // set the line state to the current commentDepth curLine = styler.GetLine(sc.currentPos); styler.SetLineState(curLine, commentDepth); // reset the column to 0, nonSpace to -1 (not set) column = 0; nonSpaceColumn = -1; } // save the column position of first non space character in a line if((nonSpaceColumn == -1) && (! IsASpace(sc.ch))) { nonSpaceColumn = column; } // check for end of states if (sc.state == SCE_MATLAB_OPERATOR) { if (sc.chPrev == '.') { if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\' || sc.ch == '^') { sc.ForwardSetState(SCE_MATLAB_DEFAULT); transpose = false; } else if (sc.ch == '\'') { sc.ForwardSetState(SCE_MATLAB_DEFAULT); transpose = true; } else if(sc.ch == '.' && sc.chNext == '.') { // we werent an operator, but a '...' sc.ChangeState(SCE_MATLAB_COMMENT); transpose = false; } else { sc.SetState(SCE_MATLAB_DEFAULT); } } else { sc.SetState(SCE_MATLAB_DEFAULT); } } else if (sc.state == SCE_MATLAB_KEYWORD) { if (!isalnum(sc.ch) && sc.ch != '_') { char s[100]; sc.GetCurrentLowered(s, sizeof(s)); if (keywords.InList(s)) { sc.SetState(SCE_MATLAB_DEFAULT); transpose = false; } else { sc.ChangeState(SCE_MATLAB_IDENTIFIER); sc.SetState(SCE_MATLAB_DEFAULT); transpose = true; } } } else if (sc.state == SCE_MATLAB_NUMBER) { if (!isdigit(sc.ch) && sc.ch != '.' && !(sc.ch == 'e' || sc.ch == 'E') && !((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E'))) { sc.SetState(SCE_MATLAB_DEFAULT); transpose = true; } } else if (sc.state == SCE_MATLAB_STRING) { if (sc.ch == '\'') { if (sc.chNext == '\'') { sc.Forward(); } else { sc.ForwardSetState(SCE_MATLAB_DEFAULT); } } } else if (sc.state == SCE_MATLAB_DOUBLEQUOTESTRING) { if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\"') { sc.ForwardSetState(SCE_MATLAB_DEFAULT); } } else if (sc.state == SCE_MATLAB_COMMAND) { if (sc.atLineEnd) { sc.SetState(SCE_MATLAB_DEFAULT); transpose = false; } } else if (sc.state == SCE_MATLAB_COMMENT) { // end or start of a nested a block comment? if( IsCommentChar(sc.ch) && sc.chNext == '}' && nonSpaceColumn == column) { if(commentDepth > 0) commentDepth --; curLine = styler.GetLine(sc.currentPos); styler.SetLineState(curLine, commentDepth); sc.Forward(); if (commentDepth == 0) { sc.ForwardSetState(SCE_D_DEFAULT); transpose = false; } } else if( IsCommentChar(sc.ch) && sc.chNext == '{' && nonSpaceColumn == column) { commentDepth ++; curLine = styler.GetLine(sc.currentPos); styler.SetLineState(curLine, commentDepth); sc.Forward(); transpose = false; } else if(commentDepth == 0) { // single line comment if (sc.atLineEnd || sc.ch == '\r' || sc.ch == '\n') { sc.SetState(SCE_MATLAB_DEFAULT); transpose = false; } } } // check start of a new state if (sc.state == SCE_MATLAB_DEFAULT) { if (IsCommentChar(sc.ch)) { // ncrement depth if we are a block comment if(sc.chNext == '{' && nonSpaceColumn == column) commentDepth ++; curLine = styler.GetLine(sc.currentPos); styler.SetLineState(curLine, commentDepth); sc.SetState(SCE_MATLAB_COMMENT); } else if (sc.ch == '!' && sc.chNext != '=' ) { sc.SetState(SCE_MATLAB_COMMAND); } else if (sc.ch == '\'') { if (transpose) { sc.SetState(SCE_MATLAB_OPERATOR); } else { sc.SetState(SCE_MATLAB_STRING); } } else if (sc.ch == '"') { sc.SetState(SCE_MATLAB_DOUBLEQUOTESTRING); } else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) { sc.SetState(SCE_MATLAB_NUMBER); } else if (isalpha(sc.ch)) { sc.SetState(SCE_MATLAB_KEYWORD); } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '\\') { if (sc.ch == ')' || sc.ch == ']') { transpose = true; } else { transpose = false; } sc.SetState(SCE_MATLAB_OPERATOR); } else { transpose = false; } } } sc.Complete(); }
static void ColouriseTADS3Doc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { int visibleChars = 0; int bracketLevel = 0; int lineState = 0; unsigned int endPos = startPos + length; int lineCurrent = styler.GetLine(startPos); if (lineCurrent > 0) { lineState = styler.GetLineState(lineCurrent-1); } StyleContext sc(startPos, length, initStyle, styler); while (sc.More()) { if (IsEOL(sc.ch, sc.chNext)) { styler.SetLineState(lineCurrent, lineState); lineCurrent++; visibleChars = 0; sc.Forward(); if (sc.ch == '\n') { sc.Forward(); } } switch(sc.state) { case SCE_T3_PREPROCESSOR: case SCE_T3_LINE_COMMENT: ColouriseToEndOfLine(sc, sc.state, lineState&T3_INT_EXPRESSION ? SCE_T3_X_DEFAULT : SCE_T3_DEFAULT); break; case SCE_T3_S_STRING: case SCE_T3_D_STRING: case SCE_T3_X_STRING: ColouriseTADS3String(sc, lineState); visibleChars++; break; case SCE_T3_MSG_PARAM: ColouriseTADS3MsgParam(sc, lineState); break; case SCE_T3_LIB_DIRECTIVE: ColouriseTADS3LibDirective(sc, lineState); break; case SCE_T3_HTML_DEFAULT: ColouriseTADS3HTMLTag(sc, lineState); break; case SCE_T3_HTML_STRING: ColouriseTADSHTMLString(sc, lineState); break; case SCE_T3_BLOCK_COMMENT: ColouriseTADS3Comment(sc, lineState&T3_INT_EXPRESSION ? SCE_T3_X_DEFAULT : SCE_T3_DEFAULT); break; case SCE_T3_DEFAULT: case SCE_T3_X_DEFAULT: if (IsASpaceOrTab(sc.ch)) { sc.Forward(); } else if (sc.ch == '#' && visibleChars == 0) { ColouriseToEndOfLine(sc, SCE_T3_PREPROCESSOR, sc.state); } else if (sc.Match('/', '*')) { ColouriseTADS3Comment(sc, sc.state); visibleChars++; } else if (sc.Match('/', '/')) { ColouriseToEndOfLine(sc, SCE_T3_LINE_COMMENT, sc.state); } else if (sc.ch == '"') { bracketLevel = 0; ColouriseTADS3String(sc, lineState); visibleChars++; } else if (sc.ch == '\'') { ColouriseTADS3String(sc, lineState); visibleChars++; } else if (sc.state == SCE_T3_X_DEFAULT && bracketLevel == 0 && sc.Match('>', '>')) { sc.Forward(2); sc.SetState(SCE_T3_D_STRING); if (lineState & T3_INT_EXPRESSION_IN_TAG) sc.SetState(SCE_T3_HTML_STRING); lineState &= ~(T3_SINGLE_QUOTE|T3_INT_EXPRESSION |T3_INT_EXPRESSION_IN_TAG); } else if (IsATADS3Operator(sc.ch)) { if (sc.state == SCE_T3_X_DEFAULT) { if (sc.ch == '(') { bracketLevel++; } else if (sc.ch == ')' && bracketLevel > 0) { bracketLevel--; } } ColouriseTADS3Operator(sc); visibleChars++; } else if (IsANumberStart(sc)) { ColouriseTADS3Number(sc); visibleChars++; } else if (IsAWordStart(sc.ch)) { ColouriseTADS3Keyword(sc, keywordlists, endPos); visibleChars++; } else if (sc.Match("...")) { sc.SetState(SCE_T3_IDENTIFIER); sc.Forward(3); sc.SetState(SCE_T3_DEFAULT); } else { sc.Forward(); visibleChars++; } break; default: sc.SetState(SCE_T3_DEFAULT); sc.Forward(); } } sc.Complete(); }