• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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