1 /*=============================================================================
2     Copyright (c) 1998-2003 Joel de Guzman
3     Copyright (c)      2003 Martin Wille
4     http://spirit.sourceforge.net/
5 
6     Use, modification and distribution is subject to the Boost Software
7     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8     http://www.boost.org/LICENSE_1_0.txt)
9 =============================================================================*/
10 #include <iostream>
11 #include <string>
12 #include <boost/detail/lightweight_test.hpp>
13 #include <boost/spirit/include/classic_core.hpp>
14 #include <boost/spirit/include/classic_symbols.hpp>
15 #include <boost/detail/lightweight_test.hpp>
16 
17 ///////////////////////////////////////////////////////////////////////////////
18 using namespace std;
19 using namespace BOOST_SPIRIT_CLASSIC_NS;
20 
21 ///////////////////////////////////////////////////////////////////////////////
22 
23 template <typename IteratorT>
24 bool
equal(IteratorT p,IteratorT q)25 equal(IteratorT p, IteratorT q)
26 {
27     while (*p && *p == *q)
28     {
29         ++p;
30         ++q;
31     }
32     return *p == *q;
33 }
34 
35 template <class SymbolsT, typename CharT>
36 void
docheck(SymbolsT const & sym,CharT const * candidate,bool hit,CharT const * result,int length)37 docheck
38 (
39     SymbolsT const &sym,
40     CharT    const *candidate,
41     bool           hit,
42     CharT    const *result,
43     int            length
44 )
45 {
46     parse_info<CharT const*> info = parse(candidate, sym);
47 
48 #define correctly_matched hit == info.hit
49 #define correct_match_length unsigned(length) == info.length
50 #define correct_tail equal(candidate + (hit?1:0)*length, result)
51 
52     BOOST_TEST(correctly_matched);
53 
54     if (hit)
55     {
56         BOOST_TEST(correct_match_length);
57         BOOST_TEST(correct_tail);
58     }
59     else
60     {
61         BOOST_TEST(correct_tail);
62     }
63 }
64 
65 template <typename T>
66 struct store_action
67 {
store_actionstore_action68     store_action(T const &v) : value(v) {}
operator ()store_action69     void operator()(T &v) const { v = value; }
70 private:
71     T const value;
72 };
73 
74 template <typename T>
75 store_action<T>
store(T const & v)76 store(T const &v)
77 {
78     return v;
79 }
80 
81 template <typename T>
82 struct check_action
83 {
check_actioncheck_action84     check_action(T const &v) : value(v) {}
85 
86 #define correct_value_stored (v==value)
operator ()check_action87     void operator()(T const &v) const { BOOST_TEST(correct_value_stored); }
88 private:
89     T const value;
90 };
91 
92 template <typename T>
93 check_action<T>
docheck(T const & v)94 docheck(T const &v)
95 {
96     return v;
97 }
98 
99 
100 static void
default_constructible()101 default_constructible()
102 {   // this actually a compile time test
103     symbols<>                     ns1;
104     symbols<int, wchar_t>         ws1;
105     symbols<std::string, char>    ns2;
106     symbols<std::string, wchar_t> ws2;
107 
108     (void)ns1; (void)ws1; (void)ns2; (void)ws2;
109 }
110 
111 static void
narrow_match_tests()112 narrow_match_tests()
113 {
114     symbols<>   sym;
115     sym = "pineapple", "orange", "banana", "applepie", "apple";
116 
117     docheck(sym, "pineapple", true, "", 9);
118     docheck(sym, "orange", true, "", 6);
119     docheck(sym, "banana", true, "", 6);
120     docheck(sym, "apple", true, "", 5);
121     docheck(sym, "pizza", false, "pizza", -1);
122     docheck(sym, "steak", false, "steak", -1);
123     docheck(sym, "applepie", true, "", 8);
124     docheck(sym, "bananarama", true, "rama", 6);
125     docheck(sym, "applet", true, "t", 5);
126     docheck(sym, "applepi", true, "pi", 5);
127     docheck(sym, "appl", false, "appl", -1);
128 
129     docheck(sym, "pineapplez", true, "z", 9);
130     docheck(sym, "orangez", true, "z", 6);
131     docheck(sym, "bananaz", true, "z", 6);
132     docheck(sym, "applez", true, "z", 5);
133     docheck(sym, "pizzaz", false, "pizzaz", -1);
134     docheck(sym, "steakz", false, "steakz", -1);
135     docheck(sym, "applepiez", true, "z", 8);
136     docheck(sym, "bananaramaz", true, "ramaz", 6);
137     docheck(sym, "appletz", true, "tz", 5);
138     docheck(sym, "applepix", true, "pix", 5);
139 }
140 
141 static void
narrow_copy_ctor_tests()142 narrow_copy_ctor_tests()
143 {
144     symbols<>   sym;
145     sym = "pineapple", "orange", "banana", "applepie", "apple";
146 
147     symbols<>   sym2(sym);
148     docheck(sym2, "pineapple", true, "", 9);
149     docheck(sym2, "pizza", false, "pizza", -1);
150     docheck(sym2, "bananarama", true, "rama", 6);
151 }
152 
153 static void
narrow_assigment_operator_tests()154 narrow_assigment_operator_tests()
155 {
156     symbols<>   sym;
157     sym = "pineapple", "orange", "banana", "applepie", "apple";
158 
159     symbols<>   sym2;
160     sym2 = sym;
161 
162     docheck(sym2, "pineapple", true, "", 9);
163     docheck(sym2, "pizza", false, "pizza", -1);
164     docheck(sym2, "bananarama", true, "rama", 6);
165 }
166 
167 static void
narrow_value_tests()168 narrow_value_tests()
169 {   // also tests the add member functions
170     symbols<>   sym;
171 
172     sym = "orange", "banana";
173     sym.add("pineapple",1234);
174     sym.add("lemon");
175 
176     parse("orange", sym[store(12345)]);
177     parse("orange", sym[docheck(12345)]);
178     parse("pineapple", sym[docheck(1234)]);
179     parse("banana", sym[docheck(int())]);
180     parse("lemon", sym[docheck(int())]);
181 }
182 
183 static void
narrow_free_functions_tests()184 narrow_free_functions_tests()
185 {
186     symbols<>   sym;
187 
188 #define add_returned_non_null_value (res!=0)
189 #define add_returned_null (res==0)
190 #define find_returned_non_null_value (res!=0)
191 #define find_returned_null (res==0)
192 
193     int *res = add(sym,"pineapple");
194     BOOST_TEST(add_returned_non_null_value);
195     res = add(sym,"pineapple");
196     BOOST_TEST(add_returned_null);
197 
198     res = find(sym, "pineapple");
199     BOOST_TEST(find_returned_non_null_value);
200     res = find(sym, "banana");
201     BOOST_TEST(find_returned_null);
202 }
203 
204 static void
wide_match_tests()205 wide_match_tests()
206 {
207     symbols<int, wchar_t>   sym;
208     sym = L"pineapple", L"orange", L"banana", L"applepie", L"apple";
209 
210     docheck(sym, L"pineapple", true, L"", 9);
211     docheck(sym, L"orange", true, L"", 6);
212     docheck(sym, L"banana", true, L"", 6);
213     docheck(sym, L"apple", true, L"", 5);
214     docheck(sym, L"pizza", false, L"pizza", -1);
215     docheck(sym, L"steak", false, L"steak", -1);
216     docheck(sym, L"applepie", true, L"", 8);
217     docheck(sym, L"bananarama", true, L"rama", 6);
218     docheck(sym, L"applet", true, L"t", 5);
219     docheck(sym, L"applepi", true, L"pi", 5);
220     docheck(sym, L"appl", false, L"appl", -1);
221 
222     docheck(sym, L"pineapplez", true, L"z", 9);
223     docheck(sym, L"orangez", true, L"z", 6);
224     docheck(sym, L"bananaz", true, L"z", 6);
225     docheck(sym, L"applez", true, L"z", 5);
226     docheck(sym, L"pizzaz", false, L"pizzaz", -1);
227     docheck(sym, L"steakz", false, L"steakz", -1);
228     docheck(sym, L"applepiez", true, L"z", 8);
229     docheck(sym, L"bananaramaz", true, L"ramaz", 6);
230     docheck(sym, L"appletz", true, L"tz", 5);
231     docheck(sym, L"applepix", true, L"pix", 5);
232 }
233 
234 static void
wide_copy_ctor_tests()235 wide_copy_ctor_tests()
236 {
237     symbols<int, wchar_t>   sym;
238     sym = L"pineapple", L"orange", L"banana", L"applepie", L"apple";
239 
240     symbols<int, wchar_t>   sym2(sym);
241     docheck(sym2, L"pineapple", true, L"", 9);
242     docheck(sym2, L"pizza", false, L"pizza", -1);
243     docheck(sym2, L"bananarama", true, L"rama", 6);
244 }
245 
246 static void
wide_assigment_operator_tests()247 wide_assigment_operator_tests()
248 {
249     symbols<int, wchar_t>   sym;
250     sym = L"pineapple", L"orange", L"banana", L"applepie", L"apple";
251 
252     symbols<int, wchar_t>   sym2;
253     sym2 = sym;
254 
255     docheck(sym2, L"pineapple", true, L"", 9);
256     docheck(sym2, L"pizza", false, L"pizza", -1);
257     docheck(sym2, L"bananarama", true, L"rama", 6);
258 }
259 
260 static void
wide_value_tests()261 wide_value_tests()
262 {   // also tests the add member functions
263     symbols<int, wchar_t>   sym;
264 
265     sym = L"orange", L"banana";
266     sym.add(L"pineapple",1234);
267     sym.add(L"lemon");
268 
269     parse(L"orange", sym[store(12345)]);
270     parse(L"orange", sym[docheck(12345)]);
271     parse(L"pineapple", sym[docheck(1234)]);
272     parse(L"banana", sym[docheck(int())]);
273     parse(L"lemon", sym[docheck(int())]);
274 }
275 
276 static void
wide_free_functions_tests()277 wide_free_functions_tests()
278 {
279     symbols<int, wchar_t>   sym;
280 
281     int *res = add(sym,L"pineapple");
282     BOOST_TEST(add_returned_non_null_value);
283     res = add(sym,L"pineapple");
284     BOOST_TEST(add_returned_null);
285 
286     res = find(sym, L"pineapple");
287     BOOST_TEST(find_returned_non_null_value);
288     res = find(sym, L"banana");
289     BOOST_TEST(find_returned_null);
290 }
291 
292 static
free_add_find_functions_tests()293 void free_add_find_functions_tests()
294 {
295     symbols<> sym;
296     BOOST_TEST(*add(sym, "a", 0) == 0);
297     BOOST_TEST(*add(sym, "a2", 1) == 1);
298     BOOST_TEST(find(sym, "a2"));
299     BOOST_TEST(find(sym, "a"));
300 }
301 
302 int
main()303 main()
304 {
305     default_constructible();
306     narrow_match_tests();
307     narrow_copy_ctor_tests();
308     narrow_assigment_operator_tests();
309     narrow_value_tests();
310     narrow_free_functions_tests();
311     wide_match_tests();
312     wide_copy_ctor_tests();
313     wide_assigment_operator_tests();
314     wide_value_tests();
315     wide_free_functions_tests();
316     free_add_find_functions_tests();
317     return boost::report_errors();
318 }
319