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_mfc.cpp
15 * VERSION see <boost/version.hpp>
16 * DESCRIPTION: Test code for MFC/ATL strings with Boost.Regex.
17 */
18
19 //
20 // We can only build this if we have ATL support:
21 //
22 #include <boost/config.hpp>
23
24 #ifdef TEST_MFC
25
26 #include <boost/regex/mfc.hpp>
27 #include "test.hpp"
28 #include "atlstr.h"
29
30 #pragma warning(disable:4267)
31
test_mfc(const char &,const test_regex_search_tag &)32 void test_mfc(const char&, const test_regex_search_tag&)
33 {
34 const std::string& ss = test_info<char>::search_text();
35 const std::string& ss2 = test_info<char>::expression();
36 CAtlStringA s(ss.c_str(), ss.size());
37 CAtlStringA s2(ss2.c_str(), ss2.size());
38 boost::regex_constants::match_flag_type opts = test_info<char>::match_options();
39 const int* answer_table = test_info<char>::answer_table();
40 boost::regex r = boost::make_regex(s2, test_info<char>::syntax_options());
41 boost::cmatch what;
42 if(boost::regex_search(
43 s,
44 what,
45 r,
46 opts))
47 {
48 test_result(what, s.GetString(), answer_table);
49 }
50 else if(answer_table[0] >= 0)
51 {
52 // we should have had a match but didn't:
53 BOOST_REGEX_TEST_ERROR("Expected match was not found.", char);
54 }
55 //
56 // regex_match tests:
57 //
58 if(answer_table[0] < 0)
59 {
60 if(boost::regex_match(s, r, opts))
61 {
62 BOOST_REGEX_TEST_ERROR("boost::regex_match found a match when it should not have done so.", char);
63 }
64 }
65 else
66 {
67 if((answer_table[0] > 0) && boost::regex_match(s, r, opts))
68 {
69 BOOST_REGEX_TEST_ERROR("boost::regex_match found a match when it should not have done so.", char);
70 }
71 else if((answer_table[0] == 0) && (answer_table[1] == static_cast<int>(ss.size())))
72 {
73 if(boost::regex_match(
74 s,
75 what,
76 r,
77 opts))
78 {
79 test_result(what, s.GetString(), answer_table);
80 if(!boost::regex_match(s, r, opts))
81 {
82 // we should have had a match but didn't:
83 BOOST_REGEX_TEST_ERROR("Expected match was not found.", char);
84 }
85 }
86 else if(answer_table[0] >= 0)
87 {
88 // we should have had a match but didn't:
89 BOOST_REGEX_TEST_ERROR("Expected match was not found.", char);
90 }
91 }
92 }
93 //
94 // test regex_iterator:
95 //
96 boost::cregex_iterator start(boost::make_regex_iterator(s, r, opts)), end;
97 boost::cregex_iterator copy(start);
98 while(start != end)
99 {
100 if(start != copy)
101 {
102 BOOST_REGEX_TEST_ERROR("Failed iterator != comparison.", char);
103 }
104 if(!(start == copy))
105 {
106 BOOST_REGEX_TEST_ERROR("Failed iterator == comparison.", char);
107 }
108 test_result(*start, s.GetString(), answer_table);
109 ++start;
110 ++copy;
111 // move on the answer table to next set of answers;
112 if(*answer_table != -2)
113 while(*answer_table++ != -2){}
114 }
115 if(answer_table[0] >= 0)
116 {
117 // we should have had a match but didn't:
118 BOOST_REGEX_TEST_ERROR("Expected match was not found.", char);
119 }
120 //
121 // test regex_token_iterator:
122 //
123 typedef boost::regex_token_iterator<const char*> token_iterator;
124 answer_table = test_info<char>::answer_table();
125 //
126 // we start by testing sub-expression 0:
127 //
128 token_iterator tstart(boost::make_regex_token_iterator(s, r, 0, opts)), tend;
129 token_iterator tcopy(tstart);
130 while(tstart != tend)
131 {
132 if(tstart != tcopy)
133 {
134 BOOST_REGEX_TEST_ERROR("Failed iterator != comparison.", char);
135 }
136 if(!(tstart == tcopy))
137 {
138 BOOST_REGEX_TEST_ERROR("Failed iterator == comparison.", char);
139 }
140 test_sub_match(*tstart, s.GetString(), answer_table, 0);
141 ++tstart;
142 ++tcopy;
143 // move on the answer table to next set of answers;
144 if(*answer_table != -2)
145 while(*answer_table++ != -2){}
146 }
147 if(answer_table[0] >= 0)
148 {
149 // we should have had a match but didn't:
150 BOOST_REGEX_TEST_ERROR("Expected match was not found.", char);
151 }
152 //
153 // and now field spitting:
154 //
155 token_iterator tstart2(boost::make_regex_token_iterator(s, r, -1, opts)), tend2;
156 token_iterator tcopy2(tstart2);
157 int last_end2 = 0;
158 answer_table = test_info<char>::answer_table();
159 while(tstart2 != tend2)
160 {
161 if(tstart2 != tcopy2)
162 {
163 BOOST_REGEX_TEST_ERROR("Failed iterator != comparison.", char);
164 }
165 if(!(tstart2 == tcopy2))
166 {
167 BOOST_REGEX_TEST_ERROR("Failed iterator == comparison.", char);
168 }
169 #ifdef BOOST_MSVC
170 #pragma warning(push)
171 #pragma warning(disable:4244)
172 #endif
173 if(boost::BOOST_REGEX_DETAIL_NS::distance(s.GetString(), tstart2->first) != last_end2)
174 {
175 BOOST_REGEX_TEST_ERROR(
176 "Error in location of start of field split, found: "
177 << boost::BOOST_REGEX_DETAIL_NS::distance(s.GetString(), tstart2->first)
178 << ", expected: "
179 << last_end2
180 << ".", char);
181 }
182 int expected_end = static_cast<int>(answer_table[0] < 0 ? s.GetLength() : answer_table[0]);
183 if(boost::BOOST_REGEX_DETAIL_NS::distance(s.GetString(), tstart2->second) != expected_end)
184 {
185 BOOST_REGEX_TEST_ERROR(
186 "Error in location of end2 of field split, found: "
187 << boost::BOOST_REGEX_DETAIL_NS::distance(s.GetString(), tstart2->second)
188 << ", expected: "
189 << expected_end
190 << ".", char);
191 }
192 #ifdef BOOST_MSVC
193 #pragma warning(pop)
194 #endif
195 last_end2 = answer_table[1];
196 ++tstart2;
197 ++tcopy2;
198 // move on the answer table to next set of answers;
199 if(*answer_table != -2)
200 while(*answer_table++ != -2){}
201 }
202 if(answer_table[0] >= 0)
203 {
204 // we should have had a match but didn't:
205 BOOST_REGEX_TEST_ERROR("Expected match was not found.", char);
206 }
207
208 }
209
test_mfc(const wchar_t &,const test_regex_search_tag &)210 void test_mfc(const wchar_t&, const test_regex_search_tag&)
211 {
212 const std::wstring& ss = test_info<wchar_t>::search_text();
213 const std::wstring& ss2 = test_info<wchar_t>::expression();
214 CAtlStringW s(ss.c_str(), ss.size());
215 CAtlStringW s2(ss2.c_str(), ss2.size());
216 boost::regex_constants::match_flag_type opts = test_info<wchar_t>::match_options();
217 const int* answer_table = test_info<wchar_t>::answer_table();
218 boost::wregex r = boost::make_regex(s2, test_info<wchar_t>::syntax_options());
219 boost::wcmatch what;
220 if(boost::regex_search(
221 s,
222 what,
223 r,
224 opts))
225 {
226 test_result(what, s.GetString(), answer_table);
227 }
228 else if(answer_table[0] >= 0)
229 {
230 // we should have had a match but didn't:
231 BOOST_REGEX_TEST_ERROR("Expected match was not found.", wchar_t);
232 }
233 //
234 // regex_match tests:
235 //
236 if(answer_table[0] < 0)
237 {
238 if(boost::regex_match(s, r, opts))
239 {
240 BOOST_REGEX_TEST_ERROR("boost::regex_match found a match when it should not have done so.", wchar_t);
241 }
242 }
243 else
244 {
245 if((answer_table[0] > 0) && boost::regex_match(s, r, opts))
246 {
247 BOOST_REGEX_TEST_ERROR("boost::regex_match found a match when it should not have done so.", wchar_t);
248 }
249 else if((answer_table[0] == 0) && (answer_table[1] == static_cast<int>(ss.size())))
250 {
251 if(boost::regex_match(
252 s,
253 what,
254 r,
255 opts))
256 {
257 test_result(what, s.GetString(), answer_table);
258 if(!boost::regex_match(s, r, opts))
259 {
260 // we should have had a match but didn't:
261 BOOST_REGEX_TEST_ERROR("Expected match was not found.", wchar_t);
262 }
263 }
264 else if(answer_table[0] >= 0)
265 {
266 // we should have had a match but didn't:
267 BOOST_REGEX_TEST_ERROR("Expected match was not found.", wchar_t);
268 }
269 }
270 }
271 //
272 // test regex_iterator:
273 //
274 boost::wcregex_iterator start(boost::make_regex_iterator(s, r, opts)), end;
275 boost::wcregex_iterator copy(start);
276 while(start != end)
277 {
278 if(start != copy)
279 {
280 BOOST_REGEX_TEST_ERROR("Failed iterator != comparison.", wchar_t);
281 }
282 if(!(start == copy))
283 {
284 BOOST_REGEX_TEST_ERROR("Failed iterator == comparison.", wchar_t);
285 }
286 test_result(*start, s.GetString(), answer_table);
287 ++start;
288 ++copy;
289 // move on the answer table to next set of answers;
290 if(*answer_table != -2)
291 while(*answer_table++ != -2){}
292 }
293 if(answer_table[0] >= 0)
294 {
295 // we should have had a match but didn't:
296 BOOST_REGEX_TEST_ERROR("Expected match was not found.", wchar_t);
297 }
298 //
299 // test regex_token_iterator:
300 //
301 typedef boost::regex_token_iterator<const wchar_t*> token_iterator;
302 answer_table = test_info<wchar_t>::answer_table();
303 //
304 // we start by testing sub-expression 0:
305 //
306 token_iterator tstart(boost::make_regex_token_iterator(s, r, 0, opts)), tend;
307 token_iterator tcopy(tstart);
308 while(tstart != tend)
309 {
310 if(tstart != tcopy)
311 {
312 BOOST_REGEX_TEST_ERROR("Failed iterator != comparison.", wchar_t);
313 }
314 if(!(tstart == tcopy))
315 {
316 BOOST_REGEX_TEST_ERROR("Failed iterator == comparison.", wchar_t);
317 }
318 test_sub_match(*tstart, s.GetString(), answer_table, 0);
319 ++tstart;
320 ++tcopy;
321 // move on the answer table to next set of answers;
322 if(*answer_table != -2)
323 while(*answer_table++ != -2){}
324 }
325 if(answer_table[0] >= 0)
326 {
327 // we should have had a match but didn't:
328 BOOST_REGEX_TEST_ERROR("Expected match was not found.", wchar_t);
329 }
330 //
331 // and now field spitting:
332 //
333 token_iterator tstart2(boost::make_regex_token_iterator(s, r, -1, opts)), tend2;
334 token_iterator tcopy2(tstart2);
335 int last_end2 = 0;
336 answer_table = test_info<wchar_t>::answer_table();
337 while(tstart2 != tend2)
338 {
339 if(tstart2 != tcopy2)
340 {
341 BOOST_REGEX_TEST_ERROR("Failed iterator != comparison.", wchar_t);
342 }
343 if(!(tstart2 == tcopy2))
344 {
345 BOOST_REGEX_TEST_ERROR("Failed iterator == comparison.", wchar_t);
346 }
347 #ifdef BOOST_MSVC
348 #pragma warning(push)
349 #pragma warning(disable:4244)
350 #endif
351 if(boost::BOOST_REGEX_DETAIL_NS::distance(s.GetString(), tstart2->first) != last_end2)
352 {
353 BOOST_REGEX_TEST_ERROR(
354 "Error in location of start of field split, found: "
355 << boost::BOOST_REGEX_DETAIL_NS::distance(s.GetString(), tstart2->first)
356 << ", expected: "
357 << last_end2
358 << ".", wchar_t);
359 }
360 int expected_end = static_cast<int>(answer_table[0] < 0 ? s.GetLength() : answer_table[0]);
361 if(boost::BOOST_REGEX_DETAIL_NS::distance(s.GetString(), tstart2->second) != expected_end)
362 {
363 BOOST_REGEX_TEST_ERROR(
364 "Error in location of end2 of field split, found: "
365 << boost::BOOST_REGEX_DETAIL_NS::distance(s.GetString(), tstart2->second)
366 << ", expected: "
367 << expected_end
368 << ".", wchar_t);
369 }
370 #ifdef BOOST_MSVC
371 #pragma warning(pop)
372 #endif
373 last_end2 = answer_table[1];
374 ++tstart2;
375 ++tcopy2;
376 // move on the answer table to next set of answers;
377 if(*answer_table != -2)
378 while(*answer_table++ != -2){}
379 }
380 if(answer_table[0] >= 0)
381 {
382 // we should have had a match but didn't:
383 BOOST_REGEX_TEST_ERROR("Expected match was not found.", wchar_t);
384 }
385
386 }
387
test_mfc(const char &,const test_invalid_regex_tag &)388 void test_mfc(const char&, const test_invalid_regex_tag&)
389 {
390 std::string ss = test_info<char>::expression();
391 CAtlStringA s(ss.c_str(), ss.size());
392 bool have_catch = false;
393 try{
394 boost::regex e = boost::make_regex(s, test_info<char>::syntax_options());
395 if(e.error_code())
396 have_catch = true;
397 }
398 catch(const boost::bad_expression&)
399 {
400 have_catch = true;
401 }
402 catch(const std::runtime_error& r)
403 {
404 have_catch = true;
405 BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but a std::runtime_error instead: " << r.what(), char);
406 }
407 catch(const std::exception& r)
408 {
409 have_catch = true;
410 BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but a std::exception instead: " << r.what(), char);
411 }
412 catch(...)
413 {
414 have_catch = true;
415 BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but got an exception of unknown type instead", char);
416 }
417 if(!have_catch)
418 {
419 // oops expected exception was not thrown:
420 BOOST_REGEX_TEST_ERROR("Expected an exception, but didn't find one.", char);
421 }
422
423 }
424
test_mfc(const wchar_t &,const test_invalid_regex_tag &)425 void test_mfc(const wchar_t&, const test_invalid_regex_tag&)
426 {
427 std::wstring ss = test_info<wchar_t>::expression();
428 CAtlStringW s(ss.c_str(), ss.size());
429 bool have_catch = false;
430 try{
431 boost::wregex e = boost::make_regex(s, test_info<wchar_t>::syntax_options());
432 if(e.error_code())
433 have_catch = true;
434 }
435 catch(const boost::bad_expression&)
436 {
437 have_catch = true;
438 }
439 catch(const std::runtime_error& r)
440 {
441 have_catch = true;
442 BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but a std::runtime_error instead: " << r.what(), wchar_t);
443 }
444 catch(const std::exception& r)
445 {
446 have_catch = true;
447 BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but a std::exception instead: " << r.what(), wchar_t);
448 }
449 catch(...)
450 {
451 have_catch = true;
452 BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but got an exception of unknown type instead", wchar_t);
453 }
454 if(!have_catch)
455 {
456 // oops expected exception was not thrown:
457 BOOST_REGEX_TEST_ERROR("Expected an exception, but didn't find one.", wchar_t);
458 }
459 }
460
test_mfc(const char &,const test_regex_replace_tag &)461 void test_mfc(const char&, const test_regex_replace_tag&)
462 {
463 const CStringA expression(test_info<char>::expression().c_str(), test_info<char>::expression().size());
464 boost::regex_constants::syntax_option_type syntax_options = test_info<char>::syntax_options();
465 try{
466 boost::regex r = boost::make_regex(expression, syntax_options);
467 if(r.status())
468 {
469 BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done, error code = " << r.status(), char);
470 }
471 const CStringA search_text(test_info<char>::search_text().c_str(), test_info<char>::search_text().size());
472 boost::regex_constants::match_flag_type opts = test_info<char>::match_options();
473 const CStringA format_string(test_info<char>::format_string().c_str(), test_info<char>::format_string().size());
474 const CStringA result_string(test_info<char>::result_string().c_str(), test_info<char>::result_string().size());
475
476 CStringA result = boost::regex_replace(search_text, r, format_string, opts);
477 if(result != result_string)
478 {
479 BOOST_REGEX_TEST_ERROR("regex_replace generated an incorrect string result", char);
480 }
481 }
482 catch(const boost::bad_expression& e)
483 {
484 BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done: " << e.what(), char);
485 }
486 catch(const std::runtime_error& r)
487 {
488 BOOST_REGEX_TEST_ERROR("Received an unexpected std::runtime_error: " << r.what(), char);
489 }
490 catch(const std::exception& r)
491 {
492 BOOST_REGEX_TEST_ERROR("Received an unexpected std::exception: " << r.what(), char);
493 }
494 catch(...)
495 {
496 BOOST_REGEX_TEST_ERROR("Received an unexpected exception of unknown type", char);
497 }
498 }
499
test_mfc(const wchar_t &,const test_regex_replace_tag &)500 void test_mfc(const wchar_t&, const test_regex_replace_tag&)
501 {
502 const CStringW expression(test_info<wchar_t>::expression().c_str(), test_info<wchar_t>::expression().size());
503 boost::regex_constants::syntax_option_type syntax_options = test_info<wchar_t>::syntax_options();
504 try{
505 boost::wregex r = boost::make_regex(expression, syntax_options);
506 if(r.status())
507 {
508 BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done, error code = " << r.status(), wchar_t);
509 }
510 const CStringW search_text(test_info<wchar_t>::search_text().c_str(), test_info<wchar_t>::search_text().size());
511 boost::regex_constants::match_flag_type opts = test_info<wchar_t>::match_options();
512 const CStringW format_string(test_info<wchar_t>::format_string().c_str(), test_info<wchar_t>::format_string().size());
513 const CStringW result_string(test_info<wchar_t>::result_string().c_str(), test_info<wchar_t>::result_string().size());
514
515 CStringW result = boost::regex_replace(search_text, r, format_string, opts);
516 if(result != result_string)
517 {
518 BOOST_REGEX_TEST_ERROR("regex_replace generated an incorrect string result", wchar_t);
519 }
520 }
521 catch(const boost::bad_expression& e)
522 {
523 BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done: " << e.what(), wchar_t);
524 }
525 catch(const std::runtime_error& r)
526 {
527 BOOST_REGEX_TEST_ERROR("Received an unexpected std::runtime_error: " << r.what(), wchar_t);
528 }
529 catch(const std::exception& r)
530 {
531 BOOST_REGEX_TEST_ERROR("Received an unexpected std::exception: " << r.what(), wchar_t);
532 }
533 catch(...)
534 {
535 BOOST_REGEX_TEST_ERROR("Received an unexpected exception of unknown type", wchar_t);
536 }
537 }
538
539 #else
540
541 #include "test.hpp"
542
test_mfc(const char &,const test_regex_search_tag &)543 void test_mfc(const char&, const test_regex_search_tag&){}
test_mfc(const wchar_t &,const test_regex_search_tag &)544 void test_mfc(const wchar_t&, const test_regex_search_tag&){}
test_mfc(const char &,const test_invalid_regex_tag &)545 void test_mfc(const char&, const test_invalid_regex_tag&){}
test_mfc(const wchar_t &,const test_invalid_regex_tag &)546 void test_mfc(const wchar_t&, const test_invalid_regex_tag&){}
test_mfc(const char &,const test_regex_replace_tag &)547 void test_mfc(const char&, const test_regex_replace_tag&){}
test_mfc(const wchar_t &,const test_regex_replace_tag &)548 void test_mfc(const wchar_t&, const test_regex_replace_tag&){}
549
550
551 #endif
552