From 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 20:24:20 +0200 Subject: Adding upstream version 14.2.21. Signed-off-by: Daniel Baumann --- src/boost/libs/xpressive/test/test_actions.cpp | 287 +++++++++++++++++++++++++ 1 file changed, 287 insertions(+) create mode 100644 src/boost/libs/xpressive/test/test_actions.cpp (limited to 'src/boost/libs/xpressive/test/test_actions.cpp') diff --git a/src/boost/libs/xpressive/test/test_actions.cpp b/src/boost/libs/xpressive/test/test_actions.cpp new file mode 100644 index 00000000..44b443b5 --- /dev/null +++ b/src/boost/libs/xpressive/test/test_actions.cpp @@ -0,0 +1,287 @@ +/////////////////////////////////////////////////////////////////////////////// +// test_actions.cpp +// +// 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) + +//#define BOOST_XPRESSIVE_BETTER_ERRORS + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace xp = boost::xpressive; + +/////////////////////////////////////////////////////////////////////////////// +// test1 +// simple action which builds a string +void test1() +{ + using namespace boost::xpressive; + + std::string result; + std::string str("foo bar baz foo bar baz"); + sregex rx = (+_w)[ xp::ref(result) += _ ] >> *(' ' >> (+_w)[ xp::ref(result) += ',' + _ ]); + + if(!regex_match(str, rx)) + { + BOOST_ERROR("oops"); + } + else + { + BOOST_CHECK_EQUAL(result, "foo,bar,baz,foo,bar,baz"); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// test2 +// test backtracking over actions +void test2() +{ + using namespace boost::xpressive; + + std::string result; + std::string str("foo bar baz foo bar baz"); + sregex rx = (+_w)[ xp::ref(result) += _ ] >> *(' ' >> (+_w)[ xp::ref(result) += ',' + _ ]) >> repeat<4>(_); + + if(!regex_match(str, rx)) + { + BOOST_ERROR("oops"); + } + else + { + BOOST_CHECK_EQUAL(result, "foo,bar,baz,foo,bar"); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// test3 +// cast string to int, push back into list, use alternate ->* syntax +void test3() +{ + using namespace boost::xpressive; + + std::list result; + std::string str("1 23 456 7890"); +#if BOOST_VERSION >= 103500 + sregex rx = (+_d)[ xp::ref(result)->*push_back( as(_) ) ] + >> *(' ' >> (+_d)[ xp::ref(result)->*push_back( as(_) ) ]); +#else + sregex rx = (+_d)[ push_back(xp::ref(result), as(_) ) ] + >> *(' ' >> (+_d)[ push_back(xp::ref(result), as(_) ) ]); +#endif + + if(!regex_match(str, rx)) + { + BOOST_ERROR("oops"); + } + else + { + BOOST_REQUIRE_EQUAL(result.size(), 4u); + BOOST_CHECK_EQUAL(*result.begin(), 1); + BOOST_CHECK_EQUAL(*++result.begin(), 23); + BOOST_CHECK_EQUAL(*++++result.begin(), 456); + BOOST_CHECK_EQUAL(*++++++result.begin(), 7890); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// test4 +// build a map of strings to integers +void test4() +{ + using namespace boost::xpressive; + + std::map result; + std::string str("aaa=>1 bbb=>23 ccc=>456"); + sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) )[ xp::ref(result)[s1] = as(s2) ]; + sregex rx = pair >> *(+_s >> pair); + + if(!regex_match(str, rx)) + { + BOOST_ERROR("oops"); + } + else + { + BOOST_REQUIRE_EQUAL(result.size(), 3u); + BOOST_CHECK_EQUAL(result["aaa"], 1); + BOOST_CHECK_EQUAL(result["bbb"], 23); + BOOST_CHECK_EQUAL(result["ccc"], 456); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// test4_aux +// build a map of strings to integers, with a late-bound action argument. +void test4_aux() +{ + using namespace boost::xpressive; + placeholder< std::map > const _map = {{}}; + + sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) )[ _map[s1] = as(s2) ]; + sregex rx = pair >> *(+_s >> pair); + + std::string str("aaa=>1 bbb=>23 ccc=>456"); + smatch what; + std::map result; + what.let(_map = result); // bind the argument! + + BOOST_REQUIRE(regex_match(str, what, rx)); + BOOST_REQUIRE_EQUAL(result.size(), 3u); + BOOST_CHECK_EQUAL(result["aaa"], 1); + BOOST_CHECK_EQUAL(result["bbb"], 23); + BOOST_CHECK_EQUAL(result["ccc"], 456); + + // Try the same test with regex_iterator + result.clear(); + sregex_iterator it(str.begin(), str.end(), pair, let(_map=result)), end; + BOOST_REQUIRE_EQUAL(3, std::distance(it, end)); + BOOST_REQUIRE_EQUAL(result.size(), 3u); + BOOST_CHECK_EQUAL(result["aaa"], 1); + BOOST_CHECK_EQUAL(result["bbb"], 23); + BOOST_CHECK_EQUAL(result["ccc"], 456); + + // Try the same test with regex_token_iterator + result.clear(); + sregex_token_iterator it2(str.begin(), str.end(), pair, (s1,s2), let(_map=result)), end2; + BOOST_REQUIRE_EQUAL(6, std::distance(it2, end2)); + BOOST_REQUIRE_EQUAL(result.size(), 3u); + BOOST_CHECK_EQUAL(result["aaa"], 1); + BOOST_CHECK_EQUAL(result["bbb"], 23); + BOOST_CHECK_EQUAL(result["ccc"], 456); +} + +/////////////////////////////////////////////////////////////////////////////// +// test5 +// calculator that calculates. This is just silly, but hey. +void test5() +{ + using namespace boost::xpressive; + + // test for "local" variables. + local left, right; + + // test for reference<> to an existing variable + std::stack stack_; + reference > stack(stack_); + + std::string str("4+5*(3-1)"); + + sregex group, factor, term, expression; + + group = '(' >> by_ref(expression) >> ')'; + factor = (+_d)[ push(stack, as(_)) ] | group; + term = factor >> *( + ('*' >> factor) + [ right = top(stack) + , pop(stack) + , left = top(stack) + , pop(stack) + , push(stack, left * right) + ] + | ('/' >> factor) + [ right = top(stack) + , pop(stack) + , left = top(stack) + , pop(stack) + , push(stack, left / right) + ] + ); + expression = term >> *( + ('+' >> term) + [ right = top(stack) + , pop(stack) + , left = top(stack) + , pop(stack) + , push(stack, left + right) + ] + | ('-' >> term) + [ right = top(stack) + , pop(stack) + , left = top(stack) + , pop(stack) + , push(stack, left - right) + ] + ); + + if(!regex_match(str, expression)) + { + BOOST_ERROR("oops"); + } + else + { + BOOST_REQUIRE_EQUAL(stack_.size(), 1u); + BOOST_CHECK_EQUAL(stack_.top(), 14); + + BOOST_REQUIRE_EQUAL(stack.get().size(), 1u); + BOOST_CHECK_EQUAL(stack.get().top(), 14); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// test6 +// Test as<>() with wide strings. Bug #4496. +void test6() +{ + using namespace boost::xpressive; + + std::wstring version(L"0.9.500"); + + local maj1(0), min1(0), build1(0); + + wsregex re1 = (+_d)[maj1 = as(_)] >> L"." >> + (+_d)[min1 = as(_)] >> L"." >> + (+_d)[build1 = as(_)]; + + BOOST_REQUIRE(regex_match(version, re1)); + + BOOST_CHECK_EQUAL(maj1.get(), 0); + BOOST_CHECK_EQUAL(min1.get(), 9); + BOOST_CHECK_EQUAL(build1.get(), 500); +} + +/////////////////////////////////////////////////////////////////////////////// +// test7 +// Test regex_replace with an xpressive lambda +void test7() +{ + namespace xp = boost::xpressive; + using namespace xp; + + std::map env; + env["XXX"] = "!!!"; + env["YYY"] = "???"; + + std::string text("This is a %XXX% string %YYY% and stuff."); + sregex var = '%' >> (s1 = +_w) >> '%'; + + text = regex_replace(text, var, xp::ref(env)[s1]); + + BOOST_CHECK_EQUAL(text, "This is a !!! string ??? and stuff."); +} + +using namespace boost::unit_test; + +/////////////////////////////////////////////////////////////////////////////// +// init_unit_test_suite +// +test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + test_suite *test = BOOST_TEST_SUITE("test_actions"); + test->add(BOOST_TEST_CASE(&test1)); + test->add(BOOST_TEST_CASE(&test2)); + test->add(BOOST_TEST_CASE(&test3)); + test->add(BOOST_TEST_CASE(&test4)); + test->add(BOOST_TEST_CASE(&test4_aux)); + test->add(BOOST_TEST_CASE(&test5)); + test->add(BOOST_TEST_CASE(&test6)); + test->add(BOOST_TEST_CASE(&test7)); + return test; +} + -- cgit v1.2.3