diff options
author | nyamatongwe <devnull@localhost> | 2011-02-10 13:18:41 +1100 |
---|---|---|
committer | nyamatongwe <devnull@localhost> | 2011-02-10 13:18:41 +1100 |
commit | ddb01581fee90cf458c463b7df49d79c44822d57 (patch) | |
tree | 679389a2a7d0ddd0e77c6095ae8c4a97b8e3a547 | |
parent | a9b43404324187f56e038bab245353ba2d9d850d (diff) | |
download | scintilla-mirror-ddb01581fee90cf458c463b7df49d79c44822d57.tar.gz |
New lexical class SCE_C_STRINGRAW for C++0x raw strings. Feature #3054629.
-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(); } |