aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support/Regex.cpp
diff options
context:
space:
mode:
authorThomas Preud'homme <thomasp@graphcore.ai>2019-09-24 14:42:36 +0000
committerThomas Preud'homme <thomasp@graphcore.ai>2019-09-24 14:42:36 +0000
commit5f738940b552fe22ca0850981c55279da8e7527d (patch)
tree573211606034b47838be7fb3ae59cf69c6049531 /llvm/lib/Support/Regex.cpp
parent5a4355324e1bb5cf6acc5f8b54349184b98eb60a (diff)
downloadllvm-5f738940b552fe22ca0850981c55279da8e7527d.zip
llvm-5f738940b552fe22ca0850981c55279da8e7527d.tar.gz
llvm-5f738940b552fe22ca0850981c55279da8e7527d.tar.bz2
Regex: Make "match" and "sub" const member functions
Summary: The Regex "match" and "sub" member functions were previously not "const" because they wrote to the "error" member variable. This commit removes those assignments, and instead assumes that the validity of the regex is already known after the initial compilation of the regular expression. As a result, these member functions were possible to make "const". This makes it easier to do things like pre-compile Regexes up-front, and makes "match" and "sub" thread-safe. The error status is now returned as an optional output, which also makes the API of "match" and "sub" more consistent with each other. Also, some uses of Regex that could be refactored to be const were made const. Patch by Nicolas Guillemot Reviewers: jankratochvil, thopre Subscribers: llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D67241 llvm-svn: 372764
Diffstat (limited to 'llvm/lib/Support/Regex.cpp')
-rw-r--r--llvm/lib/Support/Regex.cpp39
1 files changed, 27 insertions, 12 deletions
diff --git a/llvm/lib/Support/Regex.cpp b/llvm/lib/Support/Regex.cpp
index 4c1b070..8da345d 100644
--- a/llvm/lib/Support/Regex.cpp
+++ b/llvm/lib/Support/Regex.cpp
@@ -52,14 +52,24 @@ Regex::~Regex() {
}
}
-bool Regex::isValid(std::string &Error) const {
- if (!error)
- return true;
+namespace {
+/// Utility to convert a regex error code into a human-readable string.
+void RegexErrorToString(int error, struct llvm_regex *preg,
+ std::string &Error) {
size_t len = llvm_regerror(error, preg, nullptr, 0);
Error.resize(len - 1);
llvm_regerror(error, preg, &Error[0], len);
+}
+
+} // namespace
+
+bool Regex::isValid(std::string &Error) const {
+ if (!error)
+ return true;
+
+ RegexErrorToString(error, preg, Error);
return false;
}
@@ -69,8 +79,14 @@ unsigned Regex::getNumMatches() const {
return preg->re_nsub;
}
-bool Regex::match(StringRef String, SmallVectorImpl<StringRef> *Matches){
- if (error)
+bool Regex::match(StringRef String, SmallVectorImpl<StringRef> *Matches,
+ std::string *Error) const {
+ // Reset error, if given.
+ if (Error && !Error->empty())
+ *Error = "";
+
+ // Check if the regex itself didn't successfully compile.
+ if (Error ? !isValid(*Error) : !isValid())
return false;
unsigned nmatch = Matches ? preg->re_nsub+1 : 0;
@@ -83,11 +99,13 @@ bool Regex::match(StringRef String, SmallVectorImpl<StringRef> *Matches){
int rc = llvm_regexec(preg, String.data(), nmatch, pm.data(), REG_STARTEND);
+ // Failure to match is not an error, it's just a normal return value.
+ // Any other error code is considered abnormal, and is logged in the Error.
if (rc == REG_NOMATCH)
return false;
if (rc != 0) {
- // regexec can fail due to invalid pattern or running out of memory.
- error = rc;
+ if (Error)
+ RegexErrorToString(error, preg, *Error);
return false;
}
@@ -112,14 +130,11 @@ bool Regex::match(StringRef String, SmallVectorImpl<StringRef> *Matches){
}
std::string Regex::sub(StringRef Repl, StringRef String,
- std::string *Error) {
+ std::string *Error) const {
SmallVector<StringRef, 8> Matches;
- // Reset error, if given.
- if (Error && !Error->empty()) *Error = "";
-
// Return the input if there was no match.
- if (!match(String, &Matches))
+ if (!match(String, &Matches, Error))
return String;
// Otherwise splice in the replacement string, starting with the prefix before