]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/util/testsuite_regex.h
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / util / testsuite_regex.h
1 // -*- C++ -*-
2 // regex utils for the C++ library testsuite.
3 //
4 // Copyright (C) 2012-2022 Free Software Foundation, Inc.
5 //
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)
10 // any later version.
11 //
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.
16 //
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/>.
20 //
21
22 #ifndef _TESTSUITE_REGEX_H
23 #define _TESTSUITE_REGEX_H 1
24
25 #include <regex>
26 #include <stdexcept>
27 #include <iostream>
28
29 namespace __gnu_test
30 {
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;
40
41 // Utilities
42 struct regex_expected_fail { };
43
44 const error_type regex_error_internal(static_cast<error_type>(-1));
45
46 // Stringify error codes for text logging.
47 const char* regex_error_codes[] =
48 {
49 "error_collate",
50 "error_ctype",
51 "error_escape",
52 "error_backref",
53 "error_brack",
54 "error_paren",
55 "error_brace",
56 "error_badbrace",
57 "error_range",
58 "error_space",
59 "error_badrepeat",
60 "error_complexity",
61 "error_stack"
62 };
63
64 void
65 show_regex_error_codes()
66 {
67 using namespace std;
68 using namespace std::regex_constants;
69 const char tab('\t');
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;
83 }
84
85 // Arguments
86 // string __res: the regular expression string
87 // flag_type __f: flag
88 // __error: expected error, if any
89 void
90 regex_sanity_check(const string_type& __res,
91 flag_type __f = regex_type::basic,
92 error_type __error = regex_error_internal)
93 {
94 using namespace std;
95
96 try
97 {
98 regex_type reo(__res, __f);
99 auto n = reo.mark_count();
100 cout << "regex_type::mark_count " << n << endl;
101 }
102 catch (const regex_error& e)
103 {
104 cout << "regex_sanity_check: " << __res << endl;
105 cout << "regex_error::what " << e.what() << endl;
106
107 show_regex_error_codes();
108 cout << "regex_error::code " << regex_error_codes[e.code()] << endl;
109
110 if (__error != regex_error_internal)
111 {
112 // Then expected error_type is __error. Check.
113 if (__error != e.code())
114 {
115 throw regex_expected_fail();
116 }
117 }
118 throw;
119 }
120 catch (const logic_error& e)
121 {
122 cout << "logic_error::what " << e.what() << endl;
123 throw;
124 }
125 catch (const std::exception& e)
126 {
127 cout << "exception: " << endl;
128 throw;
129 }
130 }
131
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>
137 bool
138 regex_match_debug(_Bi_iter __s,
139 _Bi_iter __e,
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)
144 {
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))
155 return __res1;
156 throw std::exception();
157 }
158
159 // No match_results version
160 template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits>
161 inline bool
162 regex_match_debug(_Bi_iter __first,
163 _Bi_iter __last,
164 const basic_regex<_Ch_type, _Rx_traits>& __re,
165 match_flag_type __flags
166 = std::regex_constants::match_default)
167 {
168 match_results<_Bi_iter> __what;
169 return regex_match_debug(__first, __last, __what, __re, __flags);
170 }
171
172 // C-string version
173 template<typename _Ch_type, typename _Alloc, typename _Rx_traits>
174 inline bool
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,
178 match_flag_type __f
179 = std::regex_constants::match_default)
180 { return regex_match_debug(__s, __s + _Rx_traits::length(__s),
181 __m, __re, __f); }
182
183 // C-string version without match_results
184 template<typename _Ch_type, class _Rx_traits>
185 inline bool
186 regex_match_debug(const _Ch_type* __s,
187 const basic_regex<_Ch_type, _Rx_traits>& __re,
188 match_flag_type __f
189 = std::regex_constants::match_default)
190 { return regex_match_debug(__s, __s + _Rx_traits::length(__s),
191 __re, __f); }
192
193 // std::basic_string version
194 template<typename _Ch_traits, typename _Ch_alloc,
195 typename _Alloc, typename _Ch_type, typename _Rx_traits>
196 inline bool
197 regex_match_debug(const std::basic_string<_Ch_type, _Ch_traits,
198 _Ch_alloc>& __s,
199 match_results<typename std::basic_string<_Ch_type,
200 _Ch_traits, _Ch_alloc>::const_iterator,
201 _Alloc>& __m,
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); }
207
208 // std::basic_string version without match_results
209 template<typename _Ch_traits, typename _Str_allocator,
210 typename _Ch_type, typename _Rx_traits>
211 inline bool
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); }
218
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>
224 bool
225 regex_search_debug(_Bi_iter __s,
226 _Bi_iter __e,
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)
231 {
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)
241 return __res1;
242 throw(std::exception()); // Let test fail. Give it a name.
243 }
244
245 // No match_results version
246 template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits>
247 inline bool
248 regex_search_debug(_Bi_iter __first,
249 _Bi_iter __last,
250 const basic_regex<_Ch_type, _Rx_traits>& __re,
251 match_flag_type __flags
252 = std::regex_constants::match_default)
253 {
254 match_results<_Bi_iter> __what;
255 return regex_search_debug(__first, __last, __what, __re, __flags);
256 }
257
258 // C-string version
259 template<typename _Ch_type, class _Alloc, class _Rx_traits>
260 inline bool
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,
264 match_flag_type __f
265 = std::regex_constants::match_default)
266 { return regex_search_debug(__s, __s + _Rx_traits::length(__s),
267 __m, __e, __f); }
268
269 // C-string version without match_results
270 template<typename _Ch_type, typename _Rx_traits>
271 inline bool
272 regex_search_debug(const _Ch_type* __s,
273 const basic_regex<_Ch_type, _Rx_traits>& __e,
274 match_flag_type __f
275 = std::regex_constants::match_default)
276 { return regex_search_debug(__s, __s + _Rx_traits::length(__s),
277 __e, __f); }
278
279 // std::basic_string version
280 template<typename _Ch_traits, typename _Ch_alloc,
281 typename _Alloc, typename _Ch_type,
282 typename _Rx_traits>
283 inline bool
284 regex_search_debug(const std::basic_string<_Ch_type, _Ch_traits,
285 _Ch_alloc>& __s,
286 match_results<typename std::basic_string<_Ch_type,
287 _Ch_traits, _Ch_alloc>::const_iterator, _Alloc>&
288 __m,
289 const basic_regex<_Ch_type, _Rx_traits>& __e,
290 match_flag_type __f
291 = std::regex_constants::match_default)
292 { return regex_search_debug(__s.begin(), __s.end(), __m, __e, __f); }
293
294 // std::basic_string version without match_results
295 template<typename _Ch_traits, typename _String_allocator,
296 typename _Ch_type, typename _Rx_traits>
297 inline bool
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,
301 match_flag_type __f
302 = std::regex_constants::match_default)
303 { return regex_search_debug(__s.begin(), __s.end(), __e, __f); }
304
305 } // namespace __gnu_test
306 #endif