diff options
| -rw-r--r-- | include/SciLexer.h | 1 | ||||
| -rw-r--r-- | include/Scintilla.iface | 1 | ||||
| -rw-r--r-- | lexers/LexCPP.cxx | 46 | 
3 files changed, 46 insertions, 2 deletions
| diff --git a/include/SciLexer.h b/include/SciLexer.h index 87dbfe510..118e3927e 100644 --- a/include/SciLexer.h +++ b/include/SciLexer.h @@ -151,6 +151,7 @@  #define SCE_C_COMMENTDOCKEYWORD 17  #define SCE_C_COMMENTDOCKEYWORDERROR 18  #define SCE_C_GLOBALCLASS 19 +#define SCE_C_STRINGRAW 20  #define SCE_D_DEFAULT 0  #define SCE_D_COMMENT 1  #define SCE_D_COMMENTLINE 2 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 2f28862a5..c78a0e6e5 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -2397,6 +2397,7 @@ val SCE_C_WORD2=16  val SCE_C_COMMENTDOCKEYWORD=17  val SCE_C_COMMENTDOCKEYWORDERROR=18  val SCE_C_GLOBALCLASS=19 +val SCE_C_STRINGRAW=20  # Lexical states for SCLEX_D  lex D=SCLEX_D SCE_D_  val SCE_D_DEFAULT=0 diff --git a/lexers/LexCPP.cxx b/lexers/LexCPP.cxx index cb021b244..5fc769f51 100644 --- a/lexers/LexCPP.cxx +++ b/lexers/LexCPP.cxx @@ -33,6 +33,7 @@  #include "CharacterSet.h"  #include "LexerModule.h"  #include "OptionSet.h" +#include "SparseState.h"  #ifdef SCI_NAMESPACE  using namespace Scintilla; @@ -317,6 +318,7 @@ class LexerCPP : public ILexer {  	std::map<std::string, std::string> preprocessorDefinitionsStart;  	OptionsCPP options;  	OptionSetCPP osCPP; +	SparseState<std::string> rawStringTerminators;  public:  	LexerCPP(bool caseSensitive_) :  		caseSensitive(caseSensitive_), @@ -503,6 +505,8 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,  	}  	const int maskActivity = 0x3F; +	std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1); +	bool changedRawStringState = rawStringTerminators.Delete(lineCurrent);  	int activitySet = preproc.IsInactive() ? 0x40 : 0; @@ -535,6 +539,10 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,  		if (sc.atLineEnd) {  			lineCurrent++;  			vlls.Add(lineCurrent, preproc); +			if (rawStringTerminator != "") { +				rawStringTerminators.Set(lineCurrent-1, rawStringTerminator); +				changedRawStringState = true; +			}  		}  		// Handle line continuation generically. @@ -578,6 +586,20 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,  					} else if (keywords4.InList(s)) {  						sc.ChangeState(SCE_C_GLOBALCLASS|activitySet);  					} +					if (sc.ch == '\"') { +						// Should check all s in "L|u|U|u8" "R" +						const bool raw = sc.chPrev == 'R'; +						size_t lenS = strlen(s); +						if (raw) +							s[lenS--] = '\0'; +						bool valid =  +							(lenS == 0) || +							((lenS == 1) && ((s[0] == 'L') || (s[0] == 'u') || (s[0] == 'U'))) || +							((lenS == 2) && (s[0] == 'u') && (s[1] == '8')); +						if (valid) { +							sc.ChangeState((raw ? SCE_C_STRINGRAW : SCE_C_STRING)|activitySet); +						} +					}  					sc.SetState(SCE_C_DEFAULT|activitySet);  				}  				break; @@ -662,6 +684,14 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,  					sc.ForwardSetState(SCE_C_DEFAULT|activitySet);  				}  				break; +			case SCE_C_STRINGRAW: +				if (sc.Match(rawStringTerminator.c_str())) { +					for (size_t termPos=rawStringTerminator.size(); termPos; termPos--) +						sc.Forward(); +					sc.SetState(SCE_C_DEFAULT|activitySet); +					rawStringTerminator = ""; +				} +				break;  			case SCE_C_CHARACTER:  				if (sc.atLineEnd) {  					sc.ChangeState(SCE_C_STRINGEOL|activitySet); @@ -753,7 +783,19 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,  				       || !FollowsPostfixOperator(sc, styler))) {  				sc.SetState(SCE_C_REGEX|activitySet);	// JavaScript's RegEx  			} else if (sc.ch == '\"') { -				sc.SetState(SCE_C_STRING|activitySet); +				if (sc.chPrev == 'R') { +					sc.SetState(SCE_C_STRINGRAW|activitySet); +					rawStringTerminator = ")"; +					for (int termPos = sc.currentPos + 1;;termPos++) { +						char chTerminator = styler.SafeGetCharAt(termPos, '('); +						if (chTerminator == '(') +							break; +						rawStringTerminator += chTerminator; +					} +					rawStringTerminator += '\"'; +				} else { +					sc.SetState(SCE_C_STRING|activitySet); +				}  				isIncludePreprocessor = false;	// ensure that '>' won't end the string  			} else if (isIncludePreprocessor && sc.ch == '<') {  				sc.SetState(SCE_C_STRING|activitySet); @@ -848,7 +890,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,  		}  		continuationLine = false;  	} -	if (definitionsChanged) +	if (definitionsChanged || changedRawStringState)  		styler.ChangeLexerState(startPos, startPos + length);  	sc.Complete();  } | 
