/////////////////////////////////////////////////////////////////////////////// // test_cycles.hpp // // Copyright 2004 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 #ifdef _MSC_VER # include #endif #include #include #include "./test_minimal.hpp" 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. int test_main( int, char*[] ) { { 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::instances) { BOOST_ERROR("leaks detected (cycle test 1)"); } { 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::instances) { BOOST_ERROR("leaks detected (cycle test 2)"); } { 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::instances) { BOOST_ERROR("leaks detected (cycle test 3)"); } { 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::instances) { BOOST_ERROR("leaks detected (cycle test 4)"); } { 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::instances) { BOOST_ERROR("leaks detected (cycle test 5)"); } return 0; } /////////////////////////////////////////////////////////////////////////////// // 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; }