123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- ///////////////////////////////////////////////////////////////////////////////
- // test_cycles.hpp
- //
- // Copyright 2008 Eric Niebler. Distributed under the Boost
- // Software License, Version 1.0. (See accompanying file
- // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- // defining this causes regex_impl objects to be counted, allowing us to detect
- // leaks portably.
- #define BOOST_XPRESSIVE_DEBUG_CYCLE_TEST
- #include <iostream>
- #include <boost/test/unit_test.hpp>
- #include <boost/xpressive/xpressive.hpp>
- #if defined(_MSC_VER) && defined(_DEBUG)
- # define _CRTDBG_MAP_ALLOC
- # include <crtdbg.h>
- #endif
- using namespace boost::unit_test;
- using namespace boost::xpressive;
- ///////////////////////////////////////////////////////////////////////////////
- // test_main
- // regexes referred to by other regexes are kept alive via reference counting.
- // but cycles are handled naturally. the following works as expected and doesn't leak.
- void test_main()
- {
- {
- sregex v;
- {
- sregex a,b,c;
- a = 'a' >> !by_ref(b);
- //std::cout << a << std::endl;
- //std::cout << b << std::endl;
- //std::cout << c << std::endl;
- // just for giggles
- c = a;
- c = epsilon >> 'a';
- b = epsilon >> by_ref(c);
- //std::cout << a << std::endl;
- //std::cout << b << std::endl;
- //std::cout << c << std::endl;
- c = epsilon >> by_ref(a);
- //std::cout << a << std::endl;
- //std::cout << b << std::endl;
- //std::cout << c << std::endl;
- v = a;
- }
- std::string const s("aaa");
- smatch m;
- if(!regex_match(s, m, v))
- {
- BOOST_ERROR("cycle test 1 failed");
- }
- }
- if(0 != detail::regex_impl<std::string::const_iterator>::instances)
- {
- BOOST_ERROR("leaks detected (cycle test 1)");
- detail::regex_impl<std::string::const_iterator>::instances = 0;
- }
- {
- sregex v;
- {
- sregex a,b,c;
- b = epsilon >> by_ref(c);
- a = 'a' >> !by_ref(b);
- c = epsilon >> by_ref(a);
- //std::cout << a << std::endl;
- //std::cout << b << std::endl;
- //std::cout << c << std::endl;
- v = a;
- }
- std::string const s("aaa");
- smatch m;
- if(!regex_match(s, m, v))
- {
- BOOST_ERROR("cycle test 2 failed");
- }
- }
- if(0 != detail::regex_impl<std::string::const_iterator>::instances)
- {
- BOOST_ERROR("leaks detected (cycle test 2)");
- detail::regex_impl<std::string::const_iterator>::instances = 0;
- }
- {
- sregex v;
- {
- sregex a,b,c;
- b = epsilon >> by_ref(c);
- c = epsilon >> by_ref(a);
- a = 'a' >> !by_ref(b);
- //std::cout << a << std::endl;
- //std::cout << b << std::endl;
- //std::cout << c << std::endl;
- v = a;
- }
- std::string const s("aaa");
- smatch m;
- if(!regex_match(s, m, v))
- {
- BOOST_ERROR("cycle test 3 failed");
- }
- }
- if(0 != detail::regex_impl<std::string::const_iterator>::instances)
- {
- BOOST_ERROR("leaks detected (cycle test 3)");
- detail::regex_impl<std::string::const_iterator>::instances = 0;
- }
- {
- sregex v;
- {
- sregex a,b,c;
- c = epsilon >> by_ref(a);
- b = epsilon >> by_ref(c);
- a = 'a' >> !by_ref(b);
- //std::cout << a << std::endl;
- //std::cout << b << std::endl;
- //std::cout << c << std::endl;
- v = a;
- }
- std::string const s("aaa");
- smatch m;
- if(!regex_match(s, m, v))
- {
- BOOST_ERROR("cycle test 4 failed");
- }
- }
- if(0 != detail::regex_impl<std::string::const_iterator>::instances)
- {
- BOOST_ERROR("leaks detected (cycle test 4)");
- detail::regex_impl<std::string::const_iterator>::instances = 0;
- }
- {
- sregex v;
- {
- sregex a,b,c;
- a = 'a' >> !by_ref(b);
- b = epsilon >> by_ref(c);
- c = epsilon >> by_ref(a);
- sregex d,e;
- d = epsilon >> by_ref(e);
- e = epsilon >> "aa";
- c = d;
- //std::cout << a << std::endl;
- //std::cout << b << std::endl;
- //std::cout << c << std::endl;
- //std::cout << e << std::endl;
- e = 'a' >> by_ref(c);
- //std::cout << "-new loop!\n";
- //std::cout << a << std::endl;
- //std::cout << b << std::endl;
- //std::cout << c << std::endl;
- //std::cout << e << std::endl;
- v = a;
- //std::cout << v << std::endl;
- }
- std::string const s("aaa");
- smatch m;
- if(regex_match(s, m, v)) // OK, this shouldn't match
- {
- BOOST_ERROR("cycle test 5 failed");
- }
- }
- if(0 != detail::regex_impl<std::string::const_iterator>::instances)
- {
- BOOST_ERROR("leaks detected (cycle test 5)");
- detail::regex_impl<std::string::const_iterator>::instances = 0;
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // init_unit_test_suite
- //
- test_suite* init_unit_test_suite( int argc, char* argv[] )
- {
- test_suite *test = BOOST_TEST_SUITE("test_cycles");
- test->add(BOOST_TEST_CASE(&test_main));
- return test;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Debug stuff
- //
- namespace
- {
- const struct debug_init
- {
- debug_init()
- {
- #ifdef _MSC_VER
- // Send warnings, errors and asserts to STDERR
- _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
- _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
- _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
- _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
- _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
- _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
- // Check for leaks at program termination
- _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
- //_CrtSetBreakAlloc(221);
- #endif
- }
- } dbg;
- }
|