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 #define qDebug 0
14 #include <iostream>
15 #include <cstring>
16 #if qDebug
17 #define SPIRIT_DEBUG
18 #endif
19 #include <string>
20 #include <boost/spirit/include/classic_core.hpp>
21 #include <boost/spirit/include/classic_assign_actor.hpp>
22 #include <boost/spirit/include/classic_for.hpp>
23 #include <boost/ref.hpp>
24 #include "impl/string_length.hpp"
25
26 namespace local
27 {
28 template <typename T>
29 struct var_wrapper
30 : public ::boost::reference_wrapper<T>
31 {
32 typedef ::boost::reference_wrapper<T> parent;
33
var_wrapperlocal::var_wrapper34 explicit inline var_wrapper(T& t) : parent(t) {}
35
operator ()local::var_wrapper36 inline T& operator()() const { return parent::get(); }
37 };
38
39 template <typename T>
40 inline var_wrapper<T>
var(T & t)41 var(T& t)
42 {
43 return var_wrapper<T>(t);
44 }
45 }
46
47 namespace
48 {
49 template <typename T>
50 class add_actor
51 {
52 public:
add_actor(T & ref_)53 explicit add_actor(T &ref_) : ref(ref_) {}
54
55 template <typename T2>
operator ()(T2 const & val) const56 void operator()(T2 const &val) const
57 { ref += val; }
58
59 private:
60 T& ref;
61 };
62
63 template <typename T>
64 inline add_actor<T> const
add(T & ref)65 add(T& ref)
66 {
67 return add_actor<T>(ref);
68 }
69 }
70
71 typedef ::BOOST_SPIRIT_CLASSIC_NS::rule<> rule_t;
72
73 unsigned int test_count = 0;
74 unsigned int error_count = 0;
75
76 unsigned int iterations_performed;
77 unsigned int iterations_desired;
78 std::string input_matched;
79
80 //static const unsigned int kError = 999;
81 static const bool good = true;
82 static const bool bad = false;
83
84 rule_t for_rule;
85 rule_t for_rule2;
86
87 void
test_for(char const * s,bool succeed,rule_t const & r,unsigned int iterations_expected)88 test_for
89 (
90 char const *s,
91 bool succeed,
92 rule_t const &r,
93 unsigned int iterations_expected
94 )
95 {
96 using namespace std;
97
98 ++test_count;
99
100 iterations_performed = 0;
101
102 ::BOOST_SPIRIT_CLASSIC_NS::parse_info<> m = ::BOOST_SPIRIT_CLASSIC_NS::parse(s, s + test_impl::string_length(s), r);
103
104 bool result = (succeed==m.full)?good:bad;
105
106 if (m.full && (m.length != test_impl::string_length(s)))
107 result = bad;
108
109 result &= iterations_expected == iterations_performed;
110
111 if (result==good)
112 cout << "PASSED";
113 else
114 {
115 ++error_count;
116 cout << "FAILED";
117 }
118
119 cout << ": \"" << s << "\" ==> ";
120 if (!m.full)
121 cout << "<error>";
122 else
123 cout << '"' << input_matched << '"';
124
125 cout << " " << iterations_performed << " of "
126 << iterations_desired << " iterations\n";
127 }
128
129 namespace
130 {
zero()131 void zero() { iterations_performed = 0; }
132
133 struct inc
134 {
operator ()__anon5460ecdf0211::inc135 inline void operator()() const { ++iterations_performed; }
136 };
137 struct cmp
138 {
operator ()__anon5460ecdf0211::cmp139 inline bool operator()() const
140 {
141 return iterations_performed<iterations_desired;
142 }
143 };
144 }
145
146 int
main()147 main()
148 {
149 using namespace std;
150
151 using BOOST_SPIRIT_CLASSIC_NS::uint_p;
152 using BOOST_SPIRIT_CLASSIC_NS::for_p;
153 using BOOST_SPIRIT_CLASSIC_NS::assign_a;
154
155 #if qDebug
156 SPIRIT_DEBUG_RULE(for_rule);
157 SPIRIT_DEBUG_RULE(for_rule2);
158 #endif
159
160 for_rule
161 = uint_p[assign_a(iterations_desired)] >> ':'
162 >> for_p(&zero, cmp(), inc())["xy"]
163 [assign_a(input_matched)]
164 ;
165
166 for_rule2
167 = for_p(&zero, '.', inc())["xy"]
168 [assign_a(input_matched)]
169 ;
170
171 cout << "/////////////////////////////////////////////////////////\n";
172 cout << "\n";
173 cout << " for_p test\n";
174 cout << "\n";
175 cout << "/////////////////////////////////////////////////////////\n";
176 cout << "\n";
177
178 test_for("3:xyxyxy", true, for_rule, 3);
179 test_for("3:", false, for_rule, 0);
180 test_for("3:xyxy", false, for_rule, 2);
181 test_for("3:xyxyxyxy", false, for_rule, 3);
182
183 test_for(".xy.xy.xy", true, for_rule2, 3);
184 test_for(".xy.xy.xy.", false, for_rule2, 3);
185
186 std::cout << "\n ";
187 if (error_count==0)
188 cout << "All " << test_count << " for_p-tests passed.\n"
189 << "Test concluded successfully\n";
190 else
191 cout << error_count << " of " << test_count << " for_p-tests failed\n"
192 << "Test failed\n";
193
194 return error_count!=0;
195 }
196
197