test_deprecated.cpp 12 KB

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