| 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 | |
| 21 | using boost::unit_test::test_suite; |
| 22 | namespace io = boost::iostreams; |
| 23 | |
| 24 | const 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 | |
| 44 | const 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 | |
| 64 | const std::string = |
| 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 | |
| 70 | const std::string = |
| 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 | |
| 76 | struct 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 | |
| 83 | struct 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 | |
| 92 | struct 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 | |
| 104 | struct : io::finite_state_machine<uncommenting_fsm> { |
| 105 | BOOST_IOSTREAMS_FSM(uncommenting_fsm) // Define skip and push. |
| 106 | typedef uncommenting_fsm ; |
| 107 | |
| 108 | static const int = initial_state; |
| 109 | static const int = no_comment + 1; |
| 110 | static const int = pre_comment + 1; |
| 111 | static const int = comment + 1; |
| 112 | |
| 113 | void (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 | > ; |
| 127 | }; |
| 128 | |
| 129 | void 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> ; |
| 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 | |
| 175 | test_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 | |