1 /*
2 *
3 * Copyright (c) 2004
4 * John Maddock
5 *
6 * Use, modification and distribution are subject to the
7 * Boost Software License, Version 1.0. (See accompanying file
8 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 *
10 */
11
12 /*
13 * LOCATION: see http://www.boost.org for most recent version.
14 * FILE test_deprecated.cpp
15 * VERSION see <boost/version.hpp>
16 * DESCRIPTION: Tests for deprecated interfaces.
17 */
18
19 #include "test.hpp"
20 #include <boost/cregex.hpp>
21
22 #ifdef BOOST_MSVC
23 #pragma warning(disable:4267)
24 #endif
25
26 #ifdef BOOST_NO_STDC_NAMESPACE
27 namespace std{
28 using ::atoi;
29 using ::wcstol;
30 }
31 #endif
32
get_posix_compile_options(boost::regex_constants::syntax_option_type opts)33 int get_posix_compile_options(boost::regex_constants::syntax_option_type opts)
34 {
35 using namespace boost;
36 int result = 0;
37 switch(opts & regbase::main_option_type)
38 {
39 case regbase::perl:
40 result = (opts & regbase::no_perl_ex) ? REG_EXTENDED : REG_PERL;
41 if(opts & (regbase::no_bk_refs|regbase::no_mod_m|regbase::mod_x|regbase::mod_s|regbase::no_mod_s|regbase::no_escape_in_lists|regbase::no_empty_expressions))
42 return -1;
43 break;
44 case regbase::basic:
45 result = REG_BASIC;
46 if(opts & (regbase::no_char_classes|regbase::no_intervals|regbase::bk_plus_qm|regbase::bk_vbar))
47 return -1;
48 if((opts & regbase::no_escape_in_lists) == 0)
49 return -1;
50 break;
51 default:
52 return -1;
53 }
54
55 if(opts & regbase::icase)
56 result |= REG_ICASE;
57 if(opts & regbase::nosubs)
58 result |= REG_NOSUB;
59 if(opts & regbase::newline_alt)
60 result |= REG_NEWLINE;
61 if((opts & regbase::collate) == 0)
62 result |= REG_NOCOLLATE;
63
64 return result;
65 }
66
get_posix_match_flags(boost::regex_constants::match_flag_type f)67 int get_posix_match_flags(boost::regex_constants::match_flag_type f)
68 {
69 int result = 0;
70 if(f & boost::regex_constants::match_not_bol)
71 result |= boost::REG_NOTBOL;
72 if(f & boost::regex_constants::match_not_eol)
73 result |= boost::REG_NOTEOL;
74 if(f & ~(boost::regex_constants::match_not_bol|boost::regex_constants::match_not_eol))
75 return -1;
76 return result;
77 }
78
test_deprecated(const char &,const test_regex_search_tag &)79 void test_deprecated(const char&, const test_regex_search_tag&)
80 {
81 const std::string& expression = test_info<char>::expression();
82 if(expression.find('\0') != std::string::npos)
83 return;
84 const std::string& search_text = test_info<char>::search_text();
85 if(search_text.find('\0') != std::string::npos)
86 return;
87 int posix_options = get_posix_compile_options(test_info<char>::syntax_options());
88 if(posix_options < 0)
89 return;
90 int posix_match_options = get_posix_match_flags(test_info<char>::match_options());
91 if(posix_match_options < 0)
92 return;
93 const int* results = test_info<char>::answer_table();
94
95 // OK try and compile the expression:
96 boost::regex_tA re;
97 if(boost::regcompA(&re, expression.c_str(), posix_options) != 0)
98 {
99 BOOST_REGEX_TEST_ERROR("Expression : \"" << expression.c_str() << "\" did not compile with the POSIX C API.", char);
100 return;
101 }
102 // try and find the first occurance:
103 static const unsigned max_subs = 100;
104 boost::regmatch_t matches[max_subs];
105 if(boost::regexecA(&re, search_text.c_str(), max_subs, matches, posix_match_options) == 0)
106 {
107 int i = 0;
108 while(results[2*i] != -2)
109 {
110 if((int)max_subs > i)
111 {
112 if(results[2*i] != matches[i].rm_so)
113 {
114 BOOST_REGEX_TEST_ERROR("Mismatch in start of subexpression " << i << " found with the POSIX C API.", char);
115 }
116 if(results[2*i+1] != matches[i].rm_eo)
117 {
118 BOOST_REGEX_TEST_ERROR("Mismatch in end of subexpression " << i << " found with the POSIX C API.", char);
119 }
120 }
121 ++i;
122 }
123 }
124 else
125 {
126 if(results[0] >= 0)
127 {
128 BOOST_REGEX_TEST_ERROR("Expression : \"" << expression.c_str() << "\" was not found with the POSIX C API.", char);
129 }
130 }
131 // clean up whatever:
132 boost::regfreeA(&re);
133
134 //
135 // now try the RegEx class:
136 //
137 if(test_info<char>::syntax_options() & ~boost::regex::icase)
138 return;
139 #ifndef BOOST_NO_EXCEPTIONS
140 try
141 #endif
142 {
143 boost::RegEx e(expression, (test_info<char>::syntax_options() & boost::regex::icase) != 0);
144 if(e.error_code())
145 {
146 BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done, error code = " << e.error_code(), char);
147 }
148 if(e.Search(search_text, test_info<char>::match_options()))
149 {
150 int i = 0;
151 while(results[i*2] != -2)
152 {
153 if(e.Matched(i))
154 {
155 if(results[2*i] != static_cast<int>(e.Position(i)))
156 {
157 BOOST_REGEX_TEST_ERROR("Mismatch in start of subexpression " << i << " found with the RegEx class (found " << e.Position(i) << " expected " << results[2*i] << ").", char);
158 }
159 if(results[2*i+1] != static_cast<int>(e.Position(i) + e.Length(i)))
160 {
161 BOOST_REGEX_TEST_ERROR("Mismatch in end of subexpression " << i << " found with the RegEx class (found " << e.Position(i) + e.Length(i) << " expected " << results[2*i+1] << ").", char);
162 }
163 }
164 else
165 {
166 if(results[2*i] >= 0)
167 {
168 BOOST_REGEX_TEST_ERROR("Mismatch in start of subexpression " << i << " found with the RegEx class (found " << e.Position(i) << " expected " << results[2*i] << ").", char);
169 }
170 if(results[2*i+1] >= 0)
171 {
172 BOOST_REGEX_TEST_ERROR("Mismatch in end of subexpression " << i << " found with the RegEx class (found " << e.Position(i) + e.Length(i) << " expected " << results[2*i+1] << ").", char);
173 }
174 }
175 ++i;
176 }
177 }
178 else
179 {
180 if(results[0] >= 0)
181 {
182 BOOST_REGEX_TEST_ERROR("Expression : \"" << expression.c_str() << "\" was not found with class RegEx.", char);
183 }
184 }
185 }
186 #ifndef BOOST_NO_EXCEPTIONS
187 catch(const boost::bad_expression& r)
188 {
189 BOOST_REGEX_TEST_ERROR("Expression did not compile with RegEx class: " << r.what(), char);
190 }
191 catch(const std::runtime_error& r)
192 {
193 BOOST_REGEX_TEST_ERROR("Unexpected std::runtime_error : " << r.what(), char);
194 }
195 catch(const std::exception& r)
196 {
197 BOOST_REGEX_TEST_ERROR("Unexpected std::exception: " << r.what(), char);
198 }
199 catch(...)
200 {
201 BOOST_REGEX_TEST_ERROR("Unexpected exception of unknown type", char);
202 }
203 #endif
204 }
205
test_deprecated(const wchar_t &,const test_regex_search_tag &)206 void test_deprecated(const wchar_t&, const test_regex_search_tag&)
207 {
208 #ifndef BOOST_NO_WREGEX
209 const std::wstring& expression = test_info<wchar_t>::expression();
210 if(expression.find(L'\0') != std::wstring::npos)
211 return;
212 const std::wstring& search_text = test_info<wchar_t>::search_text();
213 if(search_text.find(L'\0') != std::wstring::npos)
214 return;
215 int posix_options = get_posix_compile_options(test_info<wchar_t>::syntax_options());
216 if(posix_options < 0)
217 return;
218 int posix_match_options = get_posix_match_flags(test_info<wchar_t>::match_options());
219 if(posix_match_options < 0)
220 return;
221 const int* results = test_info<wchar_t>::answer_table();
222
223 // OK try and compile the expression:
224 boost::regex_tW re;
225 if(boost::regcompW(&re, expression.c_str(), posix_options) != 0)
226 {
227 BOOST_REGEX_TEST_ERROR("Expression : \"" << expression.c_str() << "\" did not compile with the POSIX C API.", wchar_t);
228 return;
229 }
230 // try and find the first occurance:
231 static const unsigned max_subs = 100;
232 boost::regmatch_t matches[max_subs];
233 if(boost::regexecW(&re, search_text.c_str(), max_subs, matches, posix_match_options) == 0)
234 {
235 int i = 0;
236 while(results[2*i] != -2)
237 {
238 if((int)max_subs > i)
239 {
240 if(results[2*i] != matches[i].rm_so)
241 {
242 BOOST_REGEX_TEST_ERROR("Mismatch in start of subexpression " << i << " found with the POSIX C API.", wchar_t);
243 }
244 if(results[2*i+1] != matches[i].rm_eo)
245 {
246 BOOST_REGEX_TEST_ERROR("Mismatch in end of subexpression " << i << " found with the POSIX C API.", wchar_t);
247 }
248 }
249 ++i;
250 }
251 }
252 else
253 {
254 if(results[0] >= 0)
255 {
256 BOOST_REGEX_TEST_ERROR("Expression : \"" << expression.c_str() << "\" was not found with the POSIX C API.", wchar_t);
257 }
258 }
259 // clean up whatever:
260 boost::regfreeW(&re);
261 #endif
262 }
263
test_deprecated(const char &,const test_invalid_regex_tag &)264 void test_deprecated(const char&, const test_invalid_regex_tag&)
265 {
266 const std::string& expression = test_info<char>::expression();
267 if(expression.find('\0') != std::string::npos)
268 return;
269 int posix_options = get_posix_compile_options(test_info<char>::syntax_options());
270 if(posix_options < 0)
271 return;
272
273 // OK try and compile the expression:
274 boost::regex_tA re;
275 int code = boost::regcompA(&re, expression.c_str(), posix_options);
276 if(code == 0)
277 {
278 boost::regfreeA(&re);
279 BOOST_REGEX_TEST_ERROR("Expression : \"" << expression.c_str() << "\" unexpectedly compiled with the POSIX C API.", char);
280 }
281 else
282 {
283 char buf[100];
284 int s = boost::regerrorA(code, &re, 0, 0);
285 if(s < 100)
286 s = boost::regerrorA(code, &re, buf, 100);
287 s = boost::regerrorA(code | boost::REG_ITOA, &re, 0, 0);
288 if(s < 100)
289 {
290 s = boost::regerrorA(code | boost::REG_ITOA, &re, buf, 100);
291 re.re_endp = buf;
292 s = boost::regerrorA(code | boost::REG_ATOI, &re, buf, 100);
293 if(s)
294 {
295 int code2 = std::atoi(buf);
296 if(code2 != code)
297 {
298 BOOST_REGEX_TEST_ERROR("Got a bad error code from regerrA with REG_ATOI set: ", char);
299 }
300 }
301 }
302 }
303 //
304 // now try the RegEx class:
305 //
306 if(test_info<char>::syntax_options() & ~boost::regex::icase)
307 return;
308 bool have_catch = false;
309 #ifndef BOOST_NO_EXCEPTIONS
310 try
311 #endif
312 {
313 boost::RegEx e(expression, (test_info<char>::syntax_options() & boost::regex::icase) != 0);
314 if(e.error_code())
315 have_catch = true;
316 }
317 #ifndef BOOST_NO_EXCEPTIONS
318 catch(const boost::bad_expression&)
319 {
320 have_catch = true;
321 }
322 catch(const std::runtime_error& r)
323 {
324 have_catch = true;
325 BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but a std::runtime_error instead: " << r.what(), char);
326 }
327 catch(const std::exception& r)
328 {
329 have_catch = true;
330 BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but a std::exception instead: " << r.what(), char);
331 }
332 catch(...)
333 {
334 have_catch = true;
335 BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but got an exception of unknown type instead", char);
336 }
337 #endif
338 if(!have_catch)
339 {
340 // oops expected exception was not thrown:
341 BOOST_REGEX_TEST_ERROR("Expected an exception, but didn't find one.", char);
342 }
343 }
344
test_deprecated(const wchar_t &,const test_invalid_regex_tag &)345 void test_deprecated(const wchar_t&, const test_invalid_regex_tag&)
346 {
347 #ifndef BOOST_NO_WREGEX
348 const std::wstring& expression = test_info<wchar_t>::expression();
349 if(expression.find(L'\0') != std::string::npos)
350 return;
351 int posix_options = get_posix_compile_options(test_info<wchar_t>::syntax_options());
352 if(posix_options < 0)
353 return;
354
355 // OK try and compile the expression:
356 boost::regex_tW re;
357 int code = boost::regcompW(&re, expression.c_str(), posix_options);
358 if(code == 0)
359 {
360 boost::regfreeW(&re);
361 BOOST_REGEX_TEST_ERROR("Expression : \"" << expression.c_str() << "\" unexpectedly compiled with the POSIX C API.", wchar_t);
362 }
363 else
364 {
365 wchar_t buf[100];
366 int s = boost::regerrorW(code, &re, 0, 0);
367 if(s < 100)
368 s = boost::regerrorW(code, &re, buf, 100);
369 s = boost::regerrorW(code | boost::REG_ITOA, &re, 0, 0);
370 if(s < 100)
371 {
372 s = boost::regerrorW(code | boost::REG_ITOA, &re, buf, 100);
373 re.re_endp = buf;
374 s = boost::regerrorW(code | boost::REG_ATOI, &re, buf, 100);
375 if(s)
376 {
377 long code2 = std::wcstol(buf, 0, 10);
378 if(code2 != code)
379 {
380 BOOST_REGEX_TEST_ERROR("Got a bad error code from regerrW with REG_ATOI set: ", char);
381 }
382 }
383 }
384 }
385 #endif
386 }
387