/*============================================================================= Copyright (c) 2004 Stefan Slapeta Copyright (c) 2002-2003 Martin Wille http://spirit.sourceforge.net/ Use, modification and distribution is subject to 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) =============================================================================*/ // vi:ts=4:sw=4:et // Tests for BOOST_SPIRIT_CLASSIC_NS::if_p // [28-Dec-2002] //////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include "impl/string_length.hpp" namespace local { template struct var_wrapper : public ::boost::reference_wrapper { typedef ::boost::reference_wrapper parent; explicit inline var_wrapper(T& t) : parent(t) {} inline T& operator()() const { return parent::get(); } }; template inline var_wrapper var(T& t) { return var_wrapper(t); } } typedef ::BOOST_SPIRIT_CLASSIC_NS::rule<> rule_t; typedef ::BOOST_SPIRIT_CLASSIC_NS::rule::type > no_actions_rule_t; unsigned int test_count = 0; unsigned int error_count = 0; unsigned int number_result; static const unsigned int kError = 999; static const bool good = true; static const bool bad = false; rule_t hex_prefix; no_actions_rule_t oct_prefix; rule_t hex_rule, oct_rule, dec_rule; rule_t auto_number_rule; rule_t hex_or_dec_number_rule; void test_number(char const *s, unsigned int wanted, rule_t const &r) { using namespace std; ++test_count; number_result = wanted-1; ::BOOST_SPIRIT_CLASSIC_NS::parse_info<> m = ::BOOST_SPIRIT_CLASSIC_NS::parse(s, s + test_impl::string_length(s), r); bool result = wanted == kError?(m.full?bad:good): (number_result==wanted); if (m.full && (m.length != test_impl::string_length(s))) result = bad; if (result==good) cout << "PASSED"; else { ++error_count; cout << "FAILED"; } cout << ": \"" << s << "\" ==> "; if (number_result==wanted-1) cout << ""; else cout << number_result; cout << "\n"; } void test_enclosed_fail() { using namespace std; using ::BOOST_SPIRIT_CLASSIC_NS::if_p; using ::BOOST_SPIRIT_CLASSIC_NS::str_p; using ::BOOST_SPIRIT_CLASSIC_NS::nothing_p; cout << "\nfail enclosed parser:\n"; const char *p = "abc"; ::BOOST_SPIRIT_CLASSIC_NS::strlit success_p = str_p(p); ::BOOST_SPIRIT_CLASSIC_NS::strlit fail_p = str_p("xxx"); ::BOOST_SPIRIT_CLASSIC_NS::rule<> r = if_p(success_p)[nothing_p]; ::BOOST_SPIRIT_CLASSIC_NS::parse_info<> m = ::BOOST_SPIRIT_CLASSIC_NS::parse(p, r); if (m.full) { cout << "FAILED: if --> match" << endl; ++error_count; } else { cout << "PASSED: if --> no_match" << endl; } r = if_p(fail_p)[success_p].else_p[nothing_p]; m = ::BOOST_SPIRIT_CLASSIC_NS::parse(p, r); if (m.full) { cout << "FAILED: else --> match" << endl; ++error_count; } else { cout << "PASSED: else --> no_match" << endl; } } int main() { using namespace std; using ::BOOST_SPIRIT_CLASSIC_NS::if_p; using ::BOOST_SPIRIT_CLASSIC_NS::uint_p; using ::BOOST_SPIRIT_CLASSIC_NS::oct_p; using ::BOOST_SPIRIT_CLASSIC_NS::hex_p; using ::BOOST_SPIRIT_CLASSIC_NS::str_p; using ::BOOST_SPIRIT_CLASSIC_NS::ch_p; using ::BOOST_SPIRIT_CLASSIC_NS::assign_a; cout << "/////////////////////////////////////////////////////////\n"; cout << "\n"; cout << " if_p test\n"; cout << "\n"; cout << "/////////////////////////////////////////////////////////\n"; cout << "\n"; bool as_hex; #if qDebug BOOST_SPIRIT_DEBUG_RULE(hex_prefix); BOOST_SPIRIT_DEBUG_RULE(hex_rule); BOOST_SPIRIT_DEBUG_RULE(oct_prefix); BOOST_SPIRIT_DEBUG_RULE(oct_rule); BOOST_SPIRIT_DEBUG_RULE(dec_rule); BOOST_SPIRIT_DEBUG_RULE(auto_number_rule); BOOST_SPIRIT_DEBUG_RULE(hex_or_dec_number_rule); #endif hex_prefix = str_p("0x"); oct_prefix = ch_p('0'); hex_rule = hex_p[assign_a(number_result)]; oct_rule = oct_p[assign_a(number_result)]; dec_rule = uint_p[assign_a(number_result)]; auto_number_rule = if_p(hex_prefix) [hex_rule] .else_p [ if_p(::BOOST_SPIRIT_CLASSIC_NS::eps_p(oct_prefix)) [oct_rule] .else_p [dec_rule] ]; hex_or_dec_number_rule = if_p(local::var(as_hex))[hex_prefix>>hex_rule].else_p[dec_rule]; cout << "auto:\n"; test_number("", kError, auto_number_rule); test_number("0", 0, auto_number_rule); test_number("1", 1, auto_number_rule); test_number("00", 0, auto_number_rule); test_number("0x", kError, auto_number_rule); test_number("0x0", 0, auto_number_rule); test_number("0755", 493, auto_number_rule); test_number("0x100", 256, auto_number_rule); cout << "\ndecimal:\n"; as_hex = false; test_number("", kError, hex_or_dec_number_rule); test_number("100", 100, hex_or_dec_number_rule); test_number("0x100", kError, hex_or_dec_number_rule); test_number("0xff", kError, hex_or_dec_number_rule); cout << "\nhexadecimal:\n"; as_hex = true; test_number("", kError, hex_or_dec_number_rule); test_number("0x100", 256, hex_or_dec_number_rule); test_number("0xff", 255, hex_or_dec_number_rule); ////////////////////////////////// // tests for if_p without else-parser cout << "\nno-else:\n"; rule_t r = if_p(::BOOST_SPIRIT_CLASSIC_NS::eps_p('0'))[oct_rule]; test_number("0", 0, r); ++test_count; ::BOOST_SPIRIT_CLASSIC_NS::parse_info<> m = ::BOOST_SPIRIT_CLASSIC_NS::parse("", r); if (!m.hit || !m.full || m.length!=0) { std::cout << "FAILED: \"\" ==> \n"; ++error_count; } else std::cout << "PASSED: \"\" ==> \n"; ++test_count; m = ::BOOST_SPIRIT_CLASSIC_NS::parse("junk", r); if (!m.hit || m.full || m.length!=0) { std::cout << "FAILED: \"junk\" ==> \n"; ++error_count; } else std::cout << "PASSED: \"junk\" ==> \n"; test_enclosed_fail(); ////////////////////////////////// // report results std::cout << "\n "; if (error_count==0) cout << "All " << test_count << " if_p-tests passed.\n" << "Test concluded successfully\n"; else cout << error_count << " of " << test_count << " if_p-tests failed\n" << "Test failed\n"; return error_count!=0; }