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/spirit/repository/test/Jamfile | 56 +++ .../libs/spirit/repository/test/karma/confix.cpp | 123 +++++++ .../libs/spirit/repository/test/karma/subrule.cpp | 186 ++++++++++ .../libs/spirit/repository/test/karma/test.hpp | 297 +++++++++++++++ .../libs/spirit/repository/test/qi/advance.cpp | 111 ++++++ .../libs/spirit/repository/test/qi/confix.cpp | 147 ++++++++ .../libs/spirit/repository/test/qi/distinct.cpp | 101 ++++++ .../libs/spirit/repository/test/qi/keywords.cpp | 269 ++++++++++++++ src/boost/libs/spirit/repository/test/qi/seek.cpp | 101 ++++++ .../libs/spirit/repository/test/qi/subrule.cpp | 397 +++++++++++++++++++++ src/boost/libs/spirit/repository/test/qi/test.hpp | 102 ++++++ .../spirit/repository/test/test_headers/Jamfile | 81 +++++ .../spirit/repository/test/test_headers/main.cpp | 14 + .../spirit/repository/test/test_headers/test.cpp | 22 ++ 14 files changed, 2007 insertions(+) create mode 100644 src/boost/libs/spirit/repository/test/Jamfile create mode 100644 src/boost/libs/spirit/repository/test/karma/confix.cpp create mode 100644 src/boost/libs/spirit/repository/test/karma/subrule.cpp create mode 100644 src/boost/libs/spirit/repository/test/karma/test.hpp create mode 100644 src/boost/libs/spirit/repository/test/qi/advance.cpp create mode 100644 src/boost/libs/spirit/repository/test/qi/confix.cpp create mode 100644 src/boost/libs/spirit/repository/test/qi/distinct.cpp create mode 100644 src/boost/libs/spirit/repository/test/qi/keywords.cpp create mode 100644 src/boost/libs/spirit/repository/test/qi/seek.cpp create mode 100644 src/boost/libs/spirit/repository/test/qi/subrule.cpp create mode 100644 src/boost/libs/spirit/repository/test/qi/test.hpp create mode 100644 src/boost/libs/spirit/repository/test/test_headers/Jamfile create mode 100644 src/boost/libs/spirit/repository/test/test_headers/main.cpp create mode 100644 src/boost/libs/spirit/repository/test/test_headers/test.cpp (limited to 'src/boost/libs/spirit/repository/test') diff --git a/src/boost/libs/spirit/repository/test/Jamfile b/src/boost/libs/spirit/repository/test/Jamfile new file mode 100644 index 00000000..18cf1774 --- /dev/null +++ b/src/boost/libs/spirit/repository/test/Jamfile @@ -0,0 +1,56 @@ +#============================================================================== +# Copyright (c) 2001-2009 Joel de Guzman +# Copyright (c) 2001-2009 Hartmut Kaiser +# Copyright (c) 2017-2019 Nikita Kniazev +# +# 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) +#============================================================================== +project spirit_v2_repository/test + : requirements + . + 300 + : + : + ; + +############################################################################### + +alias qi-pch : : on-spirit:../../test/qi//pch ; +alias ka-pch : : on-spirit:../../test/karma//pch ; +explicit qi-pch ka-pch ; + +############################################################################### + +import os ; + +local keywords_reqs ; + +if [ os.environ APPVEYOR ] +{ + # Workaround MSVC codegen bug. See #400 for the info. + keywords_reqs = msvc-14.1:off ; +} + +# bring in rules for testing +import testing ; + +{ + test-suite spirit_v2_repository : + + # run Qi repository tests + [ run qi-pch qi/advance.cpp : : : : qi_repo_advance ] + [ run qi-pch qi/confix.cpp : : : : qi_repo_confix ] + [ run qi-pch qi/distinct.cpp : : : : qi_repo_distinct ] + [ run qi-pch qi/subrule.cpp : : : : qi_repo_subrule ] + [ run qi-pch qi/keywords.cpp : : : $(keywords_reqs) : qi_repo_keywords ] + [ run qi-pch qi/seek.cpp : : : : qi_repo_seek ] + + # run Karma repository tests + [ run ka-pch karma/confix.cpp : : : : karma_repo_confix ] + [ run ka-pch karma/subrule.cpp : : : : karma_repo_subrule ] + + ; +} + diff --git a/src/boost/libs/spirit/repository/test/karma/confix.cpp b/src/boost/libs/spirit/repository/test/karma/confix.cpp new file mode 100644 index 00000000..adbe9903 --- /dev/null +++ b/src/boost/libs/spirit/repository/test/karma/confix.cpp @@ -0,0 +1,123 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// +// 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) + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include "test.hpp" + +namespace html +{ + namespace spirit = boost::spirit; + namespace repo = boost::spirit::repository; + + /////////////////////////////////////////////////////////////////////////////// + // define a HTML tag helper generator + namespace traits + { + template + struct confix_spec + : spirit::result_of::terminal + {}; + } + + template + inline typename traits::confix_spec::type + confix_spec(Prefix const& prefix, Suffix const& suffix) + { + return repo::confix(prefix, suffix); + } + + /////////////////////////////////////////////////////////////////////////// + template + inline typename traits::confix_spec< + std::basic_string + >::type + tag (std::basic_string const& tagname) + { + typedef std::basic_string string_type; + return confix_spec(string_type("<") + tagname + ">" + , string_type(""); + } + + inline traits::confix_spec::type + tag (char const* tagname) + { + return tag(std::string(tagname)); + } + + /////////////////////////////////////////////////////////////////////////// + typedef traits::confix_spec::type html_tag_type; + + html_tag_type const ol = tag("ol"); +} + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace spirit_test; + using namespace boost::spirit; + using namespace boost::spirit::repository; + + { + using namespace boost::spirit::ascii; + + BOOST_TEST((test("a", + confix("", "")[char_('a')]))); + BOOST_TEST((test("a", + confix("", "")[char_], 'a'))); + BOOST_TEST((test("// some C++ comment\n", + confix(string("//"), eol)[" some C++ comment"]))); + BOOST_TEST((test("// some C++ comment\n", + confix(string("//"), eol)[string], " some C++ comment"))); + + BOOST_TEST((test("
    some text
", html::ol["some text"]))); + BOOST_TEST((test("
    some text
", html::ol[string], "some text"))); + } + + { + using namespace boost::spirit::standard_wide; + + BOOST_TEST((test(L"a", + confix(L"", L"")[char_(L'a')]))); + BOOST_TEST((test(L"// some C++ comment\n", + confix(string(L"//"), eol)[L" some C++ comment"]))); + + BOOST_TEST((test(L"
    some text
", html::ol[L"some text"]))); + } + + { + using namespace boost::spirit::ascii; + + BOOST_TEST((test_delimited(" a ", + confix("", "")[char_('a')], space))); + BOOST_TEST((test_delimited("// some C++ comment \n ", + confix(string("//"), eol)["some C++ comment"], space))); + + BOOST_TEST((test_delimited("
    some text
", + html::ol["some text"], space))); + } + + { + using namespace boost::spirit::standard_wide; + + BOOST_TEST((test_delimited(L" a ", + confix(L"", L"")[char_(L'a')], space))); + BOOST_TEST((test_delimited(L"// some C++ comment \n ", + confix(string(L"//"), eol)[L"some C++ comment"], space))); + + BOOST_TEST((test_delimited(L"
    some text
", + html::ol[L"some text"], space))); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/repository/test/karma/subrule.cpp b/src/boost/libs/spirit/repository/test/karma/subrule.cpp new file mode 100644 index 00000000..dd6bdabe --- /dev/null +++ b/src/boost/libs/spirit/repository/test/karma/subrule.cpp @@ -0,0 +1,186 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// Copyright (c) 2009 Francois Barel +// +// 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) + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "test.hpp" + +using namespace spirit_test; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost; + using namespace boost::spirit; + using namespace boost::spirit::karma; +// using namespace boost::spirit::ascii; + using boost::spirit::repository::karma::subrule; + + typedef spirit_test::output_iterator::type outiter_type; + + // basic tests + { + rule start; + subrule<0> sr; + + start = ( + sr = char_[_1 = 'a'] << int_[_1 = 10] << double_[_1 = 12.4] + ); + BOOST_TEST(test("a1012.4", start)); + + BOOST_TEST(test("a1012.4", ( + sr = (char_ << int_ << double_)[_1 = 'a', _2 = 10, _3 = 12.4] + ))); + + subrule<1> a; + subrule<2> b; + subrule<3> c; + + start = ( + sr = a << b << c + , a = char_[_1 = 'a'] + , b = int_[_1 = 10] + , c = double_[_1 = 12.4] + ); + BOOST_TEST(test("a1012.4", start)); + } + + // basic tests with delimiter + { + rule start; + subrule<0> sr; + + start = ( + sr = char_[_1 = 'a'] << int_[_1 = 10] << double_[_1 = 12.4] + ); + BOOST_TEST(test_delimited("a 10 12.4 ", start, space)); + + BOOST_TEST(test_delimited("a 10 12.4 ", ( + sr = (char_ << int_ << double_)[_1 = 'a', _2 = 10, _3 = 12.4] + ), space)); + + subrule<1> a; + subrule<2> b; + subrule<3> c; + + start = ( + sr = a << b << c + , a = char_[_1 = 'a'] + , b = int_[_1 = 10] + , c = double_[_1 = 12.4] + ); + BOOST_TEST(test_delimited("a 10 12.4 ", start, space)); + } + + // basic tests involving a direct parameter + { + typedef variant var_type; + + rule start; + subrule<0, var_type()> sr; + + start = ( + sr = (char_ | int_ | double_)[_1 = _r0] + )[_1 = _val]; + + var_type v ('a'); + BOOST_TEST(test("a", start, v)); + v = 10; + BOOST_TEST(test("10", start, v)); + v = 12.4; + BOOST_TEST(test("12.4", start, v)); + } + + { + typedef variant var_type; + + rule start; + subrule<0, var_type()> sr; + + start %= ( + sr = (char_ | int_ | double_)[_1 = _r0] + ); + + var_type v ('a'); + BOOST_TEST(test_delimited("a ", start, v, space)); + v = 10; + BOOST_TEST(test_delimited("10 ", start, v, space)); + v = 12.4; + BOOST_TEST(test_delimited("12.4 ", start, v, space)); + } + + { + rule start; + subrule<0, void(char, int, double)> sr; + + start = ( + sr = char_[_1 = _r1] << int_[_1 = _r2] << double_[_1 = _r3] + )(_r1, _r2, _r3); + BOOST_TEST(test("a1012.4", start('a', 10, 12.4))); + + BOOST_TEST(test("a1012.4", ( + sr = (char_ << int_ << double_)[_1 = _r1, _2 = _r2, _3 = _r3] + )('a', 10, 12.4))); + + subrule<1, void(char, int, double)> entry; + subrule<2, void(char)> a; + subrule<3, void(int)> b; + subrule<4, void(double)> c; + + start = ( + entry = a(_r1) << b(_r2) << c(_r3) + , a = char_[_1 = _r1] + , b = int_[_1 = _r1] + , c = double_[_1 = _r1] + )(_r1, _r2, _r3); + BOOST_TEST(test("a1012.4", start('a', 10, 12.4))); + } + + { + rule start; + subrule<0, void(char, int, double)> sr; + + start = ( + sr = char_[_1 = _r1] << int_[_1 = _r2] << double_[_1 = _r3] + )(_r1, _r2, _r3); + BOOST_TEST(test_delimited("a 10 12.4 ", start('a', 10, 12.4), space)); + + BOOST_TEST(test_delimited("a 10 12.4 ", ( + sr = (char_ << int_ << double_)[_1 = _r1, _2 = _r2, _3 = _r3] + )('a', 10, 12.4), space)); + + subrule<1, void(char, int, double)> entry; + subrule<2, void(char)> a; + subrule<3, void(int)> b; + subrule<4, void(double)> c; + + start = ( + entry = a(_r1) << b(_r2) << c(_r3) + , a = char_[_1 = _r1] + , b = int_[_1 = _r1] + , c = double_[_1 = _r1] + )(_r1, _r2, _r3); + BOOST_TEST(test_delimited("a 10 12.4 ", start('a', 10, 12.4), space)); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/repository/test/karma/test.hpp b/src/boost/libs/spirit/repository/test/karma/test.hpp new file mode 100644 index 00000000..70b89ce5 --- /dev/null +++ b/src/boost/libs/spirit/repository/test/karma/test.hpp @@ -0,0 +1,297 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// +// 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) + +#if !defined(BOOST_SPIRIT_KARMA_TEST_FEB_23_2007_1221PM) +#define BOOST_SPIRIT_KARMA_TEST_FEB_23_2007_1221PM + +#include +#include +#include +#include +#include + +#include +#include + +namespace spirit_test +{ + /////////////////////////////////////////////////////////////////////////// + struct display_type + { + template + void operator()(T const &) const + { + std::cout << typeid(T).name() << std::endl; + } + + template + static void print() + { + std::cout << typeid(T).name() << std::endl; + } + }; + + display_type const display = {}; + + /////////////////////////////////////////////////////////////////////////// + template + struct output_iterator + { + typedef std::basic_string string_type; + typedef std::back_insert_iterator type; + }; + + /////////////////////////////////////////////////////////////////////////// + template + void print_if_failed(char const* func, bool result + , std::basic_string const& generated, T const& expected) + { + if (!result) + std::cerr << "in " << func << ": result is false" << std::endl; + else if (generated != expected) + std::cerr << "in " << func << ": generated \"" + << std::string(generated.begin(), generated.end()) + << "\"" << std::endl; + } + + /////////////////////////////////////////////////////////////////////////// + template + inline bool test(Char const *expected, Generator const& g) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator outit(generated); + bool result = karma::generate(outit, g); + + print_if_failed("test", result, generated, expected); + return result && generated == expected; + } + + template + inline bool test(std::basic_string const& expected, Generator const& g) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator outit(generated); + bool result = karma::generate(outit, g); + + print_if_failed("test", result, generated, expected); + return result && generated == expected; + } + + /////////////////////////////////////////////////////////////////////////// + template + inline bool test(Char const *expected, Generator const& g, + Attribute const &attr) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator outit(generated); + bool result = karma::generate(outit, g, attr); + + print_if_failed("test", result, generated, expected); + return result && generated == expected; + } + + template + inline bool test(std::basic_string const& expected, Generator const& g, + Attribute const &attr) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator outit(generated); + bool result = karma::generate(outit, g, attr); + + print_if_failed("test", result, generated, expected); + return result && generated == expected; + } + + /////////////////////////////////////////////////////////////////////////// + template + inline bool test_delimited(Char const *expected, Generator const& g, + Delimiter const& d) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator outit(generated); + bool result = karma::generate_delimited(outit, g, d); + + print_if_failed("test_delimited", result, generated, expected); + return result && generated == expected; + } + + template + inline bool test_delimited(std::basic_string const& expected, + Generator const& g, Delimiter const& d) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator outit(generated); + bool result = karma::generate_delimited(outit, g, d); + + print_if_failed("test_delimited", result, generated, expected); + return result && generated == expected; + } + + /////////////////////////////////////////////////////////////////////////// + template + inline bool test_delimited(Char const *expected, Generator const& g, + Attribute const &attr, Delimiter const& d) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator outit(generated); + bool result = karma::generate_delimited(outit, g, d, attr); + + print_if_failed("test_delimited", result, generated, expected); + return result && generated == expected; + } + + template + inline bool test_delimited(std::basic_string const& expected, + Generator const& g, Attribute const &attr, Delimiter const& d) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator outit(generated); + bool result = karma::generate_delimited(outit, g, d, attr); + + print_if_failed("test_delimited", result, generated, expected); + return result && generated == expected; + } + + /////////////////////////////////////////////////////////////////////////// + template + inline bool + binary_test(char const *expected, std::size_t size, + Generator const& g) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator outit(generated); + bool result = karma::generate(outit, g); + + return result && !std::memcmp(generated.c_str(), expected, size); + } + + /////////////////////////////////////////////////////////////////////////// + template + inline bool + binary_test(char const *expected, std::size_t size, + Generator const& g, Attribute const &attr) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator outit(generated); + bool result = karma::generate(outit, g, attr); + + return result && !std::memcmp(generated.c_str(), expected, size); + } + + /////////////////////////////////////////////////////////////////////////// + template + inline bool + binary_test_delimited(char const *expected, std::size_t size, + Generator const& g, Delimiter const& d) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator outit(generated); + bool result = karma::generate_delimited(outit, g, d); + + return result && !std::memcmp(generated.c_str(), expected, size); + } + + /////////////////////////////////////////////////////////////////////////// + template + inline bool + binary_test_delimited(char const *expected, std::size_t size, + Generator const& g, Attribute const &attr, Delimiter const& d) + { + namespace karma = boost::spirit::karma; + typedef std::basic_string string_type; + + // we don't care about the result of the "what" function. + // we only care that all generators have it: + karma::what(g); + + string_type generated; + std::back_insert_iterator outit(generated); + bool result = karma::generate_delimited(outit, g, d, attr); + + return result && !std::memcmp(generated.c_str(), expected, size); + } + +} // namespace spirit_test + +#endif // !BOOST_SPIRIT_KARMA_TEST_FEB_23_2007_1221PM diff --git a/src/boost/libs/spirit/repository/test/qi/advance.cpp b/src/boost/libs/spirit/repository/test/qi/advance.cpp new file mode 100644 index 00000000..160ac55f --- /dev/null +++ b/src/boost/libs/spirit/repository/test/qi/advance.cpp @@ -0,0 +1,111 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// Copyright (c) 2001-2010 Joel de Guzman +// Copyright (c) 2011 Aaron Graham +// +// 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) + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include "test.hpp" + +namespace spirit_test +{ + template + bool test_c(Container const& in, Parser const& p, bool full_match = true) + { + // we don't care about the results of the "what" function. + // we only care that all parsers have it: + boost::spirit::qi::what(p); + + typename Container::const_iterator first = in.begin(); + typename Container::const_iterator const last = in.end(); + return boost::spirit::qi::parse(first, last, p) + && (!full_match || (first == last)); + } +} + +int main() +{ + using spirit_test::test; + using spirit_test::test_c; + + using namespace boost::spirit::qi::labels; + using boost::spirit::qi::locals; + using boost::spirit::qi::rule; + using boost::spirit::qi::uint_; + using boost::spirit::qi::byte_; + + using namespace boost::assign; + using boost::spirit::repository::qi::advance; + + { // test basic functionality with random-access iterators + rule start; + + start = 'a' >> advance(3) >> "bc"; + BOOST_TEST(test("a123bc", start)); + + start = (advance(3) | 'q') >> 'i'; + BOOST_TEST(test("qi", start)); + + start = advance(-1); + BOOST_TEST(!test("0", start)); + + start = advance(-1) | "qi"; + BOOST_TEST(test("qi", start)); + + start = advance(0) >> "abc" >> advance(10) >> "nopq" >> advance(0) + >> advance(8) >> 'z'; + BOOST_TEST(test("abcdefghijklmnopqrstuvwxyz", start)); + } + + { // test locals + rule > start; + + start = byte_ [_a = _1] >> advance(_a) >> "345"; + BOOST_TEST(test("\x02""12345", start)); + BOOST_TEST(!test("\x60""345", start)); + } + + { // test basic functionality with bidirectional iterators + rule::const_iterator, locals > start; + std::list list; + + list.clear(); + list += 1,2,'a','b','c'; + start = byte_ [_a = _1] >> advance(_a) >> "abc"; + BOOST_TEST(test_c(list, start)); + + list.clear(); + list += 3,'q','i'; + start = byte_ [_a = _1] >> advance(_a); + BOOST_TEST(!test_c(list, start)); + + start = byte_ [_a = _1] >> (advance(_a) | "qi"); + BOOST_TEST(test_c(list, start)); + + list.clear(); + list += 'a','b','c','d','e','f','g','h','i','j','k','l','m'; + list += 'n','o','p','q','r','s','t','u','v','w','x','y','z'; + start = advance(0) >> "abc" >> advance(10) >> "nopq" >> advance(0) + >> advance(8) >> 'z'; + BOOST_TEST(test_c(list, start)); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/repository/test/qi/confix.cpp b/src/boost/libs/spirit/repository/test/qi/confix.cpp new file mode 100644 index 00000000..e045026c --- /dev/null +++ b/src/boost/libs/spirit/repository/test/qi/confix.cpp @@ -0,0 +1,147 @@ +/*============================================================================= + Copyright (c) 2009 Chris Hoeppler + + 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) +=============================================================================*/ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include "test.hpp" + +namespace comment { + namespace spirit = boost::spirit; + namespace repo = boost::spirit::repository; + + // Define a metafunction allowing to compute the type + // of the confix() construct + template + struct confix_spec_traits + { + typedef typename spirit::result_of::terminal< + repo::tag::confix(Prefix, Suffix) + >::type type; + }; + + template + inline typename confix_spec_traits::type + confix_spec(Prefix const& prefix, Suffix const& suffix) + { + return repo::confix(prefix, suffix); + } + + inline confix_spec_traits::type + confix_spec(const char* prefix, const char* suffix) + { + return repo::confix(std::string(prefix), std::string(suffix)); + } + confix_spec_traits::type const c_comment = confix_spec("/*", "*/"); + confix_spec_traits::type const cpp_comment = confix_spec("//", "\n"); +} + +int main() +{ + using spirit_test::test_attr; + using spirit_test::test; + + using namespace boost::spirit::ascii; + using namespace boost::spirit::qi::labels; + using boost::spirit::qi::locals; + using boost::spirit::qi::rule; + using boost::spirit::qi::debug; + + namespace phx = boost::phoenix; + namespace repo = boost::spirit::repository; + + { // basic tests + + rule start; + + start = repo::confix('a', 'c')['b']; + BOOST_TEST(test("abc", start)); + + start = repo::confix('a', 'c')['b'] | "abd"; + BOOST_TEST(test("abd", start)); + + start = repo::confix("/*", "*/")[*(alpha - "*/")]; + BOOST_TEST(test("/*aaaabababaaabbb*/", start)); + + start = repo::confix(char_('/') >> '*', '*' >> char_('/'))[*alpha - "*/"]; + BOOST_TEST(test("/*aaaabababaaabba*/", start)); + + start = comment::c_comment[*(alpha - "*/")]; + BOOST_TEST(test("/*aaaabababaaabbb*/", start)); + + // ignore the skipper! + BOOST_TEST(!test("/* aaaabababaaabba*/", start, space)); + } + + { // basic tests w/ skipper + + rule start; + + start = repo::confix('a', 'c')['b']; + BOOST_TEST(test(" a b c ", start, space)); + + start = repo::confix(char_('/') >> '*', '*' >> char_('/'))[*alpha - "*/"]; + BOOST_TEST(test(" / *a b a b a b a a a b b b * / ", start, space)); + } + + { // context tests + char ch; + rule a; + a = repo::confix("/*", "*/")[alpha][_val = _1]; + + BOOST_TEST(test("/*x*/", a[phx::ref(ch) = _1])); + BOOST_TEST(ch == 'x'); + + a %= repo::confix("/*", "*/")[alpha]; + BOOST_TEST(test_attr("/*z*/", a, ch)); // attribute is given. + BOOST_TEST(ch == 'z'); + } + + { // rules test + rule a, b, c, start; + + a = 'a'; + b = 'b'; + c = 'c'; + + a.name("a"); + b.name("b"); + c.name("c"); + start.name("start"); + + debug(a); + debug(b); + debug(c); + debug(start); + + start = repo::confix(a.alias(), c.alias())[b]; + BOOST_TEST(test("abc", start)); + } + + { // modifiers test + rule start; + start = no_case[repo::confix("_A_", "_Z_")["heLLo"]]; + BOOST_TEST(test("_a_hello_z_", start)); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/repository/test/qi/distinct.cpp b/src/boost/libs/spirit/repository/test/qi/distinct.cpp new file mode 100644 index 00000000..7ba4c521 --- /dev/null +++ b/src/boost/libs/spirit/repository/test/qi/distinct.cpp @@ -0,0 +1,101 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// Copyright (c) 2001-2010 Joel de Guzman +// Copyright (c) 2003 Vaclav Vesely +// +// 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) + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include "test.hpp" + +using namespace boost; + +/////////////////////////////////////////////////////////////////////////////// +namespace distinct +{ + //[qi_distinct_encapsulation + namespace spirit = boost::spirit; + namespace ascii = boost::spirit::ascii; + namespace repo = boost::spirit::repository; + + // Define metafunctions allowing to compute the type of the distinct() + // and ascii::char_() constructs + namespace traits + { + // Metafunction allowing to get the type of any repository::distinct(...) + // construct + template + struct distinct_spec + : spirit::result_of::terminal + {}; + + // Metafunction allowing to get the type of any ascii::char_(...) construct + template + struct char_spec + : spirit::result_of::terminal + {}; + } + + // Define a helper function allowing to create a distinct() construct from + // an arbitrary tail parser + template + inline typename traits::distinct_spec::type + distinct_spec(Tail const& tail) + { + return repo::distinct(tail); + } + + // Define a helper function allowing to create a ascii::char_() construct + // from an arbitrary string representation + template + inline typename traits::char_spec::type + char_spec(String const& str) + { + return ascii::char_(str); + } + + // the following constructs the type of a distinct_spec holding a + // charset("0-9a-zA-Z_") as its tail parser + typedef traits::char_spec::type charset_tag_type; + typedef traits::distinct_spec::type keyword_tag_type; + + // Define a new Qi 'keyword' directive usable as a shortcut for a + // repository::distinct(char_(std::string("0-9a-zA-Z_"))) + std::string const keyword_spec("0-9a-zA-Z_"); + keyword_tag_type const keyword = distinct_spec(char_spec(keyword_spec)); + //] +} + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace spirit_test; + using namespace boost::spirit; + + { + using namespace boost::spirit::ascii; + + qi::rule r; + r = distinct::keyword["description"] >> -lit(':') >> distinct::keyword["ident"]; + + BOOST_TEST(test("description ident", r, space)); + BOOST_TEST(test("description:ident", r, space)); + BOOST_TEST(test("description: ident", r, space)); + BOOST_TEST(!test("descriptionident", r, space)); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/repository/test/qi/keywords.cpp b/src/boost/libs/spirit/repository/test/qi/keywords.cpp new file mode 100644 index 00000000..eb224d65 --- /dev/null +++ b/src/boost/libs/spirit/repository/test/qi/keywords.cpp @@ -0,0 +1,269 @@ +/*============================================================================= + Copyright (c) 2001-2011 Joel de Guzman + Copyright (c) 2011 Thomas Bernard + + 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) +=============================================================================*/ +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "test.hpp" + +struct x_attr +{ + +}; + +namespace boost { namespace spirit { namespace traits +{ + + + template <> + struct container_value + { + typedef char type; // value type of container + }; + + + template <> + struct push_back_container + { + static bool call(x_attr& /*c*/, char /*val*/) + { + // push back value type into container + return true; + } + }; +}}} + +int +main() +{ + using spirit_test::test_attr; + using spirit_test::test; + using namespace boost::spirit; + using namespace boost::spirit::ascii; + using boost::spirit::repository::kwd; + using boost::spirit::repository::ikwd; + using boost::spirit::repository::dkwd; + using boost::spirit::qi::inf; + using boost::spirit::qi::omit; + using boost::spirit::qi::int_; + using boost::spirit::qi::lit; + using boost::spirit::qi::_1; + using boost::spirit::qi::lexeme; + + + { + + // no constraints + boost::fusion::vector data; + BOOST_TEST( test_attr("c=1 a=a", kwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], data, space)); + BOOST_TEST( boost::fusion::at_c<0>(data) == 'a' ); + BOOST_TEST( boost::fusion::at_c<1>(data) == 0 ); + BOOST_TEST( boost::fusion::at_c<2>(data) == 1 ); + + BOOST_TEST( test("a=a c=1", kwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space)); + + BOOST_TEST( test("", kwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space)); + + // Exact + BOOST_TEST(test("a=a b=b c=1", kwd("a",1)[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space)); + BOOST_TEST(test("a=a b=c b=e c=1", kwd("a",1)[ '=' > char_] / kwd("b",2)[ '=' > char_] / kwd("c")['=' > int_], space)); + BOOST_TEST(!test("b=c b=e c=1", kwd("a",1)[ '=' > char_] / kwd("b",2)[ '=' > char_] / kwd("c")['=' > int_], space)); + + // Min - Max + BOOST_TEST(test("a=f b=c b=e c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,2)[ '=' > char_] / kwd("c",1,2)['=' > int_], space)); + BOOST_TEST(!test("b=c b=e c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,1)[ '=' > char_] / kwd("c",1,2)['=' > int_], space)); + BOOST_TEST(test("a=g a=f b=c b=e c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,2)[ '=' > char_] / kwd("c",1,2)['=' > int_], space)); + BOOST_TEST(!test("a=f a=e b=c b=e a=p c=1", kwd("a",1,2)[ '=' > char_] / kwd("b",0,1)[ '=' > char_] / kwd("c",1,2)['=' > int_], space)); + + // Min - inf + BOOST_TEST(test("a=f b=c b=e c=1", kwd("a",1,inf)[ '=' > char_] / kwd("b",0,inf)[ '=' > char_] / kwd("c",1,inf)['=' > int_], space )); + BOOST_TEST(!test("b=c b=e c=1", kwd("a",1,inf)[ '=' > char_] / kwd("b",0,inf)[ '=' > char_] / kwd("c",1,inf)['=' > int_], space )); + BOOST_TEST(test("a=f a=f a=g b=c b=e c=1 a=e", kwd("a",1,inf)[ '=' > char_] / kwd("b",0,inf)[ '=' > char_] / kwd("c",1,inf)['=' > int_], space )); + } + + { // Single keyword, empty string + BOOST_TEST(test(" ", kwd("aad")[char_],space)); + // Single keyword + BOOST_TEST(test("aad E ", kwd("aad")[char_],space)); + // Single no case keyword + BOOST_TEST(test("AaD E ", ikwd("aad")[char_],space)); + + } + + { + // Vector container + boost::fusion::vector,std::vector,std::vector > data; + BOOST_TEST(test_attr(" a=1 b=2 b=5 c=3",kwd("a")[ '=' > int_] / kwd("b")[ '=' > int_] / kwd("c")['=' > int_] , data, space) + && (boost::fusion::at_c<0>(data).size()==1) + && (boost::fusion::at_c<0>(data)[0]==1) + + &&(boost::fusion::at_c<1>(data).size()==2) + &&(boost::fusion::at_c<1>(data)[0]==2) + &&(boost::fusion::at_c<1>(data)[1]==5) + + &&(boost::fusion::at_c<2>(data).size()==1) + &&(boost::fusion::at_c<2>(data)[0]==3) + ); + } + + { + // no_case test + BOOST_TEST( test("B=a c=1 a=E", no_case[kwd("a")[ "=E" ] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_]], space)); + BOOST_TEST( test("B=a c=1 a=e", no_case[kwd("a")[ "=E" ] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_]], space)); + BOOST_TEST( !test("B=a c=1 A=E", no_case[kwd("a")[ '=' > char_]] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space)); + BOOST_TEST( test("b=a c=1 A=E", no_case[kwd("a")[ '=' > char_]] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space)); + BOOST_TEST( !test("A=a c=1 a=E", kwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space)); + BOOST_TEST( test("A=a c=1 a=E", ikwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space)); + BOOST_TEST( !test("A=a C=1 a=E", ikwd("a")[ '=' > char_] / kwd("b")[ '=' > char_] / kwd("c")['=' > int_], space)); + } + + { + // iterator restoration + BOOST_TEST( test("a=a c=1 ba=d", (kwd("a")[ '=' > char_] / kwd("b")[ '=' > int_] / kwd("c")['=' > int_] ) > lit("ba=") > char_, space)); + BOOST_TEST( test("A=a c=1 ba=d", (ikwd("a")[ '=' > char_] / kwd("b")[ '=' > int_] / kwd("c")['=' > int_] ) > lit("ba=") > char_, space)); + } + + { // actions + namespace phx = boost::phoenix; + + std::vector v; + BOOST_TEST(test("b=2 c=4", kwd("b")['=' > int_][phx::ref(v)=_1] / kwd("c")[ '=' > int_ ],space) && + v[0] == 2 ); + } + + + { + // no constraints + boost::fusion::vector data; + BOOST_TEST( test_attr("c,1,2=1 2,b=a", kwd( char_ >> lit(',') >> int_ )[ '=' >> char_] / kwd(int_ >> lit(',') >> char_)[ '=' >> char_] / kwd(char_ >> lit(',') >> int_ >> lit(',') >> int_)['=' >> int_], data, space)); + BOOST_TEST( boost::fusion::at_c<0>(data) == 0 ); + BOOST_TEST( boost::fusion::at_c<1>(data) == 'a'); + BOOST_TEST( boost::fusion::at_c<2>(data) == 1 ); + + BOOST_TEST( test("2,b=a c,1,2=1", kwd( char_ >> ',' >> int_ )[ '=' >> char_] / kwd(int_ >> ',' >> char_)[ '=' >> char_] / kwd(char_ >> ',' >> int_ >> ',' >> int_)['=' >> int_], space)); + + BOOST_TEST( test("", kwd( char_ >> ',' >> int_ )[ '=' >> char_] / kwd(int_ >> ',' >> char_)[ '=' >> char_] / kwd(char_ >> ',' >> int_ >> ',' >> int_)['=' >> int_], space)); + + // Exact + BOOST_TEST(test("7a=a 5b=b 2c=1", kwd(int_ >> lit('a'),1)[ '=' >> char_] / kwd(int_ >> lit('b'))[ '=' >> char_] / kwd(int_ >> lit('c'))['=' >> int_], space)); + BOOST_TEST(test("7a=a 3b=d 5b=b 2c=1", kwd(int_ >> lit('a'),1)[ '=' >> char_] / kwd(int_ >> lit('b'),2)[ '=' >> char_] / kwd(int_ >>'c')['=' >> int_], space)); + BOOST_TEST(!test("7a=a 5b=b 2c=1", kwd(int_ >> lit('a'),1)[ '=' >> char_] / kwd(int_ >> lit('b'),2)[ '=' >> char_] / kwd(int_ >>'c')['=' >> int_], space)); + + // Min - Max + BOOST_TEST(test("6a=f 2b=c 3b=e 1c=1", kwd(int_ >> "a",1,2)[ '=' >> char_] / kwd(int_ >> "b",0,2)[ '=' >> char_] / kwd(int_ >> "c",1,2)['=' >> int_], space)); + BOOST_TEST(!test("1b=c 6b=e 2c=1", kwd(int_ >> "a",1,2)[ '=' >> char_] / kwd(int_ >> "b",0,1)[ '=' >> char_] / kwd(int_ >> "c",1,2)['=' >> int_], space)); + BOOST_TEST(test("4a=g 7a=f 2b=c 1b=e 4c=1", kwd(int_ >> "a",1,2)[ '=' >> char_] / kwd(int_ >> "b",0,2)[ '=' >> char_] / kwd(int_ >> "c",1,2)['=' >> int_], space)); + BOOST_TEST(!test("1a=f a=e 2b=c 5b=e 6a=p 67c=1", kwd(int_ >> "a",1,2)[ '=' >> char_] / kwd(int_ >> "b",0,1)[ '=' >> char_] / kwd(int_ >> "c",1,2)['=' >> int_], space)); + + // Min - inf + BOOST_TEST(test("41a=f 44b=c 12b=e 45c=1", kwd(int_ >> "a",1,inf)[ '=' >> char_] / kwd(int_ >> "b",0,inf)[ '=' >> char_] / kwd(int_ >> "c",1,inf)['=' >> int_], space )); + BOOST_TEST(!test("31b=c 55b=e 2c=1", kwd("a",1,inf)[ '=' >> char_] / kwd("b",0,inf)[ '=' >> char_] / kwd("c",1,inf)['=' >> int_], space )); + BOOST_TEST(test("12a=f 45a=f 12a=g 1b=c 7b=e 12c=1 6a=e", kwd(int_ >> "a",1,inf)[ '=' >> char_] / kwd(int_ >> "b",0,inf)[ '=' >> char_] / kwd(int_ >> "c",1,inf)['=' >> int_], space )); + + } + + { + + // Vector container + boost::fusion::vector,std::vector,std::vector > data; + BOOST_TEST(test_attr(" 41a=1 4b=2 12b=5 5c=3",kwd(int_ >> "a")[ '=' >> int_] / kwd(int_ >> "b")[ '=' >> int_] / kwd(int_ >> "c")['=' >> int_] , data, space) + && (boost::fusion::at_c<0>(data).size()==1) + && (boost::fusion::at_c<0>(data)[0]==1) + + &&(boost::fusion::at_c<1>(data).size()==2) + &&(boost::fusion::at_c<1>(data)[0]==2) + &&(boost::fusion::at_c<1>(data)[1]==5) + + &&(boost::fusion::at_c<2>(data).size()==1) + &&(boost::fusion::at_c<2>(data)[0]==3) + ); + + + + } + + { + // no_case test + BOOST_TEST( test("12B=a 5c=1 1a=E", no_case[kwd(int_ >> "a")[ "=E" ] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_]], space)); + BOOST_TEST( test("5B=a 2c=1 5a=e", no_case[kwd(int_ >> "a")[ "=E" ] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_]], space)); + BOOST_TEST( !test("1B=a 8c=1 1A=E", no_case[kwd(int_ >> "a")[ '=' >> char_]] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_], space)); + BOOST_TEST( test("2b=a 6c=1 5A=E", no_case[kwd(int_ >> "a")[ '=' >> char_]] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_], space)); + BOOST_TEST( !test("1A=a 5c=1 1a=E", kwd(int_ >> "a")[ '=' >> char_] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_], space)); + BOOST_TEST( test("A=a 23c=1 a=E", ikwd("a")[ '=' >> char_] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_], space)); + BOOST_TEST( !test("A=a 21C=1 a=E", ikwd("a")[ '=' >> char_] / kwd(int_ >> "b")[ '=' >> char_] / kwd(int_ >> "c")['=' >> int_], space)); + } + + { + // iterator restoration + BOOST_TEST( test("4a=a c4=1 ba=d", (kwd(int_ >> "a")[ '=' >> char_] / kwd("b" >> int_)[ '=' >> int_] / kwd("c" >> int_ )['=' >> int_] ) >> lit("ba=") >> char_, space)); + } + + { // actions + namespace phx = boost::phoenix; + + std::vector v; + BOOST_TEST(test("b4=2 c1=4", kwd("b" >> int_)['=' >> int_][phx::ref(v)=_1] / kwd("c" >> int_)[ '=' >> int_ ],space) && + v[0] == 2 ); + } + + { + // complex keyword single test + int result=0; + + BOOST_TEST( test_attr("(a,1) = 3214", kwd( '(' >> char_ >> ',' >> int_ >> ')' )['=' >> int_], result, space) ); + BOOST_TEST(result==3214); + } + { + // Mixed complex keyword loop + boost::fusion::vector data; + + BOOST_TEST( test_attr("(a,1) = 3214 b += 2 hello 10 (a,2)=31", kwd( '(' >> char_ >> ',' >> int_ >> ')' )['=' >> int_] / kwd("hello")[int_] / kwd("b")["+=" >> int_], data, space) ); + BOOST_TEST( boost::fusion::at_c<0>(data) == 31); + BOOST_TEST( boost::fusion::at_c<1>(data) == 10); + BOOST_TEST( boost::fusion::at_c<2>(data) == 2); + } + + // dkwd and idkwd + { + BOOST_TEST( test("a =a", dkwd("a")[ '=' > char_] , space)); + BOOST_TEST( !test("a=a", dkwd("a")[ '=' > char_] , space)); + BOOST_TEST(test("a =a b =b c=1", dkwd("a",1)[ '=' > char_] / dkwd("b",1,2)[ '=' > char_] / kwd("c")['=' > int_], space)); + BOOST_TEST(!test("a=a b=b c =1", dkwd("a",1)[ '=' > char_] / dkwd("b",1,2)[ '=' > char_] / kwd("c")['=' > int_], space)); + + BOOST_TEST(test("a =a b =b b =d c=1", dkwd("a",1,inf)[ '=' > char_] / dkwd("b",2,inf)[ '=' > char_] / kwd("c")['=' > int_], space)); + + } + + { // attribute customization + +// x_attr x; +// test_attr("a = b c = d", kwd("a")['=' > char_] / kwd("c")['=' > char_], x); + } + + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/repository/test/qi/seek.cpp b/src/boost/libs/spirit/repository/test/qi/seek.cpp new file mode 100644 index 00000000..96183024 --- /dev/null +++ b/src/boost/libs/spirit/repository/test/qi/seek.cpp @@ -0,0 +1,101 @@ +/*============================================================================= + Copyright (c) 2011 Jamboree + + 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) +=============================================================================*/ + + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "test.hpp" + + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace spirit_test; + namespace qi = boost::spirit::qi; + namespace phx = boost::phoenix; + using boost::spirit::repository::qi::seek; + using boost::spirit::standard::space; + + // test eoi + { + using qi::eoi; + + BOOST_TEST(test("", seek[eoi])); + BOOST_TEST(test(" ", seek[eoi], space)); + BOOST_TEST(test("a", seek[eoi])); + BOOST_TEST(test(" a", seek[eoi], space)); + } + + // test literal finding + { + using qi::int_; + using qi::char_; + + int i = 0; + + BOOST_TEST( + test_attr("!@#$%^&*KEY:123", seek["KEY:"] >> int_, i) + && i == 123 + ); + } + + // test sequence finding + { + using qi::int_; + using qi::lit; + + int i = 0; + + BOOST_TEST( + test_attr("!@#$%^&* KEY : 123", seek[lit("KEY") >> ':'] >> int_, i, space) + && i == 123 + ); + } + + // test attr finding + { + using qi::int_; + + std::vector v; + + BOOST_TEST( // expect partial match + test_attr("a06b78c3d", +seek[int_], v, false) + && v[0] == 6 && v[1] == 78 && v[2] == 3 + ); + } + + // test action + { + using phx::ref; + + bool b = false; + + BOOST_TEST( // expect partial match + test("abcdefg", seek["def"][ref(b) = true], false) + && b + ); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/spirit/repository/test/qi/subrule.cpp b/src/boost/libs/spirit/repository/test/qi/subrule.cpp new file mode 100644 index 00000000..7eb5331f --- /dev/null +++ b/src/boost/libs/spirit/repository/test/qi/subrule.cpp @@ -0,0 +1,397 @@ +/*============================================================================= + Copyright (c) 2001-2010 Joel de Guzman + Copyright (c) 2009 Francois Barel + + 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) +=============================================================================*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include "test.hpp" + +int +main() +{ + using spirit_test::test_attr; + using spirit_test::test; + + using namespace boost::spirit::ascii; + using namespace boost::spirit::qi::labels; + using boost::spirit::qi::locals; + using boost::spirit::qi::rule; + using boost::spirit::qi::int_; + using boost::spirit::qi::fail; + using boost::spirit::qi::on_error; + using boost::spirit::qi::debug; + using boost::spirit::repository::qi::subrule; + + namespace phx = boost::phoenix; + + + { // basic tests + + subrule<99> entry; + subrule<42> a; + subrule<48> b; + subrule<16> c; + rule start; + + entry.name("entry"); + a.name("a"); + b.name("b"); + c.name("c"); + start.name("start"); + +// debug(entry); +// debug(a); +// debug(b); +// debug(c); + debug(start); + + // subrules with no rule + BOOST_TEST(test("abcabcacb", ( + entry = *(a | b | c) + , a = 'a' + , b = 'b' + , c = 'c' + ))); + + // check subrule group behaves as a parser + BOOST_TEST(test("xabcabcacb", 'x' >> ( + entry = *(a | b | c) + , a = 'a' + , b = 'b' + , c = 'c' + ))); + + // subrules in a rule + start = ( + entry = *(a | b | c) + , a = 'a' + , b = 'b' + , c = 'c' + ); + BOOST_TEST(test("abcabcacb", start)); + + // subrule -> rule call + start = ( + entry = (a | b) >> (start | b) + , a = 'a' + , b = 'b' + ); + BOOST_TEST(test("aaaabababaaabbb", start)); + BOOST_TEST(test("aaaabababaaabba", start, false)); + + // subrule recursion + start = ( + entry = (a | b) >> (entry | b) + , a = 'a' + , b = 'b' + ); + BOOST_TEST(test("aaaabababaaabbb", start)); + BOOST_TEST(test("aaaabababaaabba", start, false)); + + // no-ops +#if defined(BOOST_CLANG) && defined(__has_warning) +# pragma clang diagnostic push +# if __has_warning("-Wself-assign-overloaded") +# pragma clang diagnostic ignored "-Wself-assign-overloaded" +# endif +#endif + a = a; +#if defined(BOOST_CLANG) && defined(__has_warning) +# pragma clang diagnostic pop +#endif + subrule<42> aa(a); + } + + { // basic tests w/ skipper, subrules declared const + + subrule<0> const entry("entry"); + subrule<1> const a("a"); + subrule<2> const b("b"); + subrule<3> const c("c"); + rule start("start"); + +// debug(entry); +// debug(a); +// debug(b); +// debug(c); + debug(start); + + start = ( + entry = *(a | b | c) + , a = 'a' + , b = 'b' + , c = 'c' + ); + BOOST_TEST(test(" a b c a b c a c b ", start, space)); + + start = ( + entry = (a | b) >> (entry | b) + , a = 'a' + , b = 'b' + ); + BOOST_TEST(test(" a a a a b a b a b a a a b b b ", start, space)); + BOOST_TEST(test(" a a a a b a b a b a a a b b a ", start, space, false)); + + // no-ops +#if defined(BOOST_CLANG) && defined(__has_warning) +# pragma clang diagnostic push +# if __has_warning("-Wself-assign-overloaded") +# pragma clang diagnostic ignored "-Wself-assign-overloaded" +# endif +#endif + a = a; +#if defined(BOOST_CLANG) && defined(__has_warning) +# pragma clang diagnostic pop +#endif + subrule<1> aa(a); + } + + { // context tests + + char ch; + rule a; + subrule<0, char()> entry; + + a = (entry = alpha[_val = _1])[_val = _1]; + BOOST_TEST(test("x", a[phx::ref(ch) = _1])); + BOOST_TEST(ch == 'x'); + + a %= (entry = alpha[_val = _1]); + BOOST_TEST(test_attr("z", a, ch)); // attribute is given. + BOOST_TEST(ch == 'z'); + } + + { // auto subrules tests + + char ch; + rule a; + subrule<0, char()> entry; + + a = (entry %= alpha)[_val = _1]; + BOOST_TEST(test("x", a[phx::ref(ch) = _1])); + BOOST_TEST(ch == 'x'); + + a %= (entry %= alpha); + BOOST_TEST(test_attr("z", a, ch)); // attribute is given. + BOOST_TEST(ch == 'z'); + } + + { // auto subrules tests: allow stl containers as attributes to + // sequences (in cases where attributes of the elements + // are convertible to the value_type of the container or if + // the element itself is an stl container with value_type + // that is convertible to the value_type of the attribute). + + std::string s; + rule r; + subrule<0, std::string()> entry; + + r %= (entry %= char_ >> *(',' >> char_)); + BOOST_TEST(test("a,b,c,d,e,f", r[phx::ref(s) = _1])); + BOOST_TEST(s == "abcdef"); + + BOOST_TEST(test("abcdef", ( + entry %= char_ >> char_ >> char_ >> char_ >> char_ >> char_ + )[phx::ref(s) = _1])); + BOOST_TEST(s == "abcdef"); + } + + { // synth attribute value-init + + std::string s; + subrule<0, char()> sr; + BOOST_TEST(test_attr("abcdef", +(sr = alpha[_val += _1]), s)); + BOOST_TEST(s == "abcdef"); + } + + { // auto subrules aliasing tests + + char ch; + rule r; + subrule<0, char()> a; + subrule<1, char()> b; + r %= ( + a %= b + , b %= alpha + ); + + BOOST_TEST(test("x", r[phx::ref(ch) = _1])); + BOOST_TEST(ch == 'x'); + + BOOST_TEST(test_attr("z", r, ch)); // attribute is given. + BOOST_TEST(ch == 'z'); + } + + { // context (w/arg) tests + + char ch; + + // entry subrule with 1 arg + rule a; + subrule<1, char(int)> sr1; + a %= ( + sr1 = alpha[_val = _1 + _r1] + )(_r1); + BOOST_TEST(test("x", a(phx::val(1))[phx::ref(ch) = _1])); + BOOST_TEST(ch == 'x' + 1); + + // other subrule with 1 arg + subrule<0, char()> sr0; + a %= ( + sr0 %= sr1(1) + , sr1 = alpha[_val = _1 + _r1] + ); + + // allow scalars as subrule args too + rule b; + b %= ( + sr1 = alpha[_val = _1 + _r1] + )(1); + BOOST_TEST(test_attr("b", b, ch)); + BOOST_TEST(ch == 'b' + 1); + + // entry subrule with 2 args + subrule<2, char(int, int)> sr2; + BOOST_TEST(test_attr("a", ( + sr2 = alpha[_val = _1 + _r1 + _r2] + )(1, 2), ch)); + BOOST_TEST(ch == 'a' + 1 + 2); + + // multiple subrules + args + BOOST_TEST(test_attr("ba", ( + sr2 = alpha[_val = _1 + _r1 + _r2] >> sr1(3)[_val -= _1] + , sr1 = alpha[_val = _1 + _r1] + )(1, 2), ch)); + BOOST_TEST(ch == ('b' + 1 + 2) - ('a' + 3)); + } + + { // context (w/ reference arg) tests + + char ch; + subrule<0, void(char&)> sr; // 1 arg (reference) - direct + BOOST_TEST(test("x", (sr = alpha[_r1 = _1])(phx::ref(ch)))); + BOOST_TEST(ch == 'x'); + + rule a; // forwarded via a rule + a = (sr = alpha[_r1 = _1])(_r1); + BOOST_TEST(test("y", a(phx::ref(ch)))); + BOOST_TEST(ch == 'y'); + } + + { // context (w/locals) tests + + rule r; + subrule<0, locals > a; // 1 local + r = ( + a = alpha[_a = _1] >> char_(_a) + ); + BOOST_TEST(test("aa", r)); + BOOST_TEST(!test("ax", r)); + } + + { // context (w/args and locals) tests + + rule a; + subrule<0, void(int), locals > sr; // 1 arg + 1 local + a = ( + sr = alpha[_a = _1 + _r1] >> char_(_a) + )(_r1); + BOOST_TEST(test("ab", a(phx::val(1)))); + BOOST_TEST(test("xy", a(phx::val(1)))); + BOOST_TEST(!test("ax", a(phx::val(1)))); + } + + { // void() has unused type (void == unused_type) + + std::pair attr; + subrule<0, void()> sr; + BOOST_TEST(test_attr("123ax", int_ >> char_ >> (sr = char_), attr)); + BOOST_TEST(attr.first == 123); + BOOST_TEST(attr.second == 'a'); + } + + { // test that injected attributes are ok + + rule r; + subrule<0, char(int)> sr; + + r = ( + sr = char_(_r1)[_val = _1] + )(42); + } + + { // show that sra = srb and sra %= srb works as expected + subrule<0, int()> sra; + subrule<1, int()> srb; + int attr; + + BOOST_TEST(test_attr("123", (sra %= int_), attr)); + BOOST_TEST(attr == 123); + + BOOST_TEST(test_attr("123", (srb %= sra, sra %= int_), attr)); + BOOST_TEST(attr == 123); + + BOOST_TEST(test_attr("123", (srb = sra, sra %= int_), attr)); + BOOST_TEST(attr == 123); + } + + { // std::string as container attribute with auto subrules + + subrule<0, std::string()> text; + std::string attr; + BOOST_TEST(test_attr("x", ( + text %= +(!char_(')') >> !char_('>') >> char_) + ), attr)); + BOOST_TEST(attr == "x"); + } + +// { // error handling +// +// using namespace boost::spirit::ascii; +// using boost::phoenix::construct; +// using boost::phoenix::bind; +// +// rule r; +// r = '(' > int_ > ',' > int_ > ')'; +// +// on_error +// ( +// r, std::cout +// << phx::val("Error! Expecting: ") +// << _4 +// << phx::val(", got: \"") +// << construct(_3, _2) +// << phx::val("\"") +// << std::endl +// ); +// +// BOOST_TEST(test("(123,456)", r)); +// BOOST_TEST(!test("(abc,def)", r)); +// BOOST_TEST(!test("(123,456]", r)); +// BOOST_TEST(!test("(123;456)", r)); +// BOOST_TEST(!test("[123,456]", r)); +// } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/spirit/repository/test/qi/test.hpp b/src/boost/libs/spirit/repository/test/qi/test.hpp new file mode 100644 index 00000000..88cc7503 --- /dev/null +++ b/src/boost/libs/spirit/repository/test/qi/test.hpp @@ -0,0 +1,102 @@ +/*============================================================================= + Copyright (c) 2001-2010 Joel de Guzman + + 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) +=============================================================================*/ +#if !defined(BOOST_SPIRIT_TEST_FEBRUARY_01_2007_0605PM) +#define BOOST_SPIRIT_TEST_FEBRUARY_01_2007_0605PM + +#include +#include +#include +#include + +namespace spirit_test +{ + template + inline bool test(Char const* in, Parser const& p, bool full_match = true) + { + // we don't care about the result of the "what" function. + // we only care that all parsers have it: + boost::spirit::qi::what(p); + + Char const* last = in; + while (*last) + last++; + return boost::spirit::qi::parse(in, last, p) + && (!full_match || (in == last)); + } + + template + inline bool test(Char const* in, Parser const& p + , Skipper const& s, bool full_match = true) + { + // we don't care about the result of the "what" function. + // we only care that all parsers have it: + boost::spirit::qi::what(p); + + Char const* last = in; + while (*last) + last++; + return boost::spirit::qi::phrase_parse(in, last, p, s) + && (!full_match || (in == last)); + } + + template + inline bool test_attr(Char const* in, Parser const& p + , Attr& attr, bool full_match = true) + { + // we don't care about the result of the "what" function. + // we only care that all parsers have it: + boost::spirit::qi::what(p); + + Char const* last = in; + while (*last) + last++; + return boost::spirit::qi::parse(in, last, p, attr) + && (!full_match || (in == last)); + } + + template + inline bool test_attr(Char const* in, Parser const& p + , Attr& attr, Skipper const& s, bool full_match = true) + { + // we don't care about the result of the "what" function. + // we only care that all parsers have it: + boost::spirit::qi::what(p); + + Char const* last = in; + while (*last) + last++; + return boost::spirit::qi::phrase_parse(in, last, p, s, attr) + && (!full_match || (in == last)); + } + + struct printer + { + typedef boost::spirit::utf8_string string; + + void element(string const& tag, string const& value, int depth) const + { + for (int i = 0; i < (depth*4); ++i) // indent to depth + std::cout << ' '; + + std::cout << "tag: " << tag; + if (value != "") + std::cout << ", value: " << value; + std::cout << std::endl; + } + }; + + inline void print_info(boost::spirit::info const& what) + { + using boost::spirit::basic_info_walker; + + printer pr; + basic_info_walker walker(pr, what.tag, 0); + boost::apply_visitor(walker, what.value); + } +} + +#endif diff --git a/src/boost/libs/spirit/repository/test/test_headers/Jamfile b/src/boost/libs/spirit/repository/test/test_headers/Jamfile new file mode 100644 index 00000000..0b197a68 --- /dev/null +++ b/src/boost/libs/spirit/repository/test/test_headers/Jamfile @@ -0,0 +1,81 @@ +# Jamfile +# +# Copyright (c) 2007-2008 Steven Watanabe +# Copyright (c) 2009 Joel de Guzman +# Copyright (c) 2009 Hartmut Kaiser +# Copyright (c) 2009 Francois Barel +# +# 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 + +import testing ; +import path ; +import regex ; +import print ; +import sequence ; +import feature ; + +project boost/spirit/repository/test/test_headers + : requirements + $(BOOST_ROOT) + ../../../../.. + 300 + ; + +headers = +[ + path.glob-tree ../../../../../boost/spirit/repository/include : *.hpp +] ; + +main_headers = +[ + path.glob-tree ../../../../../boost/spirit/include : *.hpp : classic* phoenix1* +] ; + +for local file in $(headers) +{ + compile test.cpp + : # requirements + BOOST_SPIRIT_HEADER_NAME=$(file) + $(file) + : # test name + [ regex.replace [ path.relative-to ../../../../../boost/spirit/repository $(file) ] "/" "_" ] + ; +} + +feature.feature : forward reverse : incidental ; + +rule generate-include-all ( target : sources * : properties * ) +{ + print.output $(target) ; + + if reverse in $(properties) + { + sources = [ sequence.reverse $(sources) ] ; + } + + for local file in $(sources) + { + print.text "#include <$(file:G=)> +" : overwrite ; + } + +} + +make auto_all1.cpp + : $(headers) $(main_headers) + : @generate-include-all + ; + +make auto_all2.cpp + : $(headers) $(main_headers) + : @generate-include-all + : reverse + ; + +# this ought to catch non-inlined functions and other duplicate definitions +link auto_all1.cpp auto_all2.cpp main.cpp + : . + : auto_all_headers + ; diff --git a/src/boost/libs/spirit/repository/test/test_headers/main.cpp b/src/boost/libs/spirit/repository/test/test_headers/main.cpp new file mode 100644 index 00000000..99aacc62 --- /dev/null +++ b/src/boost/libs/spirit/repository/test/test_headers/main.cpp @@ -0,0 +1,14 @@ +// Copyright (c) 2003-2008 Matthias Christian Schabel +// Copyright (c) 2007-2008 Steven Watanabe +// Copyright (c) 2010 Joel de Guzman +// Copyright (c) 2010 Hartmut Kaiser +// Copyright (c) 2009 Francois Barel +// +// 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) + +int main() +{ + return 0; +} diff --git a/src/boost/libs/spirit/repository/test/test_headers/test.cpp b/src/boost/libs/spirit/repository/test/test_headers/test.cpp new file mode 100644 index 00000000..c6814198 --- /dev/null +++ b/src/boost/libs/spirit/repository/test/test_headers/test.cpp @@ -0,0 +1,22 @@ +// Copyright (c) 2003-2008 Matthias Christian Schabel +// Copyright (c) 2007-2008 Steven Watanabe +// Copyright (c) 2010 Joel de Guzman +// Copyright (c) 2010 Hartmut Kaiser +// Copyright (c) 2009 Francois Barel +// +// 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_SPIRIT_STRINGIZE_IMPL(x) #x +#define BOOST_SPIRIT_STRINGIZE(x) BOOST_SPIRIT_STRINGIZE_IMPL(x) + +#define BOOST_SPIRIT_HEADER BOOST_SPIRIT_STRINGIZE(BOOST_SPIRIT_HEADER_NAME) + +#include BOOST_SPIRIT_HEADER +#include BOOST_SPIRIT_HEADER + +int main() +{ + return 0; +} -- cgit v1.2.3