diff options
Diffstat (limited to 'libcxx/utils/google-benchmark/src/re.h')
| -rw-r--r-- | libcxx/utils/google-benchmark/src/re.h | 72 |
1 files changed, 69 insertions, 3 deletions
diff --git a/libcxx/utils/google-benchmark/src/re.h b/libcxx/utils/google-benchmark/src/re.h index af57a39cffb..af4a498c9f7 100644 --- a/libcxx/utils/google-benchmark/src/re.h +++ b/libcxx/utils/google-benchmark/src/re.h @@ -26,13 +26,16 @@ #endif #include <string> +#include "check.h" + namespace benchmark { // A wrapper around the POSIX regular expression API that provides automatic // cleanup class Regex { public: - Regex(); + Regex() : init_(false) {} + ~Regex(); // Compile a regular expression matcher from spec. Returns true on success. @@ -43,18 +46,81 @@ class Regex { // Returns whether str matches the compiled regular expression. bool Match(const std::string& str); + private: bool init_; - // Underlying regular expression object +// Underlying regular expression object #if defined(HAVE_STD_REGEX) std::regex re_; #elif defined(HAVE_POSIX_REGEX) || defined(HAVE_GNU_POSIX_REGEX) regex_t re_; #else -# error No regular expression backend implementation available +#error No regular expression backend implementation available #endif }; +#if defined(HAVE_STD_REGEX) + +inline bool Regex::Init(const std::string& spec, std::string* error) { + try { + re_ = std::regex(spec, std::regex_constants::extended); + + init_ = true; + } catch (const std::regex_error& e) { + if (error) { + *error = e.what(); + } + } + return init_; +} + +inline Regex::~Regex() {} + +inline bool Regex::Match(const std::string& str) { + if (!init_) { + return false; + } + return std::regex_search(str, re_); +} + +#else +inline bool Regex::Init(const std::string& spec, std::string* error) { + int ec = regcomp(&re_, spec.c_str(), REG_EXTENDED | REG_NOSUB); + if (ec != 0) { + if (error) { + size_t needed = regerror(ec, &re_, nullptr, 0); + char* errbuf = new char[needed]; + regerror(ec, &re_, errbuf, needed); + + // regerror returns the number of bytes necessary to null terminate + // the string, so we move that when assigning to error. + CHECK_NE(needed, 0); + error->assign(errbuf, needed - 1); + + delete[] errbuf; + } + + return false; + } + + init_ = true; + return true; +} + +inline Regex::~Regex() { + if (init_) { + regfree(&re_); + } +} + +inline bool Regex::Match(const std::string& str) { + if (!init_) { + return false; + } + return regexec(&re_, str.c_str(), 0, nullptr, 0) == 0; +} +#endif + } // end namespace benchmark #endif // BENCHMARK_RE_H_ |

