]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/util/testsuite_regex.h
edb15251d196220d23c151b49c61f0b9f074bb3e
[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-2023 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(__s, __e, __m, __re, __flags,
147 _RegexExecutorPolicy::_S_auto,
148 true);
149 match_results<_Bi_iter, _Alloc> __mm;
150 auto __res2 = __regex_algo_impl(__s, __e, __mm, __re, __flags,
151 _RegexExecutorPolicy::_S_alternate,
152 true);
153 if (__res1 == __res2 && __m == __mm)
154 return __res1;
155 throw std::exception();
156 }
157
158 // No match_results version
159 template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits>
160 inline bool
161 regex_match_debug(_Bi_iter __first,
162 _Bi_iter __last,
163 const basic_regex<_Ch_type, _Rx_traits>& __re,
164 match_flag_type __flags
165 = std::regex_constants::match_default)
166 {
167 match_results<_Bi_iter> __what;
168 return regex_match_debug(__first, __last, __what, __re, __flags);
169 }
170
171 // C-string version
172 template<typename _Ch_type, typename _Alloc, typename _Rx_traits>
173 inline bool
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,
177 match_flag_type __f
178 = std::regex_constants::match_default)
179 { return regex_match_debug(__s, __s + _Rx_traits::length(__s),
180 __m, __re, __f); }
181
182 // C-string version without match_results
183 template<typename _Ch_type, class _Rx_traits>
184 inline bool
185 regex_match_debug(const _Ch_type* __s,
186 const basic_regex<_Ch_type, _Rx_traits>& __re,
187 match_flag_type __f
188 = std::regex_constants::match_default)
189 { return regex_match_debug(__s, __s + _Rx_traits::length(__s),
190 __re, __f); }
191
192 // std::basic_string version
193 template<typename _Ch_traits, typename _Ch_alloc,
194 typename _Alloc, typename _Ch_type, typename _Rx_traits>
195 inline bool
196 regex_match_debug(const std::basic_string<_Ch_type, _Ch_traits,
197 _Ch_alloc>& __s,
198 match_results<typename std::basic_string<_Ch_type,
199 _Ch_traits, _Ch_alloc>::const_iterator,
200 _Alloc>& __m,
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); }
206
207 // std::basic_string version without match_results
208 template<typename _Ch_traits, typename _Str_allocator,
209 typename _Ch_type, typename _Rx_traits>
210 inline bool
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); }
217
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>
223 bool
224 regex_search_debug(_Bi_iter __s,
225 _Bi_iter __e,
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)
230 {
231 using namespace std::__detail;
232 auto __res1 = __regex_algo_impl(__s, __e, __m, __re, __flags,
233 _RegexExecutorPolicy::_S_auto,
234 false);
235 match_results<_Bi_iter, _Alloc> __mm;
236 auto __res2 = __regex_algo_impl(__s, __e, __mm, __re, __flags,
237 _RegexExecutorPolicy::_S_alternate,
238 false);
239 if (__res1 == __res2 && __m == __mm)
240 return __res1;
241 throw(std::exception()); // Let test fail. Give it a name.
242 }
243
244 // No match_results version
245 template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits>
246 inline bool
247 regex_search_debug(_Bi_iter __first,
248 _Bi_iter __last,
249 const basic_regex<_Ch_type, _Rx_traits>& __re,
250 match_flag_type __flags
251 = std::regex_constants::match_default)
252 {
253 match_results<_Bi_iter> __what;
254 return regex_search_debug(__first, __last, __what, __re, __flags);
255 }
256
257 // C-string version
258 template<typename _Ch_type, class _Alloc, class _Rx_traits>
259 inline bool
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,
263 match_flag_type __f
264 = std::regex_constants::match_default)
265 { return regex_search_debug(__s, __s + _Rx_traits::length(__s),
266 __m, __e, __f); }
267
268 // C-string version without match_results
269 template<typename _Ch_type, typename _Rx_traits>
270 inline bool
271 regex_search_debug(const _Ch_type* __s,
272 const basic_regex<_Ch_type, _Rx_traits>& __e,
273 match_flag_type __f
274 = std::regex_constants::match_default)
275 { return regex_search_debug(__s, __s + _Rx_traits::length(__s),
276 __e, __f); }
277
278 // std::basic_string version
279 template<typename _Ch_traits, typename _Ch_alloc,
280 typename _Alloc, typename _Ch_type,
281 typename _Rx_traits>
282 inline bool
283 regex_search_debug(const std::basic_string<_Ch_type, _Ch_traits,
284 _Ch_alloc>& __s,
285 match_results<typename std::basic_string<_Ch_type,
286 _Ch_traits, _Ch_alloc>::const_iterator, _Alloc>&
287 __m,
288 const basic_regex<_Ch_type, _Rx_traits>& __e,
289 match_flag_type __f
290 = std::regex_constants::match_default)
291 { return regex_search_debug(__s.begin(), __s.end(), __m, __e, __f); }
292
293 // std::basic_string version without match_results
294 template<typename _Ch_traits, typename _String_allocator,
295 typename _Ch_type, typename _Rx_traits>
296 inline bool
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,
300 match_flag_type __f
301 = std::regex_constants::match_default)
302 { return regex_search_debug(__s.begin(), __s.end(), __e, __f); }
303
304 } // namespace __gnu_test
305 #endif