Expose FileCheck's AddFixedStringToRegEx as Regex::escape

Both FileCheck and clang's -verify need to escape strings for regexes,
so let's expose this as a utility in the Regex class.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197096 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Hans Wennborg 2013-12-12 00:06:41 +00:00
parent eb1bac0afa
commit 76eb77dd52
3 changed files with 35 additions and 31 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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.