benchmark
1.6.1
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 "internal_macros.h"
19
20
// clang-format off
21
22
#if !defined(HAVE_STD_REGEX) && \
23
!defined(HAVE_GNU_POSIX_REGEX) && \
24
!defined(HAVE_POSIX_REGEX)
25
// No explicit regex selection; detect based on builtin hints.
26
#if defined(BENCHMARK_OS_LINUX) || defined(BENCHMARK_OS_APPLE)
27
#define HAVE_POSIX_REGEX 1
28
#elif __cplusplus >= 199711L
29
#define HAVE_STD_REGEX 1
30
#endif
31
#endif
32
33
// Prefer C regex libraries when compiling w/o exceptions so that we can
34
// correctly report errors.
35
#if defined(BENCHMARK_HAS_NO_EXCEPTIONS) && \
36
defined(BENCHMARK_HAVE_STD_REGEX) && \
37
(defined(HAVE_GNU_POSIX_REGEX) || defined(HAVE_POSIX_REGEX))
38
#undef HAVE_STD_REGEX
39
#endif
40
41
#if defined(HAVE_STD_REGEX)
42
#include <regex>
43
#elif defined(HAVE_GNU_POSIX_REGEX)
44
#include <gnuregex.h>
45
#elif defined(HAVE_POSIX_REGEX)
46
#include <regex.h>
47
#else
48
#error No regular expression backend was found!
49
#endif
50
51
// clang-format on
52
53
#include <string>
54
55
#include "check.h"
56
57
namespace
benchmark {
58
59
// A wrapper around the POSIX regular expression API that provides automatic
60
// cleanup
61
class
Regex {
62
public
:
63
Regex() : init_(
false
) {}
64
65
~Regex();
66
67
// Compile a regular expression matcher from spec. Returns true on success.
68
//
69
// On failure (and if error is not nullptr), error is populated with a human
70
// readable error message if an error occurs.
71
bool
Init(
const
std::string& spec, std::string* error);
72
73
// Returns whether str matches the compiled regular expression.
74
bool
Match(
const
std::string& str);
75
76
private
:
77
bool
init_;
78
// Underlying regular expression object
79
#if defined(HAVE_STD_REGEX)
80
std::regex re_;
81
#elif defined(HAVE_POSIX_REGEX) || defined(HAVE_GNU_POSIX_REGEX)
82
regex_t re_;
83
#else
84
#error No regular expression backend implementation available
85
#endif
86
};
87
88
#if defined(HAVE_STD_REGEX)
89
90
inline
bool
Regex::Init(
const
std::string& spec, std::string* error) {
91
#ifdef BENCHMARK_HAS_NO_EXCEPTIONS
92
((void)error);
// suppress unused warning
93
#else
94
try
{
95
#endif
96
re_ = std::regex(spec, std::regex_constants::extended);
97
init_ =
true
;
98
#ifndef BENCHMARK_HAS_NO_EXCEPTIONS
99
}
100
catch
(
const
std::regex_error& e) {
101
if
(error) {
102
*error = e.what();
103
}
104
}
105
#endif
106
return
init_;
107
}
108
109
inline
Regex::~Regex() {}
110
111
inline
bool
Regex::Match(
const
std::string& str) {
112
if
(!init_) {
113
return
false
;
114
}
115
return
std::regex_search(str, re_);
116
}
117
118
#else
119
inline
bool
Regex::Init(
const
std::string& spec, std::string* error) {
120
int
ec = regcomp(&re_, spec.c_str(), REG_EXTENDED | REG_NOSUB);
121
if
(ec != 0) {
122
if
(error) {
123
size_t
needed = regerror(ec, &re_,
nullptr
, 0);
124
char
* errbuf =
new
char
[needed];
125
regerror(ec, &re_, errbuf, needed);
126
127
// regerror returns the number of bytes necessary to null terminate
128
// the string, so we move that when assigning to error.
129
BM_CHECK_NE(needed, 0);
130
error->assign(errbuf, needed - 1);
131
132
delete
[] errbuf;
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.17.0