summaryrefslogtreecommitdiffstats
path: root/libcxx/utils/google-benchmark/src/re.h
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/utils/google-benchmark/src/re.h')
-rw-r--r--libcxx/utils/google-benchmark/src/re.h72
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_
OpenPOWER on IntegriCloud