diff options
Diffstat (limited to 'source/Utility/RegularExpression.cpp')
-rw-r--r-- | source/Utility/RegularExpression.cpp | 168 |
1 files changed, 17 insertions, 151 deletions
diff --git a/source/Utility/RegularExpression.cpp b/source/Utility/RegularExpression.cpp index 0192e8b8a01a..fd9d963f7294 100644 --- a/source/Utility/RegularExpression.cpp +++ b/source/Utility/RegularExpression.cpp @@ -8,168 +8,34 @@ #include "lldb/Utility/RegularExpression.h" -#include "llvm/ADT/StringRef.h" - #include <string> -// Enable enhanced mode if it is available. This allows for things like \d for -// digit, \s for space, and many more, but it isn't available everywhere. -#if defined(REG_ENHANCED) -#define DEFAULT_COMPILE_FLAGS (REG_ENHANCED | REG_EXTENDED) -#else -#define DEFAULT_COMPILE_FLAGS (REG_EXTENDED) -#endif - using namespace lldb_private; -RegularExpression::RegularExpression() : m_re(), m_comp_err(1), m_preg() { - memset(&m_preg, 0, sizeof(m_preg)); -} - -// Constructor that compiles "re" using "flags" and stores the resulting -// compiled regular expression into this object. RegularExpression::RegularExpression(llvm::StringRef str) - : RegularExpression() { - Compile(str); -} + : m_regex_text(str), + // m_regex does not reference str anymore after it is constructed. + m_regex(llvm::Regex(str)) {} RegularExpression::RegularExpression(const RegularExpression &rhs) - : RegularExpression() { - Compile(rhs.GetText()); -} - -const RegularExpression &RegularExpression:: -operator=(const RegularExpression &rhs) { - if (&rhs != this) - Compile(rhs.GetText()); - return *this; -} - -// Destructor -// -// Any previously compiled regular expression contained in this object will be -// freed. -RegularExpression::~RegularExpression() { Free(); } - -// Compile a regular expression using the supplied regular expression text and -// flags. The compiled regular expression lives in this object so that it can -// be readily used for regular expression matches. Execute() can be called -// after the regular expression is compiled. Any previously compiled regular -// expression contained in this object will be freed. -// -// RETURNS -// True if the regular expression compiles successfully, false -// otherwise. -bool RegularExpression::Compile(llvm::StringRef str) { - Free(); - - // regcomp() on darwin does not recognize "" as a valid regular expression, - // so we substitute it with an equivalent non-empty one. - m_re = str.empty() ? "()" : str; - m_comp_err = ::regcomp(&m_preg, m_re.c_str(), DEFAULT_COMPILE_FLAGS); - return m_comp_err == 0; -} + : RegularExpression(rhs.GetText()) {} -// Execute a regular expression match using the compiled regular expression -// that is already in this object against the match string "s". If any parens -// are used for regular expression matches "match_count" should indicate the -// number of regmatch_t values that are present in "match_ptr". The regular -// expression will be executed using the "execute_flags". -bool RegularExpression::Execute(llvm::StringRef str, Match *match) const { - int err = 1; - if (m_comp_err == 0) { - // Argument to regexec must be null-terminated. - std::string reg_str = str; - if (match) { - err = ::regexec(&m_preg, reg_str.c_str(), match->GetSize(), - match->GetData(), 0); - } else { - err = ::regexec(&m_preg, reg_str.c_str(), 0, nullptr, 0); - } - } - - if (err != 0) { - // The regular expression didn't compile, so clear the matches - if (match) - match->Clear(); +bool RegularExpression::Execute( + llvm::StringRef str, + llvm::SmallVectorImpl<llvm::StringRef> *matches) const { + if (!IsValid()) return false; - } - return true; -} - -bool RegularExpression::Match::GetMatchAtIndex(llvm::StringRef s, uint32_t idx, - std::string &match_str) const { - llvm::StringRef match_str_ref; - if (GetMatchAtIndex(s, idx, match_str_ref)) { - match_str = match_str_ref.str(); - return true; - } - return false; + return m_regex.match(str, matches); } -bool RegularExpression::Match::GetMatchAtIndex( - llvm::StringRef s, uint32_t idx, llvm::StringRef &match_str) const { - if (idx < m_matches.size()) { - if (m_matches[idx].rm_eo == -1 && m_matches[idx].rm_so == -1) - return false; - - if (m_matches[idx].rm_eo == m_matches[idx].rm_so) { - // Matched the empty string... - match_str = llvm::StringRef(); - return true; - } else if (m_matches[idx].rm_eo > m_matches[idx].rm_so) { - match_str = s.substr(m_matches[idx].rm_so, - m_matches[idx].rm_eo - m_matches[idx].rm_so); - return true; - } - } - return false; -} - -bool RegularExpression::Match::GetMatchSpanningIndices( - llvm::StringRef s, uint32_t idx1, uint32_t idx2, - llvm::StringRef &match_str) const { - if (idx1 < m_matches.size() && idx2 < m_matches.size()) { - if (m_matches[idx1].rm_so == m_matches[idx2].rm_eo) { - // Matched the empty string... - match_str = llvm::StringRef(); - return true; - } else if (m_matches[idx1].rm_so < m_matches[idx2].rm_eo) { - match_str = s.substr(m_matches[idx1].rm_so, - m_matches[idx2].rm_eo - m_matches[idx1].rm_so); - return true; - } - } - return false; -} +bool RegularExpression::IsValid() const { return m_regex.isValid(); } -// Returns true if the regular expression compiled and is ready for execution. -bool RegularExpression::IsValid() const { return m_comp_err == 0; } - -// Returns the text that was used to compile the current regular expression. -llvm::StringRef RegularExpression::GetText() const { return m_re; } - -// Free any contained compiled regular expressions. -void RegularExpression::Free() { - if (m_comp_err == 0) { - m_re.clear(); - regfree(&m_preg); - // Set a compile error since we no longer have a valid regex - m_comp_err = 1; - } -} - -size_t RegularExpression::GetErrorAsCString(char *err_str, - size_t err_str_max_len) const { - if (m_comp_err == 0) { - if (err_str && err_str_max_len) - *err_str = '\0'; - return 0; - } - - return ::regerror(m_comp_err, &m_preg, err_str, err_str_max_len); -} +llvm::StringRef RegularExpression::GetText() const { return m_regex_text; } -bool RegularExpression::operator<(const RegularExpression &rhs) const { - return (m_re < rhs.m_re); +llvm::Error RegularExpression::GetError() const { + std::string error; + if (!m_regex.isValid(error)) + return llvm::make_error<llvm::StringError>(llvm::inconvertibleErrorCode(), + error); + return llvm::Error::success(); } |