diff options
| -rw-r--r-- | src/LexEiffel.cxx | 70 | 
1 files changed, 52 insertions, 18 deletions
| diff --git a/src/LexEiffel.cxx b/src/LexEiffel.cxx index 68572db65..85f0649a6 100644 --- a/src/LexEiffel.cxx +++ b/src/LexEiffel.cxx @@ -20,7 +20,7 @@  #include "Scintilla.h"  #include "SciLexer.h" -inline bool isEiffelOperator(char ch) { +inline bool isEiffelOperator(unsigned int ch) {  	// '.' left out as it is used to make up numbers  	return ch == '*' || ch == '/' || ch == '\\' || ch == '-' || ch == '+' ||  	        ch == '(' || ch == ')' || ch == '=' || @@ -44,30 +44,62 @@ static void getRangeLowered(unsigned int start,  	s[i] = '\0';  } -class LexContext { +inline bool IsASpace(unsigned int ch) { +    return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d)); +} + +inline bool IsAWordChar(unsigned int  ch) { +	return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_'); +} + +inline bool IsAWordStart(unsigned int ch) { +	return (ch < 0x80) && (isalnum(ch) || ch == '_'); +} + +inline bool IsADigit(unsigned int ch) { +	return (ch >= '0') && (ch <= '9'); +} + +// All languages handled so far can treat all characters >= 0x80 as one class +// which just continues the current token or starts an identifier if in default. +// DBCS treated specially as the second character can be < 0x80 and hence  +// syntactically significant. UTF-8 avoids this as all trail bytes are >= 0x80 +class ColouriseContext {  	Accessor &styler;  	int lengthDoc;  	int currentPos; -	LexContext& operator=(const LexContext&) { +	ColouriseContext& operator=(const ColouriseContext&) {  		return *this;  	}  public:  	int state; -	char ch; -	char chNext; +	unsigned int chPrev; +	unsigned int ch; +	unsigned int chNext; -	LexContext(unsigned int startPos, int length, +	ColouriseContext(unsigned int startPos, int length,                          int initStyle, Accessor &styler_) :   		styler(styler_),  		lengthDoc(startPos + length),  		currentPos(startPos),   		state(initStyle),  +		chPrev(0),  		ch(0),   		chNext(0) {  		styler.StartAt(startPos);  		styler.StartSegment(startPos); -		ch = styler.SafeGetCharAt(currentPos); -		chNext = styler.SafeGetCharAt(currentPos+1); +		int pos = currentPos; +		ch = static_cast<unsigned char>(styler.SafeGetCharAt(pos)); +		if (styler.IsLeadByte(static_cast<char>(ch))) { +			pos++; +			ch = ch << 8; +			ch |= static_cast<unsigned char>(styler.SafeGetCharAt(pos)); +		} +		chNext = static_cast<unsigned char>(styler.SafeGetCharAt(pos+1)); +		if (styler.IsLeadByte(static_cast<char>(chNext))) { +			chNext = chNext << 8; +			chNext |= static_cast<unsigned char>(styler.SafeGetCharAt(pos+2)); +		}  	}  	void Complete() {  		styler.ColourTo(currentPos - 1, state); @@ -76,13 +108,15 @@ public:  		return currentPos <= lengthDoc;  	}  	void Forward() { +		chPrev = ch;  		currentPos++; -		ch = chNext; -		chNext = styler.SafeGetCharAt(currentPos + 1); -		if (styler.IsLeadByte(ch)) { +		if (ch >= 0x100)  			currentPos++; -			ch = chNext; -			chNext = styler.SafeGetCharAt(currentPos + 1); +		ch = chNext; +		chNext = static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+1)); +		if (styler.IsLeadByte(static_cast<char>(chNext))) { +			chNext = chNext << 8; +			chNext |= static_cast<unsigned char>(styler.SafeGetCharAt(currentPos + 2));  		}  	}  	void ChangeState(int state_) { @@ -105,7 +139,7 @@ static void ColouriseEiffelDoc(unsigned int startPos,  	WordList &keywords = *keywordlists[0]; -	LexContext lc(startPos, length, initStyle, styler); +	ColouriseContext lc(startPos, length, initStyle, styler);  	for (; lc.More(); lc.Forward()) { @@ -116,7 +150,7 @@ static void ColouriseEiffelDoc(unsigned int startPos,  		} else if (lc.state == SCE_EIFFEL_OPERATOR) {  			lc.SetState(SCE_EIFFEL_DEFAULT);  		} else if (lc.state == SCE_EIFFEL_WORD) { -			if (!iswordchar(lc.ch)) { +			if (!IsAWordChar(lc.ch)) {  				char s[100];  				lc.GetCurrentLowered(s, sizeof(s));  				if (!keywords.InList(s)) { @@ -125,7 +159,7 @@ static void ColouriseEiffelDoc(unsigned int startPos,  				lc.SetState(SCE_EIFFEL_DEFAULT);  			}  		} else if (lc.state == SCE_EIFFEL_NUMBER) { -			if (!iswordchar(lc.ch)) { +			if (!IsAWordChar(lc.ch)) {  				lc.SetState(SCE_EIFFEL_DEFAULT);  			}  		} else if (lc.state == SCE_EIFFEL_COMMENTLINE) { @@ -157,9 +191,9 @@ static void ColouriseEiffelDoc(unsigned int startPos,  				lc.SetState(SCE_EIFFEL_STRING);  			} else if (lc.ch == '\'') {  				lc.SetState(SCE_EIFFEL_CHARACTER); -			} else if (isdigit(lc.ch) || (lc.ch == '.')) { +			} else if (IsADigit(lc.ch) || (lc.ch == '.')) {  				lc.SetState(SCE_EIFFEL_NUMBER); -			} else if (iswordstart(lc.ch)) { +			} else if (IsAWordStart(lc.ch)) {  				lc.SetState(SCE_EIFFEL_WORD);  			} else if (isEiffelOperator(lc.ch)) {  				lc.SetState(SCE_EIFFEL_OPERATOR); | 
