2 // regex utils for the C++ library testsuite.
4 // Copyright (C) 2012-2014 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
<_Bi_iter
, _Alloc
, _Ch_type
, _Rx_traits
,
147 _RegexExecutorPolicy::_S_auto
, true>
148 (__s
, __e
, __m
, __re
, __flags
);
149 match_results
<_Bi_iter
, _Alloc
> __mm
;
150 auto __res2
= __regex_algo_impl
<_Bi_iter
, _Alloc
, _Ch_type
, _Rx_traits
,
151 _RegexExecutorPolicy::_S_alternate
, true>
152 (__s
, __e
, __mm
, __re
, __flags
);
153 // __m is unspecified if return value is false.
154 if (__res1
== __res2
&& (!__res1
|| __m
== __mm
))
156 throw std::exception();
159 // No match_results version
160 template<typename _Bi_iter
, typename _Ch_type
, typename _Rx_traits
>
162 regex_match_debug(_Bi_iter __first
,
164 const basic_regex
<_Ch_type
, _Rx_traits
>& __re
,
165 match_flag_type __flags
166 = std::regex_constants::match_default
)
168 match_results
<_Bi_iter
> __what
;
169 return regex_match_debug(__first
, __last
, __what
, __re
, __flags
);
173 template<typename _Ch_type
, typename _Alloc
, typename _Rx_traits
>
175 regex_match_debug(const _Ch_type
* __s
,
176 match_results
<const _Ch_type
*, _Alloc
>& __m
,
177 const basic_regex
<_Ch_type
, _Rx_traits
>& __re
,
179 = std::regex_constants::match_default
)
180 { return regex_match_debug(__s
, __s
+ _Rx_traits::length(__s
),
183 // C-string version without match_results
184 template<typename _Ch_type
, class _Rx_traits
>
186 regex_match_debug(const _Ch_type
* __s
,
187 const basic_regex
<_Ch_type
, _Rx_traits
>& __re
,
189 = std::regex_constants::match_default
)
190 { return regex_match_debug(__s
, __s
+ _Rx_traits::length(__s
),
193 // std::basic_string version
194 template<typename _Ch_traits
, typename _Ch_alloc
,
195 typename _Alloc
, typename _Ch_type
, typename _Rx_traits
>
197 regex_match_debug(const std::basic_string
<_Ch_type
, _Ch_traits
,
199 match_results
<typename
std::basic_string
<_Ch_type
,
200 _Ch_traits
, _Ch_alloc
>::const_iterator
,
202 const basic_regex
<_Ch_type
, _Rx_traits
>& __re
,
203 match_flag_type __flags
204 = std::regex_constants::match_default
)
205 { return regex_match_debug(__s
.begin(), __s
.end(),
206 __m
, __re
, __flags
); }
208 // std::basic_string version without match_results
209 template<typename _Ch_traits
, typename _Str_allocator
,
210 typename _Ch_type
, typename _Rx_traits
>
212 regex_match_debug(const std::basic_string
<_Ch_type
, _Ch_traits
,
213 _Str_allocator
>& __s
,
214 const basic_regex
<_Ch_type
, _Rx_traits
>& __re
,
215 match_flag_type __flags
216 = std::regex_constants::match_default
)
217 { return regex_match_debug(__s
.begin(), __s
.end(), __re
, __flags
); }
219 // regex_match_debug behaves like regex_match, but will run *two* executors
220 // (if there's no back-reference) and check if their results agree. If not,
221 // an exception throws. One can use them just in the way of using regex_match.
222 template<typename _Bi_iter
, typename _Alloc
,
223 typename _Ch_type
, typename _Rx_traits
>
225 regex_search_debug(_Bi_iter __s
,
227 match_results
<_Bi_iter
, _Alloc
>& __m
,
228 const basic_regex
<_Ch_type
, _Rx_traits
>& __re
,
229 match_flag_type __flags
230 = std::regex_constants::match_default
)
232 using namespace std::__detail
;
233 auto __res1
= __regex_algo_impl
<_Bi_iter
, _Alloc
, _Ch_type
, _Rx_traits
,
234 _RegexExecutorPolicy::_S_auto
, false>
235 (__s
, __e
, __m
, __re
, __flags
);
236 match_results
<_Bi_iter
, _Alloc
> __mm
;
237 auto __res2
= __regex_algo_impl
<_Bi_iter
, _Alloc
, _Ch_type
, _Rx_traits
,
238 _RegexExecutorPolicy::_S_alternate
, false>
239 (__s
, __e
, __mm
, __re
, __flags
);
240 if (__res1
== __res2
&& __m
== __mm
)
242 throw(std::exception()); // Let test fail. Give it a name.
245 // No match_results version
246 template<typename _Bi_iter
, typename _Ch_type
, typename _Rx_traits
>
248 regex_search_debug(_Bi_iter __first
,
250 const basic_regex
<_Ch_type
, _Rx_traits
>& __re
,
251 match_flag_type __flags
252 = std::regex_constants::match_default
)
254 match_results
<_Bi_iter
> __what
;
255 return regex_search_debug(__first
, __last
, __what
, __re
, __flags
);
259 template<typename _Ch_type
, class _Alloc
, class _Rx_traits
>
261 regex_search_debug(const _Ch_type
* __s
,
262 match_results
<const _Ch_type
*, _Alloc
>& __m
,
263 const basic_regex
<_Ch_type
, _Rx_traits
>& __e
,
265 = std::regex_constants::match_default
)
266 { return regex_search_debug(__s
, __s
+ _Rx_traits::length(__s
),
269 // C-string version without match_results
270 template<typename _Ch_type
, typename _Rx_traits
>
272 regex_search_debug(const _Ch_type
* __s
,
273 const basic_regex
<_Ch_type
, _Rx_traits
>& __e
,
275 = std::regex_constants::match_default
)
276 { return regex_search_debug(__s
, __s
+ _Rx_traits::length(__s
),
279 // std::basic_string version
280 template<typename _Ch_traits
, typename _Ch_alloc
,
281 typename _Alloc
, typename _Ch_type
,
284 regex_search_debug(const std::basic_string
<_Ch_type
, _Ch_traits
,
286 match_results
<typename
std::basic_string
<_Ch_type
,
287 _Ch_traits
, _Ch_alloc
>::const_iterator
, _Alloc
>&
289 const basic_regex
<_Ch_type
, _Rx_traits
>& __e
,
291 = std::regex_constants::match_default
)
292 { return regex_search_debug(__s
.begin(), __s
.end(), __m
, __e
, __f
); }
294 // std::basic_string version without match_results
295 template<typename _Ch_traits
, typename _String_allocator
,
296 typename _Ch_type
, typename _Rx_traits
>
298 regex_search_debug(const std::basic_string
<_Ch_type
, _Ch_traits
,
299 _String_allocator
>& __s
,
300 const basic_regex
<_Ch_type
, _Rx_traits
>& __e
,
302 = std::regex_constants::match_default
)
303 { return regex_search_debug(__s
.begin(), __s
.end(), __e
, __f
); }
305 } // namespace __gnu_test