benchmark
1.10.0
Toggle main menu visibility
Loading...
Searching...
No Matches
re.h
1
// Copyright 2015 Google Inc. All rights reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#ifndef BENCHMARK_RE_H_
16
#define BENCHMARK_RE_H_
17
18
#include <vector>
19
20
#include "internal_macros.h"
21
22
// clang-format off
23
24
#if !defined(HAVE_STD_REGEX) && \
25
!defined(HAVE_GNU_POSIX_REGEX) && \
26
!defined(HAVE_POSIX_REGEX)
27
// No explicit regex selection; detect based on builtin hints.
28
#if defined(BENCHMARK_OS_LINUX) || defined(BENCHMARK_OS_APPLE)
29
#define HAVE_POSIX_REGEX 1
30
#elif __cplusplus >= 199711L
31
#define HAVE_STD_REGEX 1
32
#endif
33
#endif
34
35
// Prefer C regex libraries when compiling w/o exceptions so that we can
36
// correctly report errors.
37
#if defined(BENCHMARK_HAS_NO_EXCEPTIONS) && \
38
defined(HAVE_STD_REGEX) && \
39
(defined(HAVE_GNU_POSIX_REGEX) || defined(HAVE_POSIX_REGEX))
40
#undef HAVE_STD_REGEX
41
#endif
42
43
#if defined(HAVE_STD_REGEX)
44
#include <regex>
45
#elif defined(HAVE_GNU_POSIX_REGEX)
46
#include <gnuregex.h>
47
#elif defined(HAVE_POSIX_REGEX)
48
#include <regex.h>
49
#else
50
#error No regular expression backend was found!
51
#endif
52
53
// clang-format on
54
55
#include <string>
56
57
#include "check.h"
58
59
namespace
benchmark {
60
61
// A wrapper around the POSIX regular expression API that provides automatic
62
// cleanup
63
class
Regex {
64
public
:
65
Regex() : init_(
false
) {}
66
67
~Regex();
68
69
// Compile a regular expression matcher from spec. Returns true on success.
70
//
71
// On failure (and if error is not nullptr), error is populated with a human
72
// readable error message if an error occurs.
73
bool
Init(
const
std::string& spec, std::string* error);
74
75
// Returns whether str matches the compiled regular expression.
76
bool
Match(
const
std::string& str);
77
78
private
:
79
bool
init_;
80
// Underlying regular expression object
81
#if defined(HAVE_STD_REGEX)
82
std::regex re_;
83
#elif defined(HAVE_POSIX_REGEX) || defined(HAVE_GNU_POSIX_REGEX)
84
regex_t re_;
85
#else
86
#error No regular expression backend implementation available
87
#endif
88
};
89
90
#if defined(HAVE_STD_REGEX)
91
92
inline
bool
Regex::Init(
const
std::string& spec, std::string* error) {
93
#ifdef BENCHMARK_HAS_NO_EXCEPTIONS
94
((void)error);
// suppress unused warning
95
#else
96
try
{
97
#endif
98
re_ = std::regex(spec, std::regex_constants::extended);
99
init_ =
true
;
100
#ifndef BENCHMARK_HAS_NO_EXCEPTIONS
101
}
102
catch
(
const
std::regex_error& e) {
103
if
(error) {
104
*error = e.what();
105
}
106
}
107
#endif
108
return
init_;
109
}
110
111
inline
Regex::~Regex() {}
112
113
inline
bool
Regex::Match(
const
std::string& str) {
114
if
(!init_) {
115
return
false
;
116
}
117
return
std::regex_search(str, re_);
118
}
119
120
#else
121
inline
bool
Regex::Init(
const
std::string& spec, std::string* error) {
122
int
ec = regcomp(&re_, spec.c_str(), REG_EXTENDED | REG_NOSUB);
123
if
(ec != 0) {
124
if
(error) {
125
size_t
needed = regerror(ec, &re_,
nullptr
, 0);
126
std::vector<char> errbuf(needed);
127
regerror(ec, &re_, errbuf.data(), needed);
128
129
// regerror returns the number of bytes necessary to null terminate
130
// the string, so we move that when assigning to error.
131
BM_CHECK_NE(needed, 0);
132
error->assign(errbuf.data(), needed - 1);
133
}
134
135
return
false
;
136
}
137
138
init_ =
true
;
139
return
true
;
140
}
141
142
inline
Regex::~Regex() {
143
if
(init_) {
144
regfree(&re_);
145
}
146
}
147
148
inline
bool
Regex::Match(
const
std::string& str) {
149
if
(!init_) {
150
return
false
;
151
}
152
return
regexec(&re_, str.c_str(), 0,
nullptr
, 0) == 0;
153
}
154
#endif
155
156
}
// end namespace benchmark
157
158
#endif
// BENCHMARK_RE_H_
src
re.h
Generated by
1.18.0