1 /*=============================================================================
2     Copyright (c) 2001-2011 Joel de Guzman
3 
4     Distributed under the Boost Software License, Version 1.0. (See accompanying
5     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 =============================================================================*/
7 #include <string>
8 #include <vector>
9 
10 #include <boost/detail/lightweight_test.hpp>
11 
12 #include <boost/spirit/include/qi_operator.hpp>
13 #include <boost/spirit/include/qi_char.hpp>
14 #include <boost/spirit/include/qi_string.hpp>
15 #include <boost/spirit/include/qi_numeric.hpp>
16 #include <boost/spirit/include/qi_directive.hpp>
17 #include <boost/spirit/include/qi_action.hpp>
18 #include <boost/spirit/include/support_argument.hpp>
19 #include <boost/spirit/include/phoenix_core.hpp>
20 #include <boost/spirit/include/phoenix_operator.hpp>
21 
22 #include <string>
23 #include <iostream>
24 #include "test.hpp"
25 
26 struct x_attr
27 {
28 };
29 
30 namespace boost { namespace spirit { namespace traits
31 {
32     template <>
33     struct container_value<x_attr>
34     {
35         typedef char type; // value type of container
36     };
37 
38     template <>
39     struct push_back_container<x_attr, char>
40     {
callboost::spirit::traits::push_back_container41         static bool call(x_attr& /*c*/, char /*val*/)
42         {
43             // push back value type into container
44             return true;
45         }
46     };
47 }}}
48 
49 int
main()50 main()
51 {
52     using spirit_test::test;
53     using spirit_test::test_attr;
54     using namespace boost::spirit::ascii;
55     using boost::spirit::qi::omit;
56     using boost::spirit::qi::uint_;
57     using boost::spirit::qi::int_;
58     using boost::spirit::qi::lexeme;
59 
60     {
61         BOOST_TEST(test("aaaaaaaa", *char_));
62         BOOST_TEST(test("a", *char_));
63         BOOST_TEST(test("", *char_));
64         BOOST_TEST(test("aaaaaaaa", *alpha));
65         BOOST_TEST(!test("aaaaaaaa", *upper));
66     }
67 
68     {
69         BOOST_TEST(test(" a a aaa aa", *char_, space));
70         BOOST_TEST(test("12345 678 9", *digit, space));
71     }
72 
73     {
74         BOOST_TEST(test("aBcdeFGH", no_case[*char_]));
75         BOOST_TEST(test("a B cde FGH", no_case[*char_], space));
76     }
77 
78     {
79         BOOST_TEST(test("12345 678 955 987", *uint_, space));
80         BOOST_TEST(test("12345, 678, 955, 987", uint_ >> *(',' >> uint_), space));
81     }
82 
83     {
84         std::string s;
85         BOOST_TEST(test_attr("bbbb", *char_, s) && 4 == s.size() && s == "bbbb");
86 
87         s.clear();
88         BOOST_TEST(test_attr("b b b b ", *char_, s, space)  && s == "bbbb");
89 
90         // The following 2 tests show that omit does not inhibit explicit attributes
91         s.clear();
92         BOOST_TEST(test_attr("bbbb", omit[*char_('b')], s) && s == "bbbb");
93 
94         s.clear();
95         BOOST_TEST(test_attr("b b b b", omit[*char_('b')], s, space) && s == "bbbb");
96     }
97 
98     {
99         std::vector<int> v;
100         BOOST_TEST(test_attr("123 456 789 10", *int_, v, space) && 4 == v.size() &&
101             v[0] == 123 && v[1] == 456 && v[2] == 789 &&  v[3] == 10);
102     }
103 
104     {
105         std::vector<std::string> v;
106         BOOST_TEST(test_attr("a b c d", *lexeme[+alpha], v, space) && 4 == v.size() &&
107             v[0] == "a" && v[1] == "b" && v[2] == "c" &&  v[3] == "d");
108     }
109 
110     {
111         std::vector<int> v;
112         BOOST_TEST(test_attr("123 456 789", *int_, v, space) && 3 == v.size() &&
113             v[0] == 123 && v[1] == 456 && v[2] == 789);
114     }
115 
116     { // actions
117         namespace phx = boost::phoenix;
118         using boost::spirit::_1;
119 
120         std::vector<char> v;
121         BOOST_TEST(test("bbbb", (*char_)[phx::ref(v) = _1]) && 4 == v.size() &&
122             v[0] == 'b' && v[1] == 'b' && v[2] == 'b' &&  v[3] == 'b');
123     }
124 
125     { // more actions
126         namespace phx = boost::phoenix;
127         using boost::spirit::_1;
128 
129         std::vector<int> v;
130         BOOST_TEST(test("123 456 789", (*int_)[phx::ref(v) = _1], space) && 3 == v.size() &&
131             v[0] == 123 && v[1] == 456 && v[2] == 789);
132     }
133 
134     { // attribute customization
135 
136         x_attr x;
137         test_attr("abcde", *char_, x);
138     }
139 
140     return boost::report_errors();
141 }
142 
143