aboutsummaryrefslogtreecommitdiffhomepage
path: root/lexers/LexCPP.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'lexers/LexCPP.cxx')
-rw-r--r--lexers/LexCPP.cxx46
1 files changed, 44 insertions, 2 deletions
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();
}