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 <cassert> |
---|
13 | #include <boost/spirit/core.hpp> |
---|
14 | #include <boost/spirit/symbols/symbols.hpp> |
---|
15 | #include <boost/detail/lightweight_test.hpp> |
---|
16 | |
---|
17 | /////////////////////////////////////////////////////////////////////////////// |
---|
18 | using namespace std; |
---|
19 | using namespace boost::spirit; |
---|
20 | |
---|
21 | /////////////////////////////////////////////////////////////////////////////// |
---|
22 | |
---|
23 | template <typename IteratorT> |
---|
24 | bool |
---|
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 |
---|
37 | check |
---|
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 | { |
---|
68 | store_action(T const &v) : value(v) {} |
---|
69 | void operator()(T &v) const { v = value; } |
---|
70 | private: |
---|
71 | T const value; |
---|
72 | }; |
---|
73 | |
---|
74 | template <typename T> |
---|
75 | store_action<T> |
---|
76 | store(T const &v) |
---|
77 | { |
---|
78 | return v; |
---|
79 | } |
---|
80 | |
---|
81 | template <typename T> |
---|
82 | struct check_action |
---|
83 | { |
---|
84 | check_action(T const &v) : value(v) {} |
---|
85 | |
---|
86 | #define correct_value_stored (v==value) |
---|
87 | 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> |
---|
94 | check(T const &v) |
---|
95 | { |
---|
96 | return v; |
---|
97 | } |
---|
98 | |
---|
99 | |
---|
100 | static void |
---|
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 |
---|
112 | narrow_match_tests() |
---|
113 | { |
---|
114 | symbols<> sym; |
---|
115 | sym = "pineapple", "orange", "banana", "applepie", "apple"; |
---|
116 | |
---|
117 | check(sym, "pineapple", true, "", 9); |
---|
118 | check(sym, "orange", true, "", 6); |
---|
119 | check(sym, "banana", true, "", 6); |
---|
120 | check(sym, "apple", true, "", 5); |
---|
121 | check(sym, "pizza", false, "pizza", -1); |
---|
122 | check(sym, "steak", false, "steak", -1); |
---|
123 | check(sym, "applepie", true, "", 8); |
---|
124 | check(sym, "bananarama", true, "rama", 6); |
---|
125 | check(sym, "applet", true, "t", 5); |
---|
126 | check(sym, "applepi", true, "pi", 5); |
---|
127 | check(sym, "appl", false, "appl", -1); |
---|
128 | |
---|
129 | check(sym, "pineapplez", true, "z", 9); |
---|
130 | check(sym, "orangez", true, "z", 6); |
---|
131 | check(sym, "bananaz", true, "z", 6); |
---|
132 | check(sym, "applez", true, "z", 5); |
---|
133 | check(sym, "pizzaz", false, "pizzaz", -1); |
---|
134 | check(sym, "steakz", false, "steakz", -1); |
---|
135 | check(sym, "applepiez", true, "z", 8); |
---|
136 | check(sym, "bananaramaz", true, "ramaz", 6); |
---|
137 | check(sym, "appletz", true, "tz", 5); |
---|
138 | check(sym, "applepix", true, "pix", 5); |
---|
139 | } |
---|
140 | |
---|
141 | static void |
---|
142 | narrow_copy_ctor_tests() |
---|
143 | { |
---|
144 | symbols<> sym; |
---|
145 | sym = "pineapple", "orange", "banana", "applepie", "apple"; |
---|
146 | |
---|
147 | symbols<> sym2(sym); |
---|
148 | check(sym2, "pineapple", true, "", 9); |
---|
149 | check(sym2, "pizza", false, "pizza", -1); |
---|
150 | check(sym2, "bananarama", true, "rama", 6); |
---|
151 | } |
---|
152 | |
---|
153 | static void |
---|
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 | check(sym2, "pineapple", true, "", 9); |
---|
163 | check(sym2, "pizza", false, "pizza", -1); |
---|
164 | check(sym2, "bananarama", true, "rama", 6); |
---|
165 | } |
---|
166 | |
---|
167 | static void |
---|
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[check(12345)]); |
---|
178 | parse("pineapple", sym[check(1234)]); |
---|
179 | parse("banana", sym[check(int())]); |
---|
180 | parse("lemon", sym[check(int())]); |
---|
181 | } |
---|
182 | |
---|
183 | static void |
---|
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 |
---|
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 | check(sym, L"pineapple", true, L"", 9); |
---|
211 | check(sym, L"orange", true, L"", 6); |
---|
212 | check(sym, L"banana", true, L"", 6); |
---|
213 | check(sym, L"apple", true, L"", 5); |
---|
214 | check(sym, L"pizza", false, L"pizza", -1); |
---|
215 | check(sym, L"steak", false, L"steak", -1); |
---|
216 | check(sym, L"applepie", true, L"", 8); |
---|
217 | check(sym, L"bananarama", true, L"rama", 6); |
---|
218 | check(sym, L"applet", true, L"t", 5); |
---|
219 | check(sym, L"applepi", true, L"pi", 5); |
---|
220 | check(sym, L"appl", false, L"appl", -1); |
---|
221 | |
---|
222 | check(sym, L"pineapplez", true, L"z", 9); |
---|
223 | check(sym, L"orangez", true, L"z", 6); |
---|
224 | check(sym, L"bananaz", true, L"z", 6); |
---|
225 | check(sym, L"applez", true, L"z", 5); |
---|
226 | check(sym, L"pizzaz", false, L"pizzaz", -1); |
---|
227 | check(sym, L"steakz", false, L"steakz", -1); |
---|
228 | check(sym, L"applepiez", true, L"z", 8); |
---|
229 | check(sym, L"bananaramaz", true, L"ramaz", 6); |
---|
230 | check(sym, L"appletz", true, L"tz", 5); |
---|
231 | check(sym, L"applepix", true, L"pix", 5); |
---|
232 | } |
---|
233 | |
---|
234 | static void |
---|
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 | check(sym2, L"pineapple", true, L"", 9); |
---|
242 | check(sym2, L"pizza", false, L"pizza", -1); |
---|
243 | check(sym2, L"bananarama", true, L"rama", 6); |
---|
244 | } |
---|
245 | |
---|
246 | static void |
---|
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 | check(sym2, L"pineapple", true, L"", 9); |
---|
256 | check(sym2, L"pizza", false, L"pizza", -1); |
---|
257 | check(sym2, L"bananarama", true, L"rama", 6); |
---|
258 | } |
---|
259 | |
---|
260 | static void |
---|
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[check(12345)]); |
---|
271 | parse(L"pineapple", sym[check(1234)]); |
---|
272 | parse(L"banana", sym[check(int())]); |
---|
273 | parse(L"lemon", sym[check(int())]); |
---|
274 | } |
---|
275 | |
---|
276 | static void |
---|
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 |
---|
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 |
---|
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 | } |
---|