1// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
2// (C) Copyright 2005-2007 Jonathan Turkanis
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
5
6// See http://www.boost.org/libs/iostreams for documentation.
7
8#include <boost/config.hpp>
9#ifdef BOOST_NO_STD_LOCALE
10# error std::locale not supported on this platform
11#else
12
13# include <map>
14# include <boost/iostreams/detail/ios.hpp> // failure.
15# include <boost/iostreams/filter/test.hpp>
16# include <boost/mpl/vector.hpp>
17# include <boost/test/test_tools.hpp>
18# include <boost/test/unit_test.hpp>
19# include "../example/finite_state_filter.hpp"
20
21using boost::unit_test::test_suite;
22namespace io = boost::iostreams;
23
24const std::string posix = // 'unix' is sometimes a macro.
25 "When I was one-and-twenty\n"
26 "I heard a wise man say,\n"
27 "'Give crowns and pounds and guineas\n"
28 "But not your heart away;\n"
29 "\n"
30 "Give pearls away and rubies\n"
31 "But keep your fancy free.'\n"
32 "But I was one-and-twenty,\n"
33 "No use to talk to me.\n"
34 "\n"
35 "When I was one-and-twenty\n"
36 "I heard him say again,\n"
37 "'The heart out of the bosom\n"
38 "Was never given in vain;\n"
39 "'Tis paid with sighs a plenty\n"
40 "And sold for endless rue.'\n"
41 "And I am two-and-twenty,\n"
42 "And oh, 'tis true, 'tis true.";
43
44const std::string dos =
45 "When I was one-and-twenty\r\n"
46 "I heard a wise man say,\r\n"
47 "'Give crowns and pounds and guineas\r\n"
48 "But not your heart away;\r\n"
49 "\r\n"
50 "Give pearls away and rubies\r\n"
51 "But keep your fancy free.'\r\n"
52 "But I was one-and-twenty,\r\n"
53 "No use to talk to me.\r\n"
54 "\r\n"
55 "When I was one-and-twenty\r\n"
56 "I heard him say again,\r\n"
57 "'The heart out of the bosom\r\n"
58 "Was never given in vain;\r\n"
59 "'Tis paid with sighs a plenty\r\n"
60 "And sold for endless rue.'\r\n"
61 "And I am two-and-twenty,\r\n"
62 "And oh, 'tis true, 'tis true.";
63
64const std::string comments =
65 "When I was /*one-and-twenty\n"
66 "I he*/ard a wise/ man say,\n"
67 "'Give cr//*owns *and po**/unds and guineas\n"
68 "But n*/ot yo*/ur he/*a*/rt /**/away;\n";
69
70const std::string no_comments =
71 "When I was "
72 "ard a wise/ man say,\n"
73 "'Give cr/unds and guineas\n"
74 "But n*/ot yo*/ur hert away;\n";
75
76struct identity_fsm
77 : io::finite_state_machine<identity_fsm, char>
78{
79 void on_any(char c) { push(c); }
80 typedef boost::mpl::vector0<> transition_table;
81};
82
83struct dos2unix_fsm : io::finite_state_machine<dos2unix_fsm> {
84 BOOST_IOSTREAMS_FSM(dos2unix_fsm) // Define skip and push.
85 typedef dos2unix_fsm self;
86 typedef boost::mpl::vector<
87 row<initial_state, is<'\r'>, initial_state, &self::skip>,
88 row<initial_state, is_any, initial_state, &self::push>
89 > transition_table;
90};
91
92struct unix2dos_fsm : io::finite_state_machine<unix2dos_fsm> {
93 BOOST_IOSTREAMS_FSM(unix2dos_fsm) // Define skip and push.
94 typedef unix2dos_fsm self;
95
96 void on_lf(char) { push(c: '\r'); push(c: '\n'); }
97
98 typedef boost::mpl::vector<
99 row<initial_state, is<'\n'>, initial_state, &self::on_lf>,
100 row<initial_state, is_any, initial_state, &self::push>
101 > transition_table;
102};
103
104struct uncommenting_fsm : io::finite_state_machine<uncommenting_fsm> {
105 BOOST_IOSTREAMS_FSM(uncommenting_fsm) // Define skip and push.
106 typedef uncommenting_fsm self;
107
108 static const int no_comment = initial_state;
109 static const int pre_comment = no_comment + 1;
110 static const int comment = pre_comment + 1;
111 static const int post_comment = comment + 1;
112
113 void push_slash(char c) { push(c: '/'); push(c); }
114
115 typedef boost::mpl::vector<
116 row<no_comment, is<'/'>, pre_comment, &self::skip>,
117 row<no_comment, is_any, no_comment, &self::push>,
118 row<pre_comment, is<'*'>, comment, &self::skip>,
119 row<pre_comment, is<'/'>, pre_comment, &self::push>,
120 row<pre_comment, is_any, no_comment, &self::push_slash>,
121 row<comment, is<'*'>, post_comment, &self::skip>,
122 row<comment, is_any, comment, &self::skip>,
123 row<post_comment, is<'/'>, no_comment, &self::skip>,
124 row<post_comment, is<'*'>, post_comment, &self::skip>,
125 row<post_comment, is_any, comment, &self::skip>
126 > transition_table;
127};
128
129void finite_state_filter_test()
130{
131 using namespace std;
132
133 typedef io::finite_state_filter<identity_fsm> identity_filter;
134 typedef io::finite_state_filter<dos2unix_fsm> dos2unix_filter;
135 typedef io::finite_state_filter<unix2dos_fsm> unix2dos_filter;
136 typedef io::finite_state_filter<uncommenting_fsm> uncommenting_filter;
137
138 // Test identity_filter.
139
140 BOOST_CHECK(
141 io::test_input_filter(identity_filter(), dos, dos)
142 );
143 BOOST_CHECK(
144 io::test_output_filter(identity_filter(), dos, dos)
145 );
146
147 // Test dos2unix_filter.
148
149 BOOST_CHECK(
150 io::test_input_filter(dos2unix_filter(), dos, posix)
151 );
152 BOOST_CHECK(
153 io::test_output_filter(dos2unix_filter(), dos, posix)
154 );
155
156 // Test unix2dos_filter.
157
158 BOOST_CHECK(
159 io::test_input_filter(unix2dos_filter(), posix, dos)
160 );
161 BOOST_CHECK(
162 io::test_output_filter(unix2dos_filter(), posix, dos)
163 );
164
165 // Test uncommenting_filter.
166
167 BOOST_CHECK(
168 io::test_input_filter(uncommenting_filter(), comments, no_comments)
169 );
170 BOOST_CHECK(
171 io::test_output_filter(uncommenting_filter(), comments, no_comments)
172 );
173}
174
175test_suite* init_unit_test_suite(int, char* [])
176{
177 test_suite* test = BOOST_TEST_SUITE("example test");
178 test->add(BOOST_TEST_CASE(&finite_state_filter_test));
179 return test;
180}
181
182#endif // #ifdef BOOST_NO_STD_LOCALE //---------------------------------------//
183

source code of boost/libs/iostreams/test/finite_state_filter_test.cpp