diff options
Diffstat (limited to 'src/boost/libs/xpressive/test/test_cycles.cpp')
-rw-r--r-- | src/boost/libs/xpressive/test/test_cycles.cpp | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/src/boost/libs/xpressive/test/test_cycles.cpp b/src/boost/libs/xpressive/test/test_cycles.cpp new file mode 100644 index 000000000..844d2ea35 --- /dev/null +++ b/src/boost/libs/xpressive/test/test_cycles.cpp @@ -0,0 +1,236 @@ +/////////////////////////////////////////////////////////////////////////////// +// 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; +} |