diff --git a/include/llvm/Support/Regex.h b/include/llvm/Support/Regex.h index 3d071bedbd8..21677dcfa16 100644 --- a/include/llvm/Support/Regex.h +++ b/include/llvm/Support/Regex.h @@ -81,6 +81,9 @@ namespace llvm { /// expression that matches Str and only Str. static bool isLiteralERE(StringRef Str); + /// \brief Turn String into a regex by escaping its special characters. + static std::string escape(StringRef String); + private: struct llvm_regex *preg; int error; diff --git a/lib/Support/Regex.cpp b/lib/Support/Regex.cpp index 54136418407..3e112df6c77 100644 --- a/lib/Support/Regex.cpp +++ b/lib/Support/Regex.cpp @@ -175,3 +175,32 @@ bool Regex::isLiteralERE(StringRef Str) { // regular expression specification. return Str.find_first_of("()^$|*+?.[]\\{}") == StringRef::npos; } + +std::string Regex::escape(StringRef String) { + std::string RegexStr; + + for (unsigned i = 0, e = String.size(); i != e; ++i) { + switch (String[i]) { + // These are the special characters matched in "p_ere_exp". + case '(': + case ')': + case '^': + case '$': + case '|': + case '*': + case '+': + case '?': + case '.': + case '[': + case '\\': + case '{': + RegexStr += '\\'; + // FALL THROUGH. + default: + RegexStr += String[i]; + break; + } + } + + return RegexStr; +} diff --git a/utils/FileCheck/FileCheck.cpp b/utils/FileCheck/FileCheck.cpp index 260bd6ce2d4..893e83d61c2 100644 --- a/utils/FileCheck/FileCheck.cpp +++ b/utils/FileCheck/FileCheck.cpp @@ -136,7 +136,6 @@ public: Check::CheckType getCheckTy() const { return CheckTy; } private: - static void AddFixedStringToRegEx(StringRef FixedStr, std::string &TheStr); bool AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM); void AddBackrefToRegEx(unsigned BackrefNum); @@ -314,40 +313,13 @@ bool Pattern::ParsePattern(StringRef PatternStr, // Find the end, which is the start of the next regex. size_t FixedMatchEnd = PatternStr.find("{{"); FixedMatchEnd = std::min(FixedMatchEnd, PatternStr.find("[[")); - AddFixedStringToRegEx(PatternStr.substr(0, FixedMatchEnd), RegExStr); + RegExStr += Regex::escape(PatternStr.substr(0, FixedMatchEnd)); PatternStr = PatternStr.substr(FixedMatchEnd); } return false; } -void Pattern::AddFixedStringToRegEx(StringRef FixedStr, std::string &TheStr) { - // Add the characters from FixedStr to the regex, escaping as needed. This - // avoids "leaning toothpicks" in common patterns. - for (unsigned i = 0, e = FixedStr.size(); i != e; ++i) { - switch (FixedStr[i]) { - // These are the special characters matched in "p_ere_exp". - case '(': - case ')': - case '^': - case '$': - case '|': - case '*': - case '+': - case '?': - case '.': - case '[': - case '\\': - case '{': - TheStr += '\\'; - // FALL THROUGH. - default: - TheStr += FixedStr[i]; - break; - } - } -} - bool Pattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM) { Regex R(RS); @@ -428,8 +400,8 @@ size_t Pattern::Match(StringRef Buffer, size_t &MatchLen, if (it == VariableTable.end()) return StringRef::npos; - // Look up the value and escape it so that we can plop it into the regex. - AddFixedStringToRegEx(it->second, Value); + // Look up the value and escape it so that we can put it into the regex. + Value += Regex::escape(it->second); } // Plop it into the regex at the adjusted offset.