diff options
Diffstat (limited to 'src/KeyWords.cxx')
| -rw-r--r-- | src/KeyWords.cxx | 2648 | 
1 files changed, 2648 insertions, 0 deletions
| diff --git a/src/KeyWords.cxx b/src/KeyWords.cxx new file mode 100644 index 000000000..7a6784f73 --- /dev/null +++ b/src/KeyWords.cxx @@ -0,0 +1,2648 @@ +// SciTE - Scintilla based Text Editor +// KeyWords.cxx - colourise for particular languages +// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org> +// The License.txt file describes the conditions under which this software may be distributed. + +#include <stdlib.h>  +#include <string.h>  +#include <ctype.h>  +#include <stdio.h>  +#include <stdarg.h>  + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +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}; + +typedef bool (*PFNIsCommentLeader)(StylingContext &styler, int pos, int len); + +static int IndentAmount(StylingContext &styler, int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0) { +	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 completely empty line or the start of a comment... +	if ( isspace(ch) || (pfnIsCommentLeader && (*pfnIsCommentLeader)(styler, pos, end-pos)) ) +		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 bool IsPyComment(StylingContext &styler, int pos, int len) { +	return len>0 && styler[pos]=='#'; +} + +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, IsPyComment); + +	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, IsPyComment); +			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_STRINGEOL) { +			if (ch != '\r' && ch != '\n') { +				styler.ColourSegment(startSeg, i - 1, state); +				state = SCE_P_DEFAULT; +				startSeg = i; +			} +		} +		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 = chNext == '#' ? SCE_P_COMMENTBLOCK : 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 = chNext == '#' ? SCE_P_COMMENTBLOCK : 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 || state == SCE_P_COMMENTBLOCK) { +				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 == '\r' || ch == '\n') && (chPrev != '\\')) { +					styler.ColourSegment(startSeg, i - 1, state); +					state = SCE_P_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_P_DEFAULT; +					startSeg = i + 1; +				} +			} else if (state == SCE_P_CHARACTER) { +				if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { +					styler.ColourSegment(startSeg, i - 1, state); +					state = SCE_P_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_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_COMMENTBLOCK) { +			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 void classifyWordHTJSA(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_HJA_WORD; +	if (wordIsNumber) +		chAttr = SCE_HJA_NUMBER; +	else { +		if (keywords.InList(s)) +			chAttr = SCE_HJA_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; +} + +static int classifyWordHTVBA(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_HBA_IDENTIFIER; +	if (wordIsNumber) +		chAttr = SCE_HBA_NUMBER; +	else { +		if (keywords.InList(s)) { +			chAttr = SCE_HBA_WORD; +			if (strcmp(s, "rem") == 0) +				chAttr = SCE_HBA_COMMENTLINE; +		} +	} +	styler.ColourTo(end, chAttr); +	if (chAttr == SCE_HBA_COMMENTLINE) +		return SCE_HBA_COMMENTLINE; +	else +		return SCE_HBA_DEFAULT; +} + +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'; +	} +	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); +} + +static void classifyWordHTPyA(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_HPA_IDENTIFIER; +	if (0 == strcmp(prevWord, "class")) +		chAttr = SCE_HPA_CLASSNAME; +	else if (0 == strcmp(prevWord, "def")) +		chAttr = SCE_HPA_DEFNAME; +	else if (wordIsNumber) +		chAttr = SCE_HPA_NUMBER; +	else if (keywords.InList(s)) +		chAttr = SCE_HPA_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, 127); +	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, 127); + +	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_HBA_START; +				else if  (defaultScript == eScriptPython) +				 	state = SCE_HPA_START; +				else +					state = SCE_HJA_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 +			if (state == SCE_HJA_WORD) { +				classifyWordHTJSA(styler.GetStartSegment(), i - 1, keywords2, styler); +			} else if (state == SCE_HBA_WORD) { +				classifyWordHTVBA(styler.GetStartSegment(), i - 1, keywords3, styler); +			} else if (state == SCE_HPA_WORD) { +				classifyWordHTPyA(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord); +			} else { +				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 (!isLineEnd(chNext)) { +				styler.ColourTo(i, state); +				state = SCE_HJ_DEFAULT; +			} +		} else if (state == SCE_HJA_DEFAULT || state == SCE_HJA_START) { +			if (iswordstart(ch)) { +				styler.ColourTo(i - 1, state); +				state = SCE_HJA_WORD; +			} else if (ch == '/' && chNext == '*') { +				styler.ColourTo(i - 1, state); +				if (chNext2 == '*') +					state = SCE_HJA_COMMENTDOC; +				else +					state = SCE_HJA_COMMENT; +			} else if (ch == '/' && chNext == '/') { +				styler.ColourTo(i - 1, state); +				state = SCE_HJA_COMMENTLINE; +			} else if (ch == '\"') { +				styler.ColourTo(i - 1, state); +				state = SCE_HJA_DOUBLESTRING; +			} else if (ch == '\'') { +				styler.ColourTo(i - 1, state); +				state = SCE_HJA_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_HJA_COMMENTLINE; +			} else if (isoperator(ch)) { +				styler.ColourTo(i - 1, state); +				styler.ColourTo(i, SCE_HJA_SYMBOLS); +				state = SCE_HJA_DEFAULT; +			} else if ((ch == ' ') || (ch == '\t')) { +				if (state == SCE_HJA_START) { +					styler.ColourTo(i - 1, state); +					state = SCE_HJA_DEFAULT; +				} +			} +		} else if (state == SCE_HJA_WORD) { +			if (!iswordchar(ch)) { +				classifyWordHTJSA(styler.GetStartSegment(), i - 1, keywords2, styler); +				//styler.ColourTo(i - 1, eHTJSKeyword); +				state = SCE_HJA_DEFAULT; +				if (ch == '/' && chNext == '*') { +					if (chNext2 == '*') +						state = SCE_HJA_COMMENTDOC; +					else +						state = SCE_HJA_COMMENT; +				} else if (ch == '/' && chNext == '/') { +					state = SCE_HJA_COMMENTLINE; +				} else if (ch == '\"') { +					state = SCE_HJA_DOUBLESTRING; +				} else if (ch == '\'') { +					state = SCE_HJA_SINGLESTRING; +				} else if (isoperator(ch)) { +					styler.ColourTo(i, SCE_HJA_SYMBOLS); +					state = SCE_HJA_DEFAULT; +				} +			} +		} else if (state == SCE_HJA_COMMENT) { +			if (ch == '/' && chPrev == '*') { +				state = SCE_HJA_DEFAULT; +				styler.ColourTo(i, SCE_HJA_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_HJA_COMMENTDOC) { +			if (ch == '/' && chPrev == '*') { +				state = SCE_HJA_DEFAULT; +				styler.ColourTo(i, SCE_HJA_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_HJA_COMMENTLINE) { +			if (ch == '\r' || ch == '\n') { +				styler.ColourTo(i - 1, SCE_HJA_COMMENTLINE); +				state = SCE_HJA_DEFAULT; +			} else if ((ch == '<') && (chNext == '/')) { +				// Common to hide end script tag in comment +				styler.ColourTo(i - 1, SCE_HJA_COMMENTLINE); +				state = SCE_H_TAGUNKNOWN; +			} +		} else if (state == SCE_HJA_DOUBLESTRING) { +			if (ch == '\\') { +				if (chNext == '\"' || chNext == '\'' || chNext == '\\') { +					i++; +				} +			} else if (ch == '\"') { +				styler.ColourTo(i, SCE_HJA_DOUBLESTRING); +				state = SCE_HJA_DEFAULT; +				i++; +				ch = chNext; +			} else if (isLineEnd(ch)) { +				styler.ColourTo(i-1, state); +				state = SCE_HJA_STRINGEOL; +			} +		} else if (state == SCE_HJA_SINGLESTRING) { +			if (ch == '\\') { +				if (chNext == '\"' || chNext == '\'' || chNext == '\\') { +					i++; +				} +			} else if (ch == '\'') { +				styler.ColourTo(i, SCE_HJA_SINGLESTRING); +				state = SCE_HJA_DEFAULT; +				i++; +				ch = chNext; +			} else if (isLineEnd(ch)) { +				styler.ColourTo(i-1, state); +				state = SCE_HJA_STRINGEOL; +			} +		} else if (state == SCE_HJA_STRINGEOL) { +			if (!isLineEnd(ch)) { +				styler.ColourTo(i - 1, state); +				state = SCE_HJA_DEFAULT; +			} else if (!isLineEnd(chNext)) { +				styler.ColourTo(i, state); +				state = SCE_HJA_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 (!isLineEnd(chNext)) { +				styler.ColourTo(i, state); +				state = SCE_HB_DEFAULT; +			} +		} else if (state == SCE_HBA_DEFAULT || state == SCE_HBA_START) { +			if (iswordstart(ch)) { +				styler.ColourTo(i - 1, state); +				state = SCE_HBA_WORD; +			} else if (ch == '\'') { +				styler.ColourTo(i - 1, state); +				state = SCE_HBA_COMMENTLINE; +			} else if (ch == '\"') { +				styler.ColourTo(i - 1, state); +				state = SCE_HBA_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_HBA_COMMENTLINE; +			} else if (isoperator(ch)) { +				styler.ColourTo(i - 1, state); +				styler.ColourTo(i, SCE_HBA_DEFAULT); +				state = SCE_HBA_DEFAULT; +			} else if ((ch == ' ') || (ch == '\t')) { +				if (state == SCE_HBA_START) { +					styler.ColourTo(i - 1, state); +					state = SCE_HBA_DEFAULT; +				} +			} +		} else if (state == SCE_HBA_WORD) { +			if (!iswordchar(ch)) { +				state = classifyWordHTVBA(styler.GetStartSegment(), i - 1, keywords3, styler); +				if (state == SCE_HBA_DEFAULT) { +					if (ch == '\"') { +						state = SCE_HBA_STRING; +					} else if (ch == '\'') { +						state = SCE_HBA_COMMENTLINE; +					} else if (isoperator(ch)) { +						styler.ColourTo(i, SCE_HBA_DEFAULT); +						state = SCE_HBA_DEFAULT; +					} +				} +			} +		} else if (state == SCE_HBA_STRING) { +			if (ch == '\"') { +				styler.ColourTo(i, state); +				state = SCE_HBA_DEFAULT; +				i++; +				ch = chNext; +			} else if (ch == '\r' || ch == '\n') { +				styler.ColourTo(i-1, state); +				state = SCE_HBA_STRINGEOL; +			} +		} else if (state == SCE_HBA_COMMENTLINE) { +			if (ch == '\r' || ch == '\n') { +				styler.ColourTo(i - 1, state); +				state = SCE_HBA_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_HBA_STRINGEOL) { +			if (!isLineEnd(ch)) { +				styler.ColourTo(i - 1, state); +				state = SCE_HBA_DEFAULT; +			} else if (!isLineEnd(chNext)) { +				styler.ColourTo(i, state); +				state = SCE_HBA_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; +			} +		} else if (state == SCE_HPA_DEFAULT || state == SCE_HPA_START) { +			if (iswordstart(ch)) { +				styler.ColourTo(i - 1, state); +				state = SCE_HPA_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_HPA_COMMENTLINE; +			} else if (ch == '#') { +				styler.ColourTo(i - 1, state); +				state = SCE_HPA_COMMENTLINE; +			} else if (ch == '\"') { +				styler.ColourTo(i - 1, state); +				if (chNext == '\"' && chNext2 == '\"') { +					i += 2; +					state = SCE_HPA_TRIPLEDOUBLE; +					ch = ' '; +					chPrev = ' '; +					chNext = styler.SafeGetCharAt(i + 1); +				} else { +					state = SCE_HPA_STRING; +				} +			} else if (ch == '\'') { +				styler.ColourTo(i - 1, state); +				if (chNext == '\'' && chNext2 == '\'') { +					i += 2; +					state = SCE_HPA_TRIPLE; +					ch = ' '; +					chPrev = ' '; +					chNext = styler.SafeGetCharAt(i + 1); +				} else { +					state = SCE_HPA_CHARACTER; +				} +			} else if (isoperator(ch)) { +				styler.ColourTo(i - 1, state); +				styler.ColourTo(i, SCE_HPA_OPERATOR); +			} else if ((ch == ' ') || (ch == '\t')) { +				if (state == SCE_HPA_START) { +					styler.ColourTo(i - 1, state); +					state = SCE_HPA_DEFAULT; +				} +			} +		} else if (state == SCE_HPA_WORD) { +			if (!iswordchar(ch)) { +				classifyWordHTPyA(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord); +				state = SCE_HPA_DEFAULT; +				if (ch == '#') { +					state = SCE_HPA_COMMENTLINE; +				} else if (ch == '\"') { +					if (chNext == '\"' && chNext2 == '\"') { +						i += 2; +						state = SCE_HPA_TRIPLEDOUBLE; +						ch = ' '; +						chPrev = ' '; +						chNext = styler.SafeGetCharAt(i + 1); +					} else { +						state = SCE_HPA_STRING; +					} +				} else if (ch == '\'') { +					if (chNext == '\'' && chNext2 == '\'') { +						i += 2; +						state = SCE_HPA_TRIPLE; +						ch = ' '; +						chPrev = ' '; +						chNext = styler.SafeGetCharAt(i + 1); +					} else { +						state = SCE_HPA_CHARACTER; +					} +				} else if (isoperator(ch)) { +					styler.ColourTo(i, SCE_HPA_OPERATOR); +				} +			} +		} else if (state == SCE_HPA_COMMENTLINE) { +			if (ch == '\r' || ch == '\n') { +				styler.ColourTo(i - 1, state); +				state = SCE_HPA_DEFAULT; +			} +		} else if (state == SCE_HPA_STRING) { +			if (ch == '\\') { +				if (chNext == '\"' || chNext == '\'' || chNext == '\\') { +					i++; +					ch = chNext; +					chNext = styler.SafeGetCharAt(i + 1); +				} +			} else if (ch == '\"') { +				styler.ColourTo(i, state); +				state = SCE_HPA_DEFAULT; +			} +		} else if (state == SCE_HPA_CHARACTER) { +			if (ch == '\\') { +				if (chNext == '\"' || chNext == '\'' || chNext == '\\') { +					i++; +					ch = chNext; +					chNext = styler.SafeGetCharAt(i + 1); +				} +			} else if (ch == '\'') { +				styler.ColourTo(i, state); +				state = SCE_HPA_DEFAULT; +			} +		} else if (state == SCE_HPA_TRIPLE) { +			if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') { +				styler.ColourTo(i, state); +				state = SCE_HPA_DEFAULT; +			} +		} else if (state == SCE_HPA_TRIPLEDOUBLE) { +			if (ch == '\"' && chPrev == '\"' && chPrev2 == '\"') { +				styler.ColourTo(i, state); +				state = SCE_HPA_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_HBA_DEFAULT) {    // One of the above succeeded +			if (ch == '\"') { +				state = SCE_HBA_STRING; +			} else if (ch == '\'') { +				state = SCE_HBA_COMMENTLINE; +			} else if (iswordstart(ch)) { +				state = SCE_HBA_WORD; +			} else if (isoperator(ch)) { +				styler.ColourTo(i, SCE_HBA_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); +			} +		} +		if (state == SCE_HJA_DEFAULT) {    // One of the above succeeded +			if (ch == '/' && chNext == '*') { +				if (styler.SafeGetCharAt(i + 2) == '*') +					state = SCE_HJA_COMMENTDOC; +				else +					state = SCE_HJA_COMMENT; +			} else if (ch == '/' && chNext == '/') { +				state = SCE_HJA_COMMENTLINE; +			} else if (ch == '\"') { +				state = SCE_HJA_DOUBLESTRING; +			} else if (ch == '\'') { +				state = SCE_HJA_SINGLESTRING; +			} else if (iswordstart(ch)) { +				state = SCE_HJA_WORD; +			} else if (isoperator(ch)) { +				styler.ColourTo(i, SCE_HJA_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); +		} +	} +} | 
