2 // regex utils for the C++ library testsuite.
4 // Copyright (C) 2012-2025 Free Software Foundation, Inc.
6 // This file is part of the GNU ISO C++ Library. This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING3. If not see
19 // <http://www.gnu.org/licenses/>.
22 #ifndef _TESTSUITE_REGEX_H
23 #define _TESTSUITE_REGEX_H 1
31 // Test on a compilation of simple expressions, throw regex_error on error.
32 typedef std::regex regex_type
;
33 typedef regex_type::flag_type flag_type
;
34 typedef std::regex_constants::match_flag_type match_flag_type
;
35 typedef std::regex_constants::error_type error_type
;
36 typedef std::size_t size_type
;
37 typedef std::string string_type
;
38 using std::basic_regex
;
39 using std::match_results
;
42 struct regex_expected_fail
{ };
44 const error_type
regex_error_internal(static_cast<error_type
>(-1));
46 // Stringify error codes for text logging.
47 const char* regex_error_codes
[] =
65 show_regex_error_codes()
68 using namespace std::regex_constants
;
70 cout
<< "error_collate = " << tab
<< error_collate
<< endl
;
71 cout
<< "error_ctype = " << tab
<< error_ctype
<< endl
;
72 cout
<< "error_escape = " << tab
<< error_escape
<< endl
;
73 cout
<< "error_backref = " << tab
<< error_backref
<< endl
;
74 cout
<< "error_brack = " << tab
<< error_brack
<< endl
;
75 cout
<< "error_paren = " << tab
<< error_paren
<< endl
;
76 cout
<< "error_brace = " << tab
<< error_brace
<< endl
;
77 cout
<< "error_badbrace = " << tab
<< error_badbrace
<< endl
;
78 cout
<< "error_range = " << tab
<< error_range
<< endl
;
79 cout
<< "error_space = " << tab
<< error_space
<< endl
;
80 cout
<< "error_badrepeat = " << tab
<< error_badrepeat
<< endl
;
81 cout
<< "error_complexity =" << tab
<< error_complexity
<< endl
;
82 cout
<< "error_stack = " << tab
<< error_stack
<< endl
;
86 // string __res: the regular expression string
87 // flag_type __f: flag
88 // __error: expected error, if any
90 regex_sanity_check(const string_type
& __res
,
91 flag_type __f
= regex_type::basic
,
92 error_type __error
= regex_error_internal
)
98 regex_type
reo(__res
, __f
);
99 auto n
= reo
.mark_count();
100 cout
<< "regex_type::mark_count " << n
<< endl
;
102 catch (const regex_error
& e
)
104 cout
<< "regex_sanity_check: " << __res
<< endl
;
105 cout
<< "regex_error::what " << e
.what() << endl
;
107 show_regex_error_codes();
108 cout
<< "regex_error::code " << regex_error_codes
[e
.code()] << endl
;
110 if (__error
!= regex_error_internal
)
112 // Then expected error_type is __error. Check.
113 if (__error
!= e
.code())
115 throw regex_expected_fail();
120 catch (const logic_error
& e
)
122 cout
<< "logic_error::what " << e
.what() << endl
;
125 catch (const std::exception
& e
)
127 cout
<< "exception: " << endl
;
132 // regex_match_debug behaves like regex_match, but will run *two* executors
133 // (if there's no back-reference) and check if their results agree. If not,
134 // an exception is thrown. The arguments are the same as for regex_match.
135 template<typename _Bi_iter
, typename _Alloc
,
136 typename _Ch_type
, typename _Rx_traits
>
138 regex_match_debug(_Bi_iter __s
,
140 match_results
<_Bi_iter
, _Alloc
>& __m
,
141 const basic_regex
<_Ch_type
, _Rx_traits
>& __re
,
142 match_flag_type __flags
143 = std::regex_constants::match_default
)
145 using namespace std::__detail
;
146 auto __res1
= __regex_algo_impl(__s
, __e
, __m
, __re
, __flags
,
147 _RegexExecutorPolicy::_S_auto
,
149 match_results
<_Bi_iter
, _Alloc
> __mm
;
150 auto __res2
= __regex_algo_impl(__s
, __e
, __mm
, __re
, __flags
,
151 _RegexExecutorPolicy::_S_alternate
,
153 if (__res1
== __res2
&& __m
== __mm
)
155 throw std::exception();
158 // No match_results version
159 template<typename _Bi_iter
, typename _Ch_type
, typename _Rx_traits
>
161 regex_match_debug(_Bi_iter __first
,
163 const basic_regex
<_Ch_type
, _Rx_traits
>& __re
,
164 match_flag_type __flags
165 = std::regex_constants::match_default
)
167 match_results
<_Bi_iter
> __what
;
168 return regex_match_debug(__first
, __last
, __what
, __re
, __flags
);
172 template<typename _Ch_type
, typename _Alloc
, typename _Rx_traits
>
174 regex_match_debug(const _Ch_type
* __s
,
175 match_results
<const _Ch_type
*, _Alloc
>& __m
,
176 const basic_regex
<_Ch_type
, _Rx_traits
>& __re
,
178 = std::regex_constants::match_default
)
179 { return regex_match_debug(__s
, __s
+ _Rx_traits::length(__s
),
182 // C-string version without match_results
183 template<typename _Ch_type
, class _Rx_traits
>
185 regex_match_debug(const _Ch_type
* __s
,
186 const basic_regex
<_Ch_type
, _Rx_traits
>& __re
,
188 = std::regex_constants::match_default
)
189 { return regex_match_debug(__s
, __s
+ _Rx_traits::length(__s
),
192 // std::basic_string version
193 template<typename _Ch_traits
, typename _Ch_alloc
,
194 typename _Alloc
, typename _Ch_type
, typename _Rx_traits
>
196 regex_match_debug(const std::basic_string
<_Ch_type
, _Ch_traits
,
198 match_results
<typename
std::basic_string
<_Ch_type
,
199 _Ch_traits
, _Ch_alloc
>::const_iterator
,
201 const basic_regex
<_Ch_type
, _Rx_traits
>& __re
,
202 match_flag_type __flags
203 = std::regex_constants::match_default
)
204 { return regex_match_debug(__s
.begin(), __s
.end(),
205 __m
, __re
, __flags
); }
207 // std::basic_string version without match_results
208 template<typename _Ch_traits
, typename _Str_allocator
,
209 typename _Ch_type
, typename _Rx_traits
>
211 regex_match_debug(const std::basic_string
<_Ch_type
, _Ch_traits
,
212 _Str_allocator
>& __s
,
213 const basic_regex
<_Ch_type
, _Rx_traits
>& __re
,
214 match_flag_type __flags
215 = std::regex_constants::match_default
)
216 { return regex_match_debug(__s
.begin(), __s
.end(), __re
, __flags
); }
218 // regex_match_debug behaves like regex_match, but will run *two* executors
219 // (if there's no back-reference) and check if their results agree. If not,
220 // an exception throws. One can use them just in the way of using regex_match.
221 template<typename _Bi_iter
, typename _Alloc
,
222 typename _Ch_type
, typename _Rx_traits
>
224 regex_search_debug(_Bi_iter __s
,
226 match_results
<_Bi_iter
, _Alloc
>& __m
,
227 const basic_regex
<_Ch_type
, _Rx_traits
>& __re
,
228 match_flag_type __flags
229 = std::regex_constants::match_default
)
231 using namespace std::__detail
;
232 auto __res1
= __regex_algo_impl(__s
, __e
, __m
, __re
, __flags
,
233 _RegexExecutorPolicy::_S_auto
,
235 match_results
<_Bi_iter
, _Alloc
> __mm
;
236 auto __res2
= __regex_algo_impl(__s
, __e
, __mm
, __re
, __flags
,
237 _RegexExecutorPolicy::_S_alternate
,
239 if (__res1
== __res2
&& __m
== __mm
)
241 throw(std::exception()); // Let test fail. Give it a name.
244 // No match_results version
245 template<typename _Bi_iter
, typename _Ch_type
, typename _Rx_traits
>
247 regex_search_debug(_Bi_iter __first
,
249 const basic_regex
<_Ch_type
, _Rx_traits
>& __re
,
250 match_flag_type __flags
251 = std::regex_constants::match_default
)
253 match_results
<_Bi_iter
> __what
;
254 return regex_search_debug(__first
, __last
, __what
, __re
, __flags
);
258 template<typename _Ch_type
, class _Alloc
, class _Rx_traits
>
260 regex_search_debug(const _Ch_type
* __s
,
261 match_results
<const _Ch_type
*, _Alloc
>& __m
,
262 const basic_regex
<_Ch_type
, _Rx_traits
>& __e
,
264 = std::regex_constants::match_default
)
265 { return regex_search_debug(__s
, __s
+ _Rx_traits::length(__s
),
268 // C-string version without match_results
269 template<typename _Ch_type
, typename _Rx_traits
>
271 regex_search_debug(const _Ch_type
* __s
,
272 const basic_regex
<_Ch_type
, _Rx_traits
>& __e
,
274 = std::regex_constants::match_default
)
275 { return regex_search_debug(__s
, __s
+ _Rx_traits::length(__s
),
278 // std::basic_string version
279 template<typename _Ch_traits
, typename _Ch_alloc
,
280 typename _Alloc
, typename _Ch_type
,
283 regex_search_debug(const std::basic_string
<_Ch_type
, _Ch_traits
,
285 match_results
<typename
std::basic_string
<_Ch_type
,
286 _Ch_traits
, _Ch_alloc
>::const_iterator
, _Alloc
>&
288 const basic_regex
<_Ch_type
, _Rx_traits
>& __e
,
290 = std::regex_constants::match_default
)
291 { return regex_search_debug(__s
.begin(), __s
.end(), __m
, __e
, __f
); }
293 // std::basic_string version without match_results
294 template<typename _Ch_traits
, typename _String_allocator
,
295 typename _Ch_type
, typename _Rx_traits
>
297 regex_search_debug(const std::basic_string
<_Ch_type
, _Ch_traits
,
298 _String_allocator
>& __s
,
299 const basic_regex
<_Ch_type
, _Rx_traits
>& __e
,
301 = std::regex_constants::match_default
)
302 { return regex_search_debug(__s
.begin(), __s
.end(), __e
, __f
); }
304 } // namespace __gnu_test