diff options
Diffstat (limited to 'lexers/LexPerl.cxx')
| -rw-r--r-- | lexers/LexPerl.cxx | 708 | 
1 files changed, 355 insertions, 353 deletions
diff --git a/lexers/LexPerl.cxx b/lexers/LexPerl.cxx index a7776ad3f..310305fd5 100644 --- a/lexers/LexPerl.cxx +++ b/lexers/LexPerl.cxx @@ -69,8 +69,7 @@ using namespace Scintilla;  #define BACK_OPERATOR	1	// whitespace/comments are insignificant  #define BACK_KEYWORD	2	// operators/keywords are needed for disambiguation -static bool isPerlKeyword(unsigned int start, unsigned int end, WordList &keywords, LexAccessor &styler) -{ +static bool isPerlKeyword(unsigned int start, unsigned int end, WordList &keywords, LexAccessor &styler) {  	// old-style keyword matcher; needed because GetCurrent() needs  	// current segment to be committed, but we may abandon early...  	char s[100]; @@ -82,8 +81,7 @@ static bool isPerlKeyword(unsigned int start, unsigned int end, WordList &keywor  }  static int disambiguateBareword(LexAccessor &styler, unsigned int bk, unsigned int fw, -                                int backFlag, unsigned int backPos, unsigned int endPos) -{ +        int backFlag, unsigned int backPos, unsigned int endPos) {  	// identifiers are recognized by Perl as barewords under some  	// conditions, the following attempts to do the disambiguation  	// by looking backward and forward; result in 2 LSB @@ -104,25 +102,25 @@ static int disambiguateBareword(LexAccessor &styler, unsigned int bk, unsigned i  		// {bareword: possible variable spec  		brace = true;  	} else if ((ch == '&' && styler.SafeGetCharAt(bk - 1) != '&') -			// &bareword: subroutine call -			   || styler.Match(bk - 1, "->") -			// ->bareword: part of variable spec -			   || styler.Match(bk - 2, "sub")) { -			// sub bareword: subroutine declaration -			// (implied BACK_KEYWORD, no keywords end in 'sub'!) +	        // &bareword: subroutine call +	        || styler.Match(bk - 1, "->") +	        // ->bareword: part of variable spec +	        || styler.Match(bk - 2, "sub")) { +		// sub bareword: subroutine declaration +		// (implied BACK_KEYWORD, no keywords end in 'sub'!)  		result |= 1;  	}  	// next, scan forward after word past tab/spaces only;  	// if ch isn't one of '[{(,' we can skip the test  	if ((ch == '{' || ch == '(' || ch == '['|| ch == ',') -		&& fw < endPos) { +	        && fw < endPos) {  		while (ch = static_cast<unsigned char>(styler.SafeGetCharAt(fw)), -			   IsASpaceOrTab(ch) && fw < endPos) { +		        IsASpaceOrTab(ch) && fw < endPos) {  			fw++;  		}  		if ((ch == '}' && brace) -			// {bareword}: variable spec -			|| styler.Match(fw, "=>")) { +		        // {bareword}: variable spec +		        || styler.Match(fw, "=>")) {  			// [{(, bareword=>: hash literal  			result |= 2;  		} @@ -130,17 +128,15 @@ static int disambiguateBareword(LexAccessor &styler, unsigned int bk, unsigned i  	return result;  } -static void skipWhitespaceComment(LexAccessor &styler, unsigned int &p) -{ +static void skipWhitespaceComment(LexAccessor &styler, unsigned int &p) {  	// when backtracking, we need to skip whitespace and comments  	int style;  	while ((p > 0) && (style = styler.StyleAt(p), -		   style == SCE_PL_DEFAULT || style == SCE_PL_COMMENTLINE)) +	        style == SCE_PL_DEFAULT || style == SCE_PL_COMMENTLINE))  		p--;  } -static int styleBeforeBracePair(LexAccessor &styler, unsigned int bk) -{ +static int styleBeforeBracePair(LexAccessor &styler, unsigned int bk) {  	// backtrack to find open '{' corresponding to a '}', balanced  	// return significant style to be tested for '/' disambiguation  	int braceCount = 1; @@ -167,8 +163,7 @@ static int styleBeforeBracePair(LexAccessor &styler, unsigned int bk)  	return SCE_PL_DEFAULT;  } -static int styleCheckIdentifier(LexAccessor &styler, unsigned int bk) -{ +static int styleCheckIdentifier(LexAccessor &styler, unsigned int bk) {  	// backtrack to classify sub-styles of identifier under test  	// return sub-style to be tested for '/' disambiguation  	if (styler.SafeGetCharAt(bk) == '>')	// inputsymbol, like <foo> @@ -180,7 +175,7 @@ static int styleCheckIdentifier(LexAccessor &styler, unsigned int bk)  	while (bk > 0) {  		int bkstyle = styler.StyleAt(bk);  		if (bkstyle == SCE_PL_DEFAULT -			|| bkstyle == SCE_PL_COMMENTLINE) { +		        || bkstyle == SCE_PL_COMMENTLINE) {  			// skip whitespace, comments  		} else if (bkstyle == SCE_PL_OPERATOR) {  			// test for "->" and "::" @@ -193,8 +188,7 @@ static int styleCheckIdentifier(LexAccessor &styler, unsigned int bk)  	return 0;  } -static int inputsymbolScan(LexAccessor &styler, unsigned int pos, unsigned int endPos) -{ +static int inputsymbolScan(LexAccessor &styler, unsigned int pos, unsigned int endPos) {  	// looks forward for matching > on same line; a bit ugly  	unsigned int fw = pos;  	while (++fw < endPos) { @@ -210,8 +204,7 @@ static int inputsymbolScan(LexAccessor &styler, unsigned int pos, unsigned int e  	return 0;  } -static int podLineScan(LexAccessor &styler, unsigned int &pos, unsigned int endPos) -{ +static int podLineScan(LexAccessor &styler, unsigned int &pos, unsigned int endPos) {  	// forward scan the current line to classify line for POD style  	int state = -1;  	while (pos <= endPos) { @@ -235,8 +228,7 @@ static int podLineScan(LexAccessor &styler, unsigned int &pos, unsigned int endP  	return state;  } -static bool styleCheckSubPrototype(LexAccessor &styler, unsigned int bk) -{ +static bool styleCheckSubPrototype(LexAccessor &styler, unsigned int bk) {  	// backtrack to identify if we're starting a subroutine prototype  	// we also need to ignore whitespace/comments:  	// 'sub' [whitespace|comment] <identifier> [whitespace|comment] @@ -249,13 +241,12 @@ static bool styleCheckSubPrototype(LexAccessor &styler, unsigned int bk)  	}  	skipWhitespaceComment(styler, bk);  	if (bk < 2 || styler.StyleAt(bk) != SCE_PL_WORD	// check "sub" keyword -		|| !styler.Match(bk - 2, "sub"))	// assume suffix is unique! +	        || !styler.Match(bk - 2, "sub"))	// assume suffix is unique!  		return false;  	return true;  } -static bool isMatch(const char *sref, char *s) -{ +static bool isMatch(const char *sref, char *s) {  	// match per-line delimiter - must kill trailing CR if CRLF  	int i = strlen(s);  	if (i != 0 && s[i - 1] == '\r') @@ -318,11 +309,11 @@ struct OptionsPerl {  	bool fold;  	bool foldComment;  	bool foldCompact; -	                         // Custom folding of POD and packages +	// Custom folding of POD and packages  	bool foldPOD;            // property fold.perl.pod -	                         // Enable folding Pod blocks when using the Perl lexer. +	// Enable folding Pod blocks when using the Perl lexer.  	bool foldPackage;        // property fold.perl.package -	                         // Enable folding packages when using the Perl lexer. +	// Enable folding packages when using the Perl lexer.  	bool foldCommentExplicit; @@ -336,7 +327,7 @@ struct OptionsPerl {  	}  }; -static const char * const perlWordListDesc[] = { +static const char *const perlWordListDesc[] = {  	"Keywords",  	0  }; @@ -350,13 +341,13 @@ struct OptionSetPerl : public OptionSet<OptionsPerl> {  		DefineProperty("fold.compact", &OptionsPerl::foldCompact);  		DefineProperty("fold.perl.pod", &OptionsPerl::foldPOD, -			"Set to 0 to disable folding Pod blocks when using the Perl lexer."); +		        "Set to 0 to disable folding Pod blocks when using the Perl lexer.");  		DefineProperty("fold.perl.package", &OptionsPerl::foldPackage, -			"Set to 0 to disable folding packages when using the Perl lexer."); +		        "Set to 0 to disable folding packages when using the Perl lexer.");  		DefineProperty("fold.perl.comment.explicit", &OptionsPerl::foldCommentExplicit, -			"Set to 0 to disable explicit folding."); +		        "Set to 0 to disable explicit folding.");  		DefineWordListSets(perlWordListDesc);  	} @@ -377,24 +368,24 @@ public:  	int SCI_METHOD Version() const {  		return lvOriginal;  	} -	const char * SCI_METHOD PropertyNames() { +	const char *SCI_METHOD PropertyNames() {  		return osPerl.PropertyNames();  	}  	int SCI_METHOD PropertyType(const char *name) {  		return osPerl.PropertyType(name);  	} -	const char * SCI_METHOD DescribeProperty(const char *name) { +	const char *SCI_METHOD DescribeProperty(const char *name) {  		return osPerl.DescribeProperty(name);  	}  	int SCI_METHOD PropertySet(const char *key, const char *val); -	const char * SCI_METHOD DescribeWordListSets() { +	const char *SCI_METHOD DescribeWordListSets() {  		return osPerl.DescribeWordListSets();  	}  	int SCI_METHOD WordListSet(int n, const char *wl);  	void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess);  	void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess); -	void * SCI_METHOD PrivateCall(int, void *) { +	void *SCI_METHOD PrivateCall(int, void *) {  		return 0;  	} @@ -464,9 +455,10 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle,  	class HereDocCls {	// Class to manage HERE doc sequence  	public: -		int State;		// 0: '<<' encountered -						// 1: collect the delimiter -						// 2: here doc text (lines after the delimiter) +		int State; +		// 0: '<<' encountered +		// 1: collect the delimiter +		// 2: here doc text (lines after the delimiter)  		int Quote;		// the char after '<<'  		bool Quoted;		// true if Quote in ('\'','"','`')  		int DelimiterLength;	// strlen(Delimiter) @@ -490,7 +482,7 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle,  	HereDocCls HereDoc;		// TODO: FIFO for stacked here-docs  	class QuoteCls {	// Class to manage quote pairs -		public: +	public:  		int Rep;  		int Count;  		int Up, Down; @@ -522,10 +514,10 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle,  	// Includes strings (may be multi-line), numbers (additional state), format  	// bodies, as well as POD sections.  	if (initStyle == SCE_PL_HERE_Q -		|| initStyle == SCE_PL_HERE_QQ -		|| initStyle == SCE_PL_HERE_QX -		|| initStyle == SCE_PL_FORMAT -	) { +	        || initStyle == SCE_PL_HERE_QQ +	        || initStyle == SCE_PL_HERE_QX +	        || initStyle == SCE_PL_FORMAT +	   ) {  		int delim = (initStyle == SCE_PL_FORMAT) ? SCE_PL_FORMAT_IDENT:SCE_PL_HERE_DELIM;  		while ((startPos > 1) && (styler.StyleAt(startPos) != delim)) {  			startPos--; @@ -534,27 +526,27 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle,  		initStyle = styler.StyleAt(startPos - 1);  	}  	if (initStyle == SCE_PL_STRING_Q -		|| initStyle == SCE_PL_STRING_QQ -		|| initStyle == SCE_PL_STRING_QX -		|| initStyle == SCE_PL_STRING_QR -		|| initStyle == SCE_PL_STRING_QW -		|| initStyle == SCE_PL_REGEX -		|| initStyle == SCE_PL_REGSUBST -		|| initStyle == SCE_PL_STRING -		|| initStyle == SCE_PL_BACKTICKS -		|| initStyle == SCE_PL_CHARACTER -		|| initStyle == SCE_PL_NUMBER -		|| initStyle == SCE_PL_IDENTIFIER -		|| initStyle == SCE_PL_ERROR -		|| initStyle == SCE_PL_SUB_PROTOTYPE -	) { +	        || initStyle == SCE_PL_STRING_QQ +	        || initStyle == SCE_PL_STRING_QX +	        || initStyle == SCE_PL_STRING_QR +	        || initStyle == SCE_PL_STRING_QW +	        || initStyle == SCE_PL_REGEX +	        || initStyle == SCE_PL_REGSUBST +	        || initStyle == SCE_PL_STRING +	        || initStyle == SCE_PL_BACKTICKS +	        || initStyle == SCE_PL_CHARACTER +	        || initStyle == SCE_PL_NUMBER +	        || initStyle == SCE_PL_IDENTIFIER +	        || initStyle == SCE_PL_ERROR +	        || initStyle == SCE_PL_SUB_PROTOTYPE +	   ) {  		while ((startPos > 1) && (styler.StyleAt(startPos - 1) == initStyle)) {  			startPos--;  		}  		initStyle = SCE_PL_DEFAULT;  	} else if (initStyle == SCE_PL_POD -			   || initStyle == SCE_PL_POD_VERB -	) { +	        || initStyle == SCE_PL_POD_VERB +	          ) {  		// POD backtracking finds preceeding blank lines and goes back past them  		int ln = styler.GetLine(startPos);  		if (ln > 0) { @@ -592,187 +584,187 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle,  		// Determine if the current state should terminate.  		switch (sc.state) { -			case SCE_PL_OPERATOR: +		case SCE_PL_OPERATOR: +			sc.SetState(SCE_PL_DEFAULT); +			backFlag = BACK_OPERATOR; +			backPos = sc.currentPos; +			break; +		case SCE_PL_IDENTIFIER:		// identifier, bareword, inputsymbol +			if ((!setWord.Contains(sc.ch) && sc.ch != '\'') +			        || sc.Match('.', '.') +			        || sc.chPrev == '>') {	// end of inputsymbol  				sc.SetState(SCE_PL_DEFAULT); -				backFlag = BACK_OPERATOR; -				backPos = sc.currentPos; -				break; -			case SCE_PL_IDENTIFIER:		// identifier, bareword, inputsymbol -				if ((!setWord.Contains(sc.ch) && sc.ch != '\'') -					|| sc.Match('.', '.') -					|| sc.chPrev == '>') {	// end of inputsymbol -					sc.SetState(SCE_PL_DEFAULT); -				} -				break; -			case SCE_PL_WORD:		// keyword, plus special cases -				if (!setWord.Contains(sc.ch)) { -					char s[100]; -					sc.GetCurrent(s, sizeof(s)); -					if ((strcmp(s, "__DATA__") == 0) || (strcmp(s, "__END__") == 0)) { -						sc.ChangeState(SCE_PL_DATASECTION); +			} +			break; +		case SCE_PL_WORD:		// keyword, plus special cases +			if (!setWord.Contains(sc.ch)) { +				char s[100]; +				sc.GetCurrent(s, sizeof(s)); +				if ((strcmp(s, "__DATA__") == 0) || (strcmp(s, "__END__") == 0)) { +					sc.ChangeState(SCE_PL_DATASECTION); +				} else { +					if ((strcmp(s, "format") == 0)) { +						sc.SetState(SCE_PL_FORMAT_IDENT); +						HereDoc.State = 0;  					} else { -						if ((strcmp(s, "format") == 0)) { -							sc.SetState(SCE_PL_FORMAT_IDENT); -							HereDoc.State = 0; -						} else { -							sc.SetState(SCE_PL_DEFAULT); -						} -						backFlag = BACK_KEYWORD; -						backPos = sc.currentPos; +						sc.SetState(SCE_PL_DEFAULT);  					} +					backFlag = BACK_KEYWORD; +					backPos = sc.currentPos;  				} -				break; -			case SCE_PL_SCALAR: -			case SCE_PL_ARRAY: -			case SCE_PL_HASH: -			case SCE_PL_SYMBOLTABLE: -				if (sc.Match(':', ':')) {	// skip :: +			} +			break; +		case SCE_PL_SCALAR: +		case SCE_PL_ARRAY: +		case SCE_PL_HASH: +		case SCE_PL_SYMBOLTABLE: +			if (sc.Match(':', ':')) {	// skip :: +				sc.Forward(); +			} else if (!setVar.Contains(sc.ch)) { +				if (sc.LengthCurrent() == 1) { +					// Special variable: $(, $_ etc.  					sc.Forward(); -				} else if (!setVar.Contains(sc.ch)) { -					if (sc.LengthCurrent() == 1) { -						// Special variable: $(, $_ etc. -						sc.Forward(); -					} -					sc.SetState(SCE_PL_DEFAULT);  				} -				break; -			case SCE_PL_NUMBER: -				// if no early break, number style is terminated at "(go through)" -				if (sc.ch == '.') { -					if (sc.chNext == '.') { -						// double dot is always an operator (go through) -					} else if (numState <= PERLNUM_FLOAT_EXP) { -						// non-decimal number or float exponent, consume next dot -						sc.SetState(SCE_PL_OPERATOR); -						break; -					} else {	// decimal or vectors allows dots -						dotCount++; -						if (numState == PERLNUM_DECIMAL) { -							if (dotCount <= 1)	// number with one dot in it -								break; -							if (IsADigit(sc.chNext)) {	// really a vector -								numState = PERLNUM_VECTOR; -								break; -							} -							// number then dot (go through) -						} else if (IsADigit(sc.chNext))	// vectors -							break; -						// vector then dot (go through) -					} -				} else if (sc.ch == '_') { -					// permissive underscoring for number and vector literals +				sc.SetState(SCE_PL_DEFAULT); +			} +			break; +		case SCE_PL_NUMBER: +			// if no early break, number style is terminated at "(go through)" +			if (sc.ch == '.') { +				if (sc.chNext == '.') { +					// double dot is always an operator (go through) +				} else if (numState <= PERLNUM_FLOAT_EXP) { +					// non-decimal number or float exponent, consume next dot +					sc.SetState(SCE_PL_OPERATOR);  					break; -				} else if (numState == PERLNUM_DECIMAL) { -					if (sc.ch == 'E' || sc.ch == 'e') {	// exponent, sign -						numState = PERLNUM_FLOAT_EXP; -						if (sc.chNext == '+' || sc.chNext == '-') { -							sc.Forward(); +				} else {	// decimal or vectors allows dots +					dotCount++; +					if (numState == PERLNUM_DECIMAL) { +						if (dotCount <= 1)	// number with one dot in it +							break; +						if (IsADigit(sc.chNext)) {	// really a vector +							numState = PERLNUM_VECTOR; +							break;  						} +						// number then dot (go through) +					} else if (IsADigit(sc.chNext))	// vectors  						break; -					} else if (IsADigit(sc.ch)) -						break; -					// number then word (go through) -				} else if (numState == PERLNUM_HEX) { -					if (IsADigit(sc.ch, 16)) -						break; -				} else if (numState == PERLNUM_VECTOR || numState == PERLNUM_V_VECTOR) { -					if (IsADigit(sc.ch))	// vector -						break; -					if (setWord.Contains(sc.ch) && dotCount == 0) {	// change to word -						sc.ChangeState(SCE_PL_IDENTIFIER); -						break; -					} -					// vector then word (go through) -				} else if (IsADigit(sc.ch)) { -					if (numState == PERLNUM_FLOAT_EXP) { -						break; -					} else if (numState == PERLNUM_OCTAL) { -						if (sc.ch <= '7') break; -					} else if (numState == PERLNUM_BINARY) { -						if (sc.ch <= '1') break; +					// vector then dot (go through) +				} +			} else if (sc.ch == '_') { +				// permissive underscoring for number and vector literals +				break; +			} else if (numState == PERLNUM_DECIMAL) { +				if (sc.ch == 'E' || sc.ch == 'e') {	// exponent, sign +					numState = PERLNUM_FLOAT_EXP; +					if (sc.chNext == '+' || sc.chNext == '-') { +						sc.Forward();  					} -					// mark invalid octal, binary numbers (go through) -					numState = PERLNUM_BAD; +					break; +				} else if (IsADigit(sc.ch)) +					break; +				// number then word (go through) +			} else if (numState == PERLNUM_HEX) { +				if (IsADigit(sc.ch, 16)) +					break; +			} else if (numState == PERLNUM_VECTOR || numState == PERLNUM_V_VECTOR) { +				if (IsADigit(sc.ch))	// vector +					break; +				if (setWord.Contains(sc.ch) && dotCount == 0) {	// change to word +					sc.ChangeState(SCE_PL_IDENTIFIER);  					break;  				} -				// complete current number or vector -				sc.ChangeState(actualNumStyle(numState)); -				sc.SetState(SCE_PL_DEFAULT); -				break; -			case SCE_PL_COMMENTLINE: -				if (sc.atLineEnd) { -					sc.SetState(SCE_PL_DEFAULT); +				// vector then word (go through) +			} else if (IsADigit(sc.ch)) { +				if (numState == PERLNUM_FLOAT_EXP) { +					break; +				} else if (numState == PERLNUM_OCTAL) { +					if (sc.ch <= '7') break; +				} else if (numState == PERLNUM_BINARY) { +					if (sc.ch <= '1') break;  				} +				// mark invalid octal, binary numbers (go through) +				numState = PERLNUM_BAD;  				break; -			case SCE_PL_HERE_DELIM: -				if (HereDoc.State == 0) { // '<<' encountered -					int delim_ch = sc.chNext; -					int ws_skip = 0; -					HereDoc.State = 1;	// pre-init HERE doc class -					HereDoc.Quote = sc.chNext; -					HereDoc.Quoted = false; -					HereDoc.DelimiterLength = 0; -					HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0'; -					if (IsASpaceOrTab(delim_ch)) { -						// skip whitespace; legal only for quoted delimiters -						unsigned int i = sc.currentPos + 1; -						while ((i < endPos) && IsASpaceOrTab(delim_ch)) { -							i++; -							delim_ch = static_cast<unsigned char>(styler.SafeGetCharAt(i)); -						} -						ws_skip = i - sc.currentPos - 1; +			} +			// complete current number or vector +			sc.ChangeState(actualNumStyle(numState)); +			sc.SetState(SCE_PL_DEFAULT); +			break; +		case SCE_PL_COMMENTLINE: +			if (sc.atLineEnd) { +				sc.SetState(SCE_PL_DEFAULT); +			} +			break; +		case SCE_PL_HERE_DELIM: +			if (HereDoc.State == 0) { // '<<' encountered +				int delim_ch = sc.chNext; +				int ws_skip = 0; +				HereDoc.State = 1;	// pre-init HERE doc class +				HereDoc.Quote = sc.chNext; +				HereDoc.Quoted = false; +				HereDoc.DelimiterLength = 0; +				HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0'; +				if (IsASpaceOrTab(delim_ch)) { +					// skip whitespace; legal only for quoted delimiters +					unsigned int i = sc.currentPos + 1; +					while ((i < endPos) && IsASpaceOrTab(delim_ch)) { +						i++; +						delim_ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));  					} -					if (delim_ch == '\'' || delim_ch == '"' || delim_ch == '`') { -						// a quoted here-doc delimiter; skip any whitespace -						sc.Forward(ws_skip + 1); -						HereDoc.Quote = delim_ch; -						HereDoc.Quoted = true; -					} else if ((ws_skip == 0 && setNonHereDoc.Contains(sc.chNext)) -							   || ws_skip > 0) { -						// left shift << or <<= operator cases -						// restore position if operator -						sc.ChangeState(SCE_PL_OPERATOR); +					ws_skip = i - sc.currentPos - 1; +				} +				if (delim_ch == '\'' || delim_ch == '"' || delim_ch == '`') { +					// a quoted here-doc delimiter; skip any whitespace +					sc.Forward(ws_skip + 1); +					HereDoc.Quote = delim_ch; +					HereDoc.Quoted = true; +				} else if ((ws_skip == 0 && setNonHereDoc.Contains(sc.chNext)) +				        || ws_skip > 0) { +					// left shift << or <<= operator cases +					// restore position if operator +					sc.ChangeState(SCE_PL_OPERATOR); +					sc.ForwardSetState(SCE_PL_DEFAULT); +					backFlag = BACK_OPERATOR; +					backPos = sc.currentPos; +					HereDoc.State = 0; +				} else { +					// specially handle initial '\' for identifier +					if (ws_skip == 0 && HereDoc.Quote == '\\') +						sc.Forward(); +					// an unquoted here-doc delimiter, no special handling +					// (cannot be prefixed by spaces/tabs), or +					// symbols terminates; deprecated zero-length delimiter +				} +			} else if (HereDoc.State == 1) { // collect the delimiter +				backFlag = BACK_NONE; +				if (HereDoc.Quoted) { // a quoted here-doc delimiter +					if (sc.ch == HereDoc.Quote) { // closing quote => end of delimiter  						sc.ForwardSetState(SCE_PL_DEFAULT); -						backFlag = BACK_OPERATOR; -						backPos = sc.currentPos; -						HereDoc.State = 0; -					} else { -						// specially handle initial '\' for identifier -						if (ws_skip == 0 && HereDoc.Quote == '\\') +					} else if (!sc.atLineEnd) { +						if (sc.Match('\\', static_cast<char>(HereDoc.Quote))) { // escaped quote  							sc.Forward(); -						// an unquoted here-doc delimiter, no special handling -						// (cannot be prefixed by spaces/tabs), or -						// symbols terminates; deprecated zero-length delimiter -					} -				} else if (HereDoc.State == 1) { // collect the delimiter -					backFlag = BACK_NONE; -					if (HereDoc.Quoted) { // a quoted here-doc delimiter -						if (sc.ch == HereDoc.Quote) { // closing quote => end of delimiter -							sc.ForwardSetState(SCE_PL_DEFAULT); -						} else if (!sc.atLineEnd) { -							if (sc.Match('\\', static_cast<char>(HereDoc.Quote))) { // escaped quote -								sc.Forward(); -							} -							if (sc.ch != '\r') {	// skip CR if CRLF -								HereDoc.Append(sc.ch); -							}  						} -					} else { // an unquoted here-doc delimiter -						if (setHereDocDelim.Contains(sc.ch)) { +						if (sc.ch != '\r') {	// skip CR if CRLF  							HereDoc.Append(sc.ch); -						} else { -							sc.SetState(SCE_PL_DEFAULT);  						}  					} -					if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) { -						sc.SetState(SCE_PL_ERROR); -						HereDoc.State = 0; +				} else { // an unquoted here-doc delimiter +					if (setHereDocDelim.Contains(sc.ch)) { +						HereDoc.Append(sc.ch); +					} else { +						sc.SetState(SCE_PL_DEFAULT);  					}  				} -				break; -			case SCE_PL_HERE_Q: -			case SCE_PL_HERE_QQ: -			case SCE_PL_HERE_QX: { +				if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) { +					sc.SetState(SCE_PL_ERROR); +					HereDoc.State = 0; +				} +			} +			break; +		case SCE_PL_HERE_Q: +		case SCE_PL_HERE_QQ: +		case SCE_PL_HERE_QX: {  				// also implies HereDoc.State == 2  				sc.Complete();  				while (!sc.atLineEnd) @@ -784,9 +776,10 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle,  					backFlag = BACK_NONE;  					HereDoc.State = 0;  				} -				} break; -			case SCE_PL_POD: -			case SCE_PL_POD_VERB: { +			} +			break; +		case SCE_PL_POD: +		case SCE_PL_POD_VERB: {  				unsigned int fw = sc.currentPos;  				int ln = styler.GetLine(fw);  				if (sc.atLineStart && sc.Match("=cut")) {	// end of POD @@ -814,86 +807,87 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle,  						pod = SCE_PL_POD;  				} else {  					if (pod == SCE_PL_POD_VERB	// still part of current paragraph -					    && (styler.GetLineState(ln - 1) == SCE_PL_POD)) { +					        && (styler.GetLineState(ln - 1) == SCE_PL_POD)) {  						pod = SCE_PL_POD;  						styler.SetLineState(ln, pod);  					} else if (pod == SCE_PL_POD -							   && (styler.GetLineState(ln - 1) == SCE_PL_POD_VERB)) { +					        && (styler.GetLineState(ln - 1) == SCE_PL_POD_VERB)) {  						pod = SCE_PL_POD_VERB;  						styler.SetLineState(ln, pod);  					}  					sc.SetState(pod);  				}  				sc.Forward(fw - sc.currentPos);	// commit style -				} break; -			case SCE_PL_REGEX: -			case SCE_PL_STRING_QR: -				if (Quote.Rep <= 0) { -					if (!setModifiers.Contains(sc.ch)) -						sc.SetState(SCE_PL_DEFAULT); -				} else if (!Quote.Up && !IsASpace(sc.ch)) { -					Quote.Open(sc.ch); -				} else if (sc.ch == '\\' && Quote.Up != '\\') { -					sc.Forward(); -				} else if (sc.ch == Quote.Down) { -					Quote.Count--; -					if (Quote.Count == 0) -						Quote.Rep--; -				} else if (sc.ch == Quote.Up) { -					Quote.Count++; -				} -				break; -			case SCE_PL_REGSUBST: -				if (Quote.Rep <= 0) { -					if (!setModifiers.Contains(sc.ch)) -						sc.SetState(SCE_PL_DEFAULT); -				} else if (!Quote.Up && !IsASpace(sc.ch)) { +			} +			break; +		case SCE_PL_REGEX: +		case SCE_PL_STRING_QR: +			if (Quote.Rep <= 0) { +				if (!setModifiers.Contains(sc.ch)) +					sc.SetState(SCE_PL_DEFAULT); +			} else if (!Quote.Up && !IsASpace(sc.ch)) { +				Quote.Open(sc.ch); +			} else if (sc.ch == '\\' && Quote.Up != '\\') { +				sc.Forward(); +			} else if (sc.ch == Quote.Down) { +				Quote.Count--; +				if (Quote.Count == 0) +					Quote.Rep--; +			} else if (sc.ch == Quote.Up) { +				Quote.Count++; +			} +			break; +		case SCE_PL_REGSUBST: +			if (Quote.Rep <= 0) { +				if (!setModifiers.Contains(sc.ch)) +					sc.SetState(SCE_PL_DEFAULT); +			} else if (!Quote.Up && !IsASpace(sc.ch)) { +				Quote.Open(sc.ch); +			} else if (sc.ch == '\\' && Quote.Up != '\\') { +				sc.Forward(); +			} else if (Quote.Count == 0 && Quote.Rep == 1) { +				// We matched something like s(...) or tr{...}, Perl 5.10 +				// appears to allow almost any character for use as the +				// next delimiters. Whitespace and comments are accepted in +				// between, but we'll limit to whitespace here. +				// For '#', if no whitespace in between, it's a delimiter. +				if (IsASpace(sc.ch)) { +					// Keep going +				} else if (sc.ch == '#' && IsASpaceOrTab(sc.chPrev)) { +					sc.SetState(SCE_PL_DEFAULT); +				} else {  					Quote.Open(sc.ch); -				} else if (sc.ch == '\\' && Quote.Up != '\\') { -					sc.Forward(); -				} else if (Quote.Count == 0 && Quote.Rep == 1) { -					// We matched something like s(...) or tr{...}, Perl 5.10 -					// appears to allow almost any character for use as the -					// next delimiters. Whitespace and comments are accepted in -					// between, but we'll limit to whitespace here. -					// For '#', if no whitespace in between, it's a delimiter. -					if (IsASpace(sc.ch)) { -						// Keep going -					} else if (sc.ch == '#' && IsASpaceOrTab(sc.chPrev)) { -						sc.SetState(SCE_PL_DEFAULT); -					} else { -						Quote.Open(sc.ch); -					} -				} else if (sc.ch == Quote.Down) { -					Quote.Count--; -					if (Quote.Count == 0) -						Quote.Rep--; -					if (Quote.Up == Quote.Down) -						Quote.Count++; -				} else if (sc.ch == Quote.Up) { -					Quote.Count++;  				} -				break; -			case SCE_PL_STRING_Q: -			case SCE_PL_STRING_QQ: -			case SCE_PL_STRING_QX: -			case SCE_PL_STRING_QW: -			case SCE_PL_STRING: -			case SCE_PL_CHARACTER: -			case SCE_PL_BACKTICKS: -				if (!Quote.Down && !IsASpace(sc.ch)) { -					Quote.Open(sc.ch); -				} else if (sc.ch == '\\' && Quote.Up != '\\') { -					sc.Forward(); -				} else if (sc.ch == Quote.Down) { -					Quote.Count--; -					if (Quote.Count == 0) -						sc.ForwardSetState(SCE_PL_DEFAULT); -				} else if (sc.ch == Quote.Up) { +			} else if (sc.ch == Quote.Down) { +				Quote.Count--; +				if (Quote.Count == 0) +					Quote.Rep--; +				if (Quote.Up == Quote.Down)  					Quote.Count++; -				} -				break; -			case SCE_PL_SUB_PROTOTYPE: { +			} else if (sc.ch == Quote.Up) { +				Quote.Count++; +			} +			break; +		case SCE_PL_STRING_Q: +		case SCE_PL_STRING_QQ: +		case SCE_PL_STRING_QX: +		case SCE_PL_STRING_QW: +		case SCE_PL_STRING: +		case SCE_PL_CHARACTER: +		case SCE_PL_BACKTICKS: +			if (!Quote.Down && !IsASpace(sc.ch)) { +				Quote.Open(sc.ch); +			} else if (sc.ch == '\\' && Quote.Up != '\\') { +				sc.Forward(); +			} else if (sc.ch == Quote.Down) { +				Quote.Count--; +				if (Quote.Count == 0) +					sc.ForwardSetState(SCE_PL_DEFAULT); +			} else if (sc.ch == Quote.Up) { +				Quote.Count++; +			} +			break; +		case SCE_PL_SUB_PROTOTYPE: {  				int i = 0;  				// forward scan; must all be valid proto characters  				while (setSubPrototype.Contains(sc.GetRelative(i))) @@ -906,8 +900,9 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle,  					sc.ChangeState(SCE_PL_OPERATOR);  					sc.SetState(SCE_PL_DEFAULT);  				} -				} break; -			case SCE_PL_FORMAT: { +			} +			break; +		case SCE_PL_FORMAT: {  				sc.Complete();  				while (!sc.atLineEnd)  					sc.Forward(); @@ -915,42 +910,43 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle,  				sc.GetCurrent(s, sizeof(s));  				if (isMatch(".", s))  					sc.SetState(SCE_PL_DEFAULT); -				} break; -			case SCE_PL_ERROR: -				break; +			} +			break; +		case SCE_PL_ERROR: +			break;  		}  		// Needed for specific continuation styles (one follows the other)  		switch (sc.state) {  			// continued from SCE_PL_WORD -			case SCE_PL_FORMAT_IDENT: -				// occupies HereDoc state 3 to avoid clashing with HERE docs -				if (IsASpaceOrTab(sc.ch)) {		// skip whitespace -					sc.ChangeState(SCE_PL_DEFAULT); -					while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd) +		case SCE_PL_FORMAT_IDENT: +			// occupies HereDoc state 3 to avoid clashing with HERE docs +			if (IsASpaceOrTab(sc.ch)) {		// skip whitespace +				sc.ChangeState(SCE_PL_DEFAULT); +				while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd) +					sc.Forward(); +				sc.SetState(SCE_PL_FORMAT_IDENT); +			} +			if (setFormatStart.Contains(sc.ch)) {	// identifier or '=' +				if (sc.ch != '=') { +					do {  						sc.Forward(); -					sc.SetState(SCE_PL_FORMAT_IDENT); +					} while (setFormat.Contains(sc.ch));  				} -				if (setFormatStart.Contains(sc.ch)) {	// identifier or '=' -					if (sc.ch != '=') { -						do { -							sc.Forward(); -						} while (setFormat.Contains(sc.ch)); -					} -					while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd) -						sc.Forward(); -					if (sc.ch == '=') { -						sc.ForwardSetState(SCE_PL_DEFAULT); -						HereDoc.State = 3; -					} else { -						// invalid indentifier; inexact fallback, but hey -						sc.ChangeState(SCE_PL_IDENTIFIER); -						sc.SetState(SCE_PL_DEFAULT); -					} +				while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd) +					sc.Forward(); +				if (sc.ch == '=') { +					sc.ForwardSetState(SCE_PL_DEFAULT); +					HereDoc.State = 3;  				} else { -					sc.ChangeState(SCE_PL_DEFAULT);	// invalid indentifier +					// invalid indentifier; inexact fallback, but hey +					sc.ChangeState(SCE_PL_IDENTIFIER); +					sc.SetState(SCE_PL_DEFAULT);  				} -				backFlag = BACK_NONE; -				break; +			} else { +				sc.ChangeState(SCE_PL_DEFAULT);	// invalid indentifier +			} +			backFlag = BACK_NONE; +			break;  		}  		// Must check end of HereDoc states here before default state is handled @@ -967,9 +963,15 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle,  					sc.ChangeState(SCE_PL_ERROR);  				}  				switch (HereDoc.Quote) { -					case '\'': st_new = SCE_PL_HERE_Q ; break; -					case '"' : st_new = SCE_PL_HERE_QQ; break; -					case '`' : st_new = SCE_PL_HERE_QX; break; +				case '\'': +					st_new = SCE_PL_HERE_Q ; +					break; +				case '"' : +					st_new = SCE_PL_HERE_QQ; +					break; +				case '`' : +					st_new = SCE_PL_HERE_QX; +					break;  				}  			} else {  				if (HereDoc.Quote == '\\') @@ -986,7 +988,7 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle,  		// Determine if a new state should be entered.  		if (sc.state == SCE_PL_DEFAULT) {  			if (IsADigit(sc.ch) || -				(IsADigit(sc.chNext) && (sc.ch == '.' || sc.ch == 'v'))) { +			        (IsADigit(sc.chNext) && (sc.ch == '.' || sc.ch == 'v'))) {  				sc.SetState(SCE_PL_NUMBER);  				backFlag = BACK_NONE;  				numState = PERLNUM_DECIMAL; @@ -1032,8 +1034,8 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle,  					sc.Forward();  					fw++;  				} else if (sc.ch == 'q' && setQDelim.Contains(sc.chNext) -						   && !setWord.Contains(sc.GetRelative(2))) { -					if      (sc.chNext == 'q') sc.ChangeState(SCE_PL_STRING_QQ); +				        && !setWord.Contains(sc.GetRelative(2))) { +					if (sc.chNext == 'q') sc.ChangeState(SCE_PL_STRING_QQ);  					else if (sc.chNext == 'x') sc.ChangeState(SCE_PL_STRING_QX);  					else if (sc.chNext == 'r') sc.ChangeState(SCE_PL_STRING_QR);  					else sc.ChangeState(SCE_PL_STRING_QW);	// sc.chNext == 'w' @@ -1041,8 +1043,8 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle,  					sc.Forward();  					fw++;  				} else if (sc.ch == 'x' && (sc.chNext == '=' ||	// repetition -						   !setWord.Contains(sc.chNext) || -						   (IsADigit(sc.chPrev) && IsADigit(sc.chNext)))) { +				        !setWord.Contains(sc.chNext) || +				        (IsADigit(sc.chPrev) && IsADigit(sc.chNext)))) {  					sc.ChangeState(SCE_PL_OPERATOR);  				}  				// if potentially a keyword, scan forward and grab word, then check @@ -1131,7 +1133,7 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle,  				} else {  					int bkstyle = styler.StyleAt(bk);  					int bkch = static_cast<unsigned char>(styler.SafeGetCharAt(bk)); -					switch(bkstyle) { +					switch (bkstyle) {  					case SCE_PL_OPERATOR:  						preferRE = true;  						if (bkch == ')' || bkch == ']') { @@ -1141,17 +1143,17 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle,  							// needed to test for variables like ${}, @{} etc.  							bkstyle = styleBeforeBracePair(styler, bk);  							if (bkstyle == SCE_PL_SCALAR -								|| bkstyle == SCE_PL_ARRAY -								|| bkstyle == SCE_PL_HASH -								|| bkstyle == SCE_PL_SYMBOLTABLE -								|| bkstyle == SCE_PL_OPERATOR) { +							        || bkstyle == SCE_PL_ARRAY +							        || bkstyle == SCE_PL_HASH +							        || bkstyle == SCE_PL_SYMBOLTABLE +							        || bkstyle == SCE_PL_OPERATOR) {  								preferRE = false;  							}  						} else if (bkch == '+' || bkch == '-') {  							if (bkch == static_cast<unsigned char>(styler.SafeGetCharAt(bk - 1)) -								&& bkch != static_cast<unsigned char>(styler.SafeGetCharAt(bk - 2))) -							// exceptions for operators: unary suffixes ++, -- -							preferRE = false; +							        && bkch != static_cast<unsigned char>(styler.SafeGetCharAt(bk - 2))) +								// exceptions for operators: unary suffixes ++, -- +								preferRE = false;  						}  						break;  					case SCE_PL_IDENTIFIER: @@ -1204,7 +1206,8 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle,  								preferRE = false;  						}  						break; -					// other styles uses the default, preferRE=false + +						// other styles uses the default, preferRE=false  					case SCE_PL_POD:  					case SCE_PL_HERE_Q:  					case SCE_PL_HERE_QQ: @@ -1278,15 +1281,15 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle,  					}  				}  			} else if (sc.ch == '='		// POD -					   && setPOD.Contains(sc.chNext) -					   && sc.atLineStart) { +			        && setPOD.Contains(sc.chNext) +			        && sc.atLineStart) {  				sc.SetState(SCE_PL_POD);  				backFlag = BACK_NONE;  			} else if (sc.ch == '-' && setWordStart.Contains(sc.chNext)) {	// extended '-' cases  				unsigned int bk = sc.currentPos;  				unsigned int fw = 2;  				if (setSingleCharOp.Contains(sc.chNext) &&	// file test operators -					!setWord.Contains(sc.GetRelative(2))) { +				        !setWord.Contains(sc.GetRelative(2))) {  					sc.SetState(SCE_PL_WORD);  				} else {  					// nominally a minus and bareword; find extent of bareword @@ -1323,9 +1326,9 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle,  	}  	sc.Complete();  	if (sc.state == SCE_PL_HERE_Q -		|| sc.state == SCE_PL_HERE_QQ -		|| sc.state == SCE_PL_HERE_QX -		|| sc.state == SCE_PL_FORMAT) { +	        || sc.state == SCE_PL_HERE_QQ +	        || sc.state == SCE_PL_HERE_QX +	        || sc.state == SCE_PL_FORMAT) {  		styler.ChangeLexerState(sc.currentPos, styler.Length());  	}  	sc.Complete(); @@ -1374,13 +1377,12 @@ void SCI_METHOD LexerPerl::Fold(unsigned int startPos, int length, int /* initSt  		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');  		bool atLineStart = ((chPrev == '\r') || (chPrev == '\n')) || i == 0;  		// Comment folding -		if (options.foldComment && atEOL && IsCommentLine(lineCurrent, styler)) -		{ +		if (options.foldComment && atEOL && IsCommentLine(lineCurrent, styler)) {  			if (!IsCommentLine(lineCurrent - 1, styler) -				&& IsCommentLine(lineCurrent + 1, styler)) +			        && IsCommentLine(lineCurrent + 1, styler))  				levelCurrent++;  			else if (IsCommentLine(lineCurrent - 1, styler) -					 && !IsCommentLine(lineCurrent + 1, styler)) +			        && !IsCommentLine(lineCurrent + 1, styler))  				levelCurrent--;  		}  		// {} [] block folding @@ -1425,7 +1427,7 @@ void SCI_METHOD LexerPerl::Fold(unsigned int startPos, int length, int /* initSt  		// package folding  		if (options.foldPackage && atLineStart) {  			if (IsPackageLine(lineCurrent, styler) -				&& !IsPackageLine(lineCurrent + 1, styler)) +			        && !IsPackageLine(lineCurrent + 1, styler))  				isPackageLine = true;  		}  | 
