1 /*=============================================================================
2     Copyright (c) 1998-2003 Joel de Guzman
3     Copyright (c) 2001-2003 Daniel Nuffer
4     Copyright (c) 2003      Martin Wille
5     http://spirit.sourceforge.net/
6 
7     Use, modification and distribution is subject to the Boost Software
8     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
9     http://www.boost.org/LICENSE_1_0.txt)
10 =============================================================================*/
11 #include <iostream>
12 #include <boost/detail/lightweight_test.hpp>
13 #include <boost/detail/lightweight_test.hpp>
14 #include "impl/sstream.hpp"
15 
16 #include <boost/spirit/include/classic_chset.hpp>
17 
18 using namespace std;
19 using namespace BOOST_SPIRIT_CLASSIC_NS;
20 
21 namespace
22 {
23     ///////////////////////////////////////////////////////////////////////////
24     //
25     //  chset tests
26     //
27     ///////////////////////////////////////////////////////////////////////////
28     void
DrawRuler(sstream_t & out,char const * str)29     DrawRuler(sstream_t& out, char const* str)
30     {
31         out << std::endl << std::endl;
32         out << "\t_____________________________________________________________\n";
33         out << "\t" << str << std::endl;
34         out << "\t";
35         for (char i = '!'; i < '^'; i++)
36             out << i;
37         out << "\n";
38         out << "\t_____________________________________________________________\n\n";
39     }
40 
41     //////////////////////////////////
42     template <typename CharT>
43     void
Draw(sstream_t & out,chset<CharT> a,char const * str)44     Draw(sstream_t& out, chset<CharT> a, char const* str)
45     {
46         out << "\t";
47 
48         for (int i = '!'; i < '^'; i++)
49             if (a.test(CharT(i)))
50                 out << '*';
51             else
52                 out << " ";
53 
54         out << "\t" << str << std::endl;
55     }
56 
57     //////////////////////////////////
58     template <typename CharT>
59     void
chset_tests(sstream_t & out,CharT const * a_,CharT b1_,CharT b2_,CharT e1_)60     chset_tests(sstream_t& out, CharT const* a_, CharT b1_, CharT b2_, CharT e1_)
61     {
62         chset<CharT>    a(a_);
63         range<CharT>    b_(b1_, b2_);
64         chset<CharT>    b(b_);
65         chset<CharT>    c(~a);  // ~char_parser code must not interfere
66                                 // with chset
67         negated_char_parser<range<CharT> > d_(~b_);
68         chset<CharT>    d(d_);
69         chlit<CharT>    e_(e1_);
70         chset<CharT>    e(e_);
71         negated_char_parser<chlit<CharT> > f_(e1_);
72         chset<CharT>    f(f_);
73 
74         DrawRuler(out, "Initial");
75         Draw(out, a, "a");
76         Draw(out, b, "b");
77         Draw(out, d, "d");
78         Draw(out, e, "e");
79         Draw(out, f, "f");
80 
81         DrawRuler(out, "Inverse");
82         Draw(out, ~a, "~a");
83         Draw(out, c, "chset<>(~a)");
84         Draw(out, ~~a, "~~a");
85         Draw(out, ~b, "~b");
86 
87         DrawRuler(out, "Union");
88         Draw(out, a, "a");
89         Draw(out, b, "b");
90         Draw(out, d, "d");
91         Draw(out, e, "e");
92         Draw(out, f, "f");
93         Draw(out, a | b, "a | b");
94         Draw(out, a | b_, "a | b_");
95         Draw(out, b_ | a, "b_ | a");
96         Draw(out, a | anychar_p, "a | anychar_p");
97         Draw(out, b | anychar_p, "b | anychar_p");
98         Draw(out, a | d, "a | d");
99         Draw(out, a | d_, "a | d_");
100         Draw(out, d_ | a, "d_ | a");
101         Draw(out, a | e_, "a | e_");
102         Draw(out, e_ | b, "e_ | b");
103         Draw(out, a | f_, "a | f_");
104         Draw(out, f_ | b, "f_ | b");
105 
106         DrawRuler(out, "Intersection");
107         Draw(out, a, "a");
108         Draw(out, b, "b");
109         Draw(out, d, "d");
110         Draw(out, e, "e");
111         Draw(out, f, "f");
112         Draw(out, a & b, "a & b");
113         Draw(out, a & b_, "a & b_");
114         Draw(out, b_ & a, "b_ & a");
115         Draw(out, a & d, "a & d");
116         Draw(out, a & d_, "a & d_");
117         Draw(out, d_ & a, "d_ & a");
118         Draw(out, a & e_, "a & e_");
119         Draw(out, e_ & b, "e_ & b");
120         Draw(out, a & f_, "a & f_");
121         Draw(out, f_ & b, "f_ & b");
122         Draw(out, a & anychar_p, "a & anychar_p");
123         Draw(out, b & anychar_p, "b & anychar_p");
124 
125         DrawRuler(out, "Difference");
126         Draw(out, a, "a");
127         Draw(out, b, "b");
128         Draw(out, d, "d");
129         Draw(out, e, "e");
130         Draw(out, f, "f");
131         Draw(out, a - b, "a - b");
132         Draw(out, b - a, "b - a");
133         Draw(out, a - b_, "a - b_");
134         Draw(out, b_ - a, "b_ - a");
135         Draw(out, a - d, "a - d");
136         Draw(out, d - a, "d - a");
137         Draw(out, a - d_, "a - d_");
138         Draw(out, d_ - a, "d_ - a");
139         Draw(out, a - e_, "a - e_");
140         Draw(out, e_ - b, "e_ - b");
141         Draw(out, a - f_, "a - f_");
142         Draw(out, f_ - b, "f_ - b");
143         Draw(out, a - anychar_p, "a - anychar_p");
144         Draw(out, anychar_p - a, "anychar_p - a");
145         Draw(out, b - anychar_p, "b - anychar_p");
146         Draw(out, anychar_p - b, "anychar_p - b");
147 
148         DrawRuler(out, "Xor");
149         Draw(out, a, "a");
150         Draw(out, b, "b");
151         Draw(out, d, "d");
152         Draw(out, e, "e");
153         Draw(out, f, "f");
154         Draw(out, a ^ b, "a ^ b");
155         Draw(out, a ^ b_, "a ^ b_");
156         Draw(out, b_ ^ a, "b_ ^ a");
157         Draw(out, a ^ d, "a ^ d");
158         Draw(out, a ^ d_, "a ^ d_");
159         Draw(out, d_ ^ a, "d_ ^ a");
160         Draw(out, a ^ e_, "a ^ e_");
161         Draw(out, e_ ^ b, "e_ ^ b");
162         Draw(out, a ^ f_, "a ^ f_");
163         Draw(out, f_ ^ b, "f_ ^ b");
164         Draw(out, a ^ nothing_p, "a ^ nothing_p");
165         Draw(out, a ^ anychar_p, "a ^ anychar_p");
166         Draw(out, b ^ nothing_p, "b ^ nothing_p");
167         Draw(out, b ^ anychar_p, "b ^ anychar_p");
168     }
169 
170     char const* expected_output =
171         "\n\n"
172         "\t_____________________________________________________________\n"
173         "\tInitial\n"
174         "\t!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]\n"
175         "\t_____________________________________________________________\n"
176         "\n"
177         "\t               **********       **************************   \ta\n"
178         "\t                    **********************                   \tb\n"
179         "\t********************                      *******************\td\n"
180         "\t                 *                                           \te\n"
181         "\t***************** *******************************************\tf\n"
182         "\n"
183         "\n"
184         "\t_____________________________________________________________\n"
185         "\tInverse\n"
186         "\t!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]\n"
187         "\t_____________________________________________________________\n"
188         "\n"
189         "\t***************          *******                          ***\t~a\n"
190         "\t***************          *******                          ***\tchset<>(~a)\n"
191         "\t               **********       **************************   \t~~a\n"
192         "\t********************                      *******************\t~b\n"
193         "\n"
194         "\n"
195         "\t_____________________________________________________________\n"
196         "\tUnion\n"
197         "\t!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]\n"
198         "\t_____________________________________________________________\n"
199         "\n"
200         "\t               **********       **************************   \ta\n"
201         "\t                    **********************                   \tb\n"
202         "\t********************                      *******************\td\n"
203         "\t                 *                                           \te\n"
204         "\t***************** *******************************************\tf\n"
205         "\t               *******************************************   \ta | b\n"
206         "\t               *******************************************   \ta | b_\n"
207         "\t               *******************************************   \tb_ | a\n"
208         "\t*************************************************************\ta | anychar_p\n"
209         "\t*************************************************************\tb | anychar_p\n"
210         "\t*************************       *****************************\ta | d\n"
211         "\t*************************       *****************************\ta | d_\n"
212         "\t*************************       *****************************\td_ | a\n"
213         "\t               **********       **************************   \ta | e_\n"
214         "\t                 *  **********************                   \te_ | b\n"
215         "\t*************************************************************\ta | f_\n"
216         "\t***************** *******************************************\tf_ | b\n"
217         "\n"
218         "\n"
219         "\t_____________________________________________________________\n"
220         "\tIntersection\n"
221         "\t!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]\n"
222         "\t_____________________________________________________________\n"
223         "\n"
224         "\t               **********       **************************   \ta\n"
225         "\t                    **********************                   \tb\n"
226         "\t********************                      *******************\td\n"
227         "\t                 *                                           \te\n"
228         "\t***************** *******************************************\tf\n"
229         "\t                    *****       **********                   \ta & b\n"
230         "\t                    *****       **********                   \ta & b_\n"
231         "\t                    *****       **********                   \tb_ & a\n"
232         "\t               *****                      ****************   \ta & d\n"
233         "\t               *****                      ****************   \ta & d_\n"
234         "\t               *****                      ****************   \td_ & a\n"
235         "\t                 *                                           \ta & e_\n"
236         "\t                                                             \te_ & b\n"
237         "\t               ** *******       **************************   \ta & f_\n"
238         "\t                    **********************                   \tf_ & b\n"
239         "\t               **********       **************************   \ta & anychar_p\n"
240         "\t                    **********************                   \tb & anychar_p\n"
241         "\n"
242         "\n"
243         "\t_____________________________________________________________\n"
244         "\tDifference\n"
245         "\t!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]\n"
246         "\t_____________________________________________________________\n"
247         "\n"
248         "\t               **********       **************************   \ta\n"
249         "\t                    **********************                   \tb\n"
250         "\t********************                      *******************\td\n"
251         "\t                 *                                           \te\n"
252         "\t***************** *******************************************\tf\n"
253         "\t               *****                      ****************   \ta - b\n"
254         "\t                         *******                             \tb - a\n"
255         "\t               *****                      ****************   \ta - b_\n"
256         "\t                         *******                             \tb_ - a\n"
257         "\t                    *****       **********                   \ta - d\n"
258         "\t***************                                           ***\td - a\n"
259         "\t                    *****       **********                   \ta - d_\n"
260         "\t***************                                           ***\td_ - a\n"
261         "\t               ** *******       **************************   \ta - e_\n"
262         "\t                 *                                           \te_ - b\n"
263         "\t                 *                                           \ta - f_\n"
264         "\t***************** **                      *******************\tf_ - b\n"
265         "\t                                                             \ta - anychar_p\n"
266         "\t***************          *******                          ***\tanychar_p - a\n"
267         "\t                                                             \tb - anychar_p\n"
268         "\t********************                      *******************\tanychar_p - b\n"
269         "\n"
270         "\n"
271         "\t_____________________________________________________________\n"
272         "\tXor\n"
273         "\t!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]\n"
274         "\t_____________________________________________________________\n"
275         "\n"
276         "\t               **********       **************************   \ta\n"
277         "\t                    **********************                   \tb\n"
278         "\t********************                      *******************\td\n"
279         "\t                 *                                           \te\n"
280         "\t***************** *******************************************\tf\n"
281         "\t               *****     *******          ****************   \ta ^ b\n"
282         "\t               *****     *******          ****************   \ta ^ b_\n"
283         "\t               *****     *******          ****************   \tb_ ^ a\n"
284         "\t***************     *****       **********                ***\ta ^ d\n"
285         "\t***************     *****       **********                ***\ta ^ d_\n"
286         "\t***************     *****       **********                ***\td_ ^ a\n"
287         "\t               ** *******       **************************   \ta ^ e_\n"
288         "\t                 *  **********************                   \te_ ^ b\n"
289         "\t***************  *       *******                          ***\ta ^ f_\n"
290         "\t***************** **                      *******************\tf_ ^ b\n"
291         "\t               **********       **************************   \ta ^ nothing_p\n"
292         "\t***************          *******                          ***\ta ^ anychar_p\n"
293         "\t                    **********************                   \tb ^ nothing_p\n"
294         "\t********************                      *******************\tb ^ anychar_p\n"
295     ;
296 
chset_tests()297     void chset_tests()
298     {
299         sstream_t tout, aout, bout;
300 
301         tout << expected_output;
302 
303         chset_tests(aout, "0-9A-Z", '5', 'J', '2');
304         chset_tests(bout, L"0-9A-Z", L'5', L'J', L'2');
305 
306 #define narrow_chset_works (getstring(aout) == getstring(tout))
307 #define wide_chset_works   (getstring(bout) == getstring(tout))
308 
309         if (!narrow_chset_works || !wide_chset_works)
310         {
311             std::cout << "EXPECTED:\n" <<
312                 getstring(tout);
313             std::cout << "GOT:\n" <<
314                 getstring(aout);
315             std::cout << "AND:\n" <<
316                 getstring(bout);
317         }
318 
319         BOOST_TEST(narrow_chset_works);
320         BOOST_TEST(wide_chset_works);
321     }
322 
323 } // namespace
324 
325 int
main(int argc,char * argv[])326 main(int argc, char *argv[])
327 {
328     chset_tests();
329     return boost::report_errors();
330 }
331 
332