• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2003 Martin Wille
3     http://spirit.sourceforge.net/
4 
5     Use, modification and distribution is subject to the Boost Software
6     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7     http://www.boost.org/LICENSE_1_0.txt)
8 =============================================================================*/
9 // vi:ts=4:sw=4:et
10 // Tests for spirit::for_p
11 // [13-Jan-2003]
12 ////////////////////////////////////////////////////////////////////////////////
13 #include <iostream>
14 #include <cstring>
15 #include <string>
16 #include <boost/spirit/include/classic_core.hpp>
17 #include <boost/spirit/include/classic_assign_actor.hpp>
18 #include <boost/spirit/include/classic_for.hpp>
19 #include <boost/ref.hpp>
20 #include "impl/string_length.hpp"
21 
22 namespace local
23 {
24     template <typename T>
25     struct var_wrapper
26         : public ::boost::reference_wrapper<T>
27     {
28         typedef ::boost::reference_wrapper<T> parent;
29 
var_wrapperlocal::var_wrapper30         explicit inline var_wrapper(T& t) : parent(t) {}
31 
operator ()local::var_wrapper32         inline T& operator()() const { return parent::get(); }
33     };
34 
35     template <typename T>
36     inline var_wrapper<T>
var(T & t)37     var(T& t)
38     {
39         return var_wrapper<T>(t);
40     }
41 }
42 
43 namespace
44 {
45     template <typename T>
46     class add_actor
47     {
48     public:
add_actor(T & ref_)49         explicit add_actor(T &ref_) : ref(ref_) {}
50 
51         template <typename T2>
operator ()(T2 const & val) const52         void operator()(T2 const &val) const
53         { ref += val; }
54 
55     private:
56         T& ref;
57     };
58 
59     template <typename T>
60     inline add_actor<T> const
add(T & ref)61     add(T& ref)
62     {
63         return add_actor<T>(ref);
64     }
65 }
66 
67 typedef ::BOOST_SPIRIT_CLASSIC_NS::rule<> rule_t;
68 
69 unsigned int test_count = 0;
70 unsigned int error_count = 0;
71 
72 unsigned int iterations_performed;
73 unsigned int iterations_desired;
74 std::string  input_matched;
75 
76 //static const unsigned int kError = 999;
77 static const bool good = true;
78 static const bool bad = false;
79 
80 rule_t for_rule;
81 rule_t for_rule2;
82 
83 void
test_for(char const * s,bool succeed,rule_t const & r,unsigned int iterations_expected)84 test_for
85 (
86     char const *s,
87     bool succeed,
88     rule_t const &r,
89     unsigned int iterations_expected
90 )
91 {
92     using namespace std;
93 
94     ++test_count;
95 
96     iterations_performed = 0;
97 
98     ::BOOST_SPIRIT_CLASSIC_NS::parse_info<> m = ::BOOST_SPIRIT_CLASSIC_NS::parse(s, s + test_impl::string_length(s), r);
99 
100     bool result = (succeed==m.full)?good:bad;
101 
102     if (m.full && (m.length != test_impl::string_length(s)))
103         result = bad;
104 
105     result &= iterations_expected == iterations_performed;
106 
107     if (result==good)
108         cout << "PASSED";
109     else
110     {
111         ++error_count;
112         cout << "FAILED";
113     }
114 
115     cout << ": \"" << s << "\" ==> ";
116     if (!m.full)
117         cout << "<error>";
118     else
119         cout << '"' << input_matched << '"';
120 
121     cout << "     " << iterations_performed << " of "
122          << iterations_desired << " iterations\n";
123 }
124 
125 namespace
126 {
zero()127     void zero() { iterations_performed = 0; }
128 
129     struct inc
130     {
operator ()__anon8757a7670211::inc131         inline void operator()() const { ++iterations_performed; }
132     };
133     struct cmp
134     {
operator ()__anon8757a7670211::cmp135         inline bool operator()() const
136         {
137             return iterations_performed<iterations_desired;
138         }
139     };
140 }
141 
142 int
main()143 main()
144 {
145     using namespace std;
146 
147     using BOOST_SPIRIT_CLASSIC_NS::uint_p;
148     using BOOST_SPIRIT_CLASSIC_NS::for_p;
149     using BOOST_SPIRIT_CLASSIC_NS::assign_a;
150 
151 #if qDebug
152     SPIRIT_DEBUG_RULE(for_rule);
153     SPIRIT_DEBUG_RULE(for_rule2);
154 #endif
155 
156     for_rule
157         =   uint_p[assign_a(iterations_desired)] >> ':'
158         >>  for_p(&zero, cmp(), inc())["xy"]
159             [assign_a(input_matched)]
160         ;
161 
162     for_rule2
163         =   for_p(&zero, '.', inc())["xy"]
164             [assign_a(input_matched)]
165         ;
166 
167     cout << "/////////////////////////////////////////////////////////\n";
168     cout << "\n";
169     cout << "          for_p test\n";
170     cout << "\n";
171     cout << "/////////////////////////////////////////////////////////\n";
172     cout << "\n";
173 
174     test_for("3:xyxyxy",    true, for_rule, 3);
175     test_for("3:",         false, for_rule, 0);
176     test_for("3:xyxy",     false, for_rule, 2);
177     test_for("3:xyxyxyxy", false, for_rule, 3);
178 
179     test_for(".xy.xy.xy", true, for_rule2, 3);
180     test_for(".xy.xy.xy.", false, for_rule2, 3);
181 
182     std::cout << "\n    ";
183     if (error_count==0)
184         cout << "All " << test_count << " for_p-tests passed.\n"
185              << "Test concluded successfully\n";
186     else
187         cout << error_count << " of " << test_count << " for_p-tests failed\n"
188              << "Test failed\n";
189 
190     return error_count!=0;
191 }
192 
193