void SCI_METHOD LexerBaan::Lex()

in ext/scintilla/lexers/LexBaan.cxx [496:727]


void SCI_METHOD LexerBaan::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {

	if (initStyle == SCE_BAAN_STRINGEOL)	// Does not leak onto next line
		initStyle = SCE_BAAN_DEFAULT;

	int visibleChars = 0;
	bool lineHasDomain = false;
	bool lineHasFunction = false;
	bool lineHasPreProc = false;
	bool lineIgnoreString = false;
	bool lineHasDefines = false;
	bool numberIsHex = false;
	char word[1000];
	int wordlen = 0;

	std::string preProcessorTags[13] = { "#context_off", "#context_on",
		"#define", "#elif", "#else", "#endif",
		"#ident", "#if", "#ifdef", "#ifndef",
		"#include", "#pragma", "#undef" };
	LexAccessor styler(pAccess);
	StyleContext sc(startPos, length, initStyle, styler);

	for (; sc.More(); sc.Forward()) {

		// Determine if the current state should terminate.
		switch (sc.state) {
		case SCE_BAAN_OPERATOR:
			sc.SetState(SCE_BAAN_DEFAULT);
			break;
		case SCE_BAAN_NUMBER:
			if (IsASpaceOrTab(sc.ch) || sc.ch == '\r' || sc.ch == '\n' || IsAnOperator(sc.ch)) {
				sc.SetState(SCE_BAAN_DEFAULT);
			}
			else if ((numberIsHex && !(MakeLowerCase(sc.ch) == 'x' || MakeLowerCase(sc.ch) == 'e' ||
				IsADigit(sc.ch, 16) || sc.ch == '.' || sc.ch == '-' || sc.ch == '+')) ||
				(!numberIsHex && !(MakeLowerCase(sc.ch) == 'e' || IsADigit(sc.ch)
				|| sc.ch == '.' || sc.ch == '-' || sc.ch == '+'))) {
					// check '-' for possible -10e-5. Add '+' as well.
					numberIsHex = false;
					sc.ChangeState(SCE_BAAN_IDENTIFIER);
					sc.SetState(SCE_BAAN_DEFAULT);
			}
			break;
		case SCE_BAAN_IDENTIFIER:
			if (!IsAWordChar(sc.ch)) {
				char s[1000];
				char s1[1000];
				sc.GetCurrentLowered(s, sizeof(s));
				if (sc.ch == ':') {
					memcpy(s1, s, sizeof(s));
					s1[sc.LengthCurrent()] = sc.ch;
					s1[sc.LengthCurrent() + 1] = '\0';
				}
				if ((keywords.kwHasSection && (sc.ch == ':')) ? keywords.Contains(s1) : keywords.Contains(s)) {
					sc.ChangeState(SCE_BAAN_WORD);
					if (0 == strcmp(s, "domain")) {
						lineHasDomain = true;
					}
					else if (0 == strcmp(s, "function")) {
						lineHasFunction = true;
					}
				}
				else if (lineHasDomain) {
					sc.ChangeState(SCE_BAAN_DOMDEF);
					lineHasDomain = false;
				}
				else if (lineHasFunction) {
					sc.ChangeState(SCE_BAAN_FUNCDEF);
					lineHasFunction = false;
				}
				else if ((keywords2.kwHasSection && (sc.ch == ':')) ? keywords2.Contains(s1) : keywords2.Contains(s)) {
					sc.ChangeState(SCE_BAAN_WORD2);
				}
				else if ((keywords3.kwHasSection && (sc.ch == ':')) ? keywords3.Contains(s1) : keywords3.Contains(s)) {
					if (sc.ch == '(')
						sc.ChangeState(SCE_BAAN_WORD3);
					else
						sc.ChangeState(SCE_BAAN_IDENTIFIER);
				}
				else if ((keywords4.kwHasSection && (sc.ch == ':')) ? keywords4.Contains(s1) : keywords4.Contains(s)) {
					sc.ChangeState(SCE_BAAN_WORD4);
				}
				else if ((keywords5.kwHasSection && (sc.ch == ':')) ? keywords5.Contains(s1) : keywords5.Contains(s)) {
					sc.ChangeState(SCE_BAAN_WORD5);
				}
				else if ((keywords6.kwHasSection && (sc.ch == ':')) ? keywords6.Contains(s1) : keywords6.Contains(s)) {
					sc.ChangeState(SCE_BAAN_WORD6);
				}
				else if ((keywords7.kwHasSection && (sc.ch == ':')) ? keywords7.Contains(s1) : keywords7.Contains(s)) {
					sc.ChangeState(SCE_BAAN_WORD7);
				}
				else if ((keywords8.kwHasSection && (sc.ch == ':')) ? keywords8.Contains(s1) : keywords8.Contains(s)) {
					sc.ChangeState(SCE_BAAN_WORD8);
				}
				else if ((keywords9.kwHasSection && (sc.ch == ':')) ? keywords9.Contains(s1) : keywords9.Contains(s)) {
					sc.ChangeState(SCE_BAAN_WORD9);
				}
				else if (lineHasPreProc) {
					sc.ChangeState(SCE_BAAN_OBJECTDEF);
					lineHasPreProc = false;
				}
				else if (lineHasDefines) {
					sc.ChangeState(SCE_BAAN_DEFINEDEF);
					lineHasDefines = false;
				}
				else {
					int state = IsAnyOtherIdentifier(s, sc.LengthCurrent());
					if (state > 0) {
						sc.ChangeState(state);
					}
				}
				sc.SetState(SCE_BAAN_DEFAULT);
			}
			break;
		case SCE_BAAN_PREPROCESSOR:
			if (options.baanStylingWithinPreprocessor) {
				if (IsASpace(sc.ch) || IsAnOperator(sc.ch)) {
					sc.SetState(SCE_BAAN_DEFAULT);
				}
			}
			else {
				if (sc.atLineEnd && (sc.chNext != '^')) {
					sc.SetState(SCE_BAAN_DEFAULT);
				}
			}
			break;
		case SCE_BAAN_COMMENT:
			if (sc.ch == '\r' || sc.ch == '\n') {
				sc.SetState(SCE_BAAN_DEFAULT);
			}
			break;
		case SCE_BAAN_COMMENTDOC:
			if (sc.MatchIgnoreCase("enddllusage")) {
				for (unsigned int i = 0; i < 10; i++) {
					sc.Forward();
				}
				sc.ForwardSetState(SCE_BAAN_DEFAULT);
			}
			else if (sc.MatchIgnoreCase("endfunctionusage")) {
				for (unsigned int i = 0; i < 15; i++) {
					sc.Forward();
				}
				sc.ForwardSetState(SCE_BAAN_DEFAULT);
			}
			break;
		case SCE_BAAN_STRING:
			if (sc.ch == '\"') {
				sc.ForwardSetState(SCE_BAAN_DEFAULT);
			}
			else if ((sc.atLineEnd) && (sc.chNext != '^')) {
				sc.ChangeState(SCE_BAAN_STRINGEOL);
				sc.ForwardSetState(SCE_BAAN_DEFAULT);
				visibleChars = 0;
			}
			break;
		}

		// Determine if a new state should be entered.
		if (sc.state == SCE_BAAN_DEFAULT) {
			if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))
				|| ((sc.ch == '-' || sc.ch == '+') && (IsADigit(sc.chNext) || sc.chNext == '.'))
				|| (MakeLowerCase(sc.ch) == 'e' && (IsADigit(sc.chNext) || sc.chNext == '+' || sc.chNext == '-'))) {
				if ((sc.ch == '0' && MakeLowerCase(sc.chNext) == 'x') ||
					((sc.ch == '-' || sc.ch == '+') && sc.chNext == '0' && MakeLowerCase(sc.GetRelativeCharacter(2)) == 'x')){
					numberIsHex = true;
				}
				sc.SetState(SCE_BAAN_NUMBER);
			}
			else if (sc.MatchIgnoreCase("dllusage") || sc.MatchIgnoreCase("functionusage")) {
				sc.SetState(SCE_BAAN_COMMENTDOC);
				do {
					sc.Forward();
				} while ((!sc.atLineEnd) && sc.More());
			}
			else if (iswordstart(sc.ch)) {
				sc.SetState(SCE_BAAN_IDENTIFIER);
			}
			else if (sc.Match('|')) {
				sc.SetState(SCE_BAAN_COMMENT);
			}
			else if (sc.ch == '\"' && !(lineIgnoreString)) {
				sc.SetState(SCE_BAAN_STRING);
			}
			else if (sc.ch == '#' && visibleChars == 0) {
				// Preprocessor commands are alone on their line
				sc.SetState(SCE_BAAN_PREPROCESSOR);
				word[0] = '\0';
				wordlen = 0;
				while (sc.More() && !(IsASpace(sc.chNext) || IsAnOperator(sc.chNext))) {
					sc.Forward();
					wordlen++;
				}
				sc.GetCurrentLowered(word, sizeof(word));
				if (!sc.atLineEnd) {
					word[wordlen++] = sc.ch;
					word[wordlen++] = '\0';
				}
				if (!wordInArray(word, preProcessorTags, 13))
					// Colorise only preprocessor built in Baan.
					sc.ChangeState(SCE_BAAN_IDENTIFIER);
				if (strcmp(word, "#pragma") == 0 || strcmp(word, "#include") == 0) {
					lineHasPreProc = true;
					lineIgnoreString = true;
				}
				else if (strcmp(word, "#define") == 0 || strcmp(word, "#undef") == 0 ||
					strcmp(word, "#ifdef") == 0 || strcmp(word, "#if") == 0 || strcmp(word, "#ifndef") == 0) {
					lineHasDefines = true;
					lineIgnoreString = false;
				}
			}
			else if (IsAnOperator(static_cast<char>(sc.ch))) {
				sc.SetState(SCE_BAAN_OPERATOR);
			}
		}

		if (sc.atLineEnd) {
			// Reset states to begining of colourise so no surprises
			// if different sets of lines lexed.
			visibleChars = 0;
			lineHasDomain = false;
			lineHasFunction = false;
			lineHasPreProc = false;
			lineIgnoreString = false;
			lineHasDefines = false;
			numberIsHex = false;
		}
		if (!IsASpace(sc.ch)) {
			visibleChars++;
		}
	}
	sc.Complete();
}