| 1 | /*============================================================================= |
|---|
| 2 | Copyright (c) 2003 Giovanni Bajo |
|---|
| 3 | Copyright (c) 2003 Joel de Guzman |
|---|
| 4 | Copyright (c) 2003 Vaclav Vesely |
|---|
| 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 <boost/detail/lightweight_test.hpp> |
|---|
| 12 | #include <boost/spirit/core.hpp> |
|---|
| 13 | #include <boost/spirit/actor/assign_actor.hpp> |
|---|
| 14 | |
|---|
| 15 | using namespace boost; |
|---|
| 16 | using namespace boost::spirit; |
|---|
| 17 | using namespace std; |
|---|
| 18 | |
|---|
| 19 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 20 | // |
|---|
| 21 | // bug_001 |
|---|
| 22 | // |
|---|
| 23 | // access_node_d[] and access_match_d[] iterator bug |
|---|
| 24 | // http://sf.net/mailarchive/forum.php?thread_id=1963157&forum_id=1595 |
|---|
| 25 | // http://sf.net/mailarchive/forum.php?thread_id=1966224&forum_id=1595 |
|---|
| 26 | // |
|---|
| 27 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 28 | #include <boost/spirit/tree/ast.hpp> |
|---|
| 29 | |
|---|
| 30 | struct my_action |
|---|
| 31 | { |
|---|
| 32 | template <typename TreeT, typename IterT> |
|---|
| 33 | void operator()(TreeT& /*t*/, IterT begin, IterT end) const |
|---|
| 34 | { |
|---|
| 35 | BOOST_TEST(*begin == '1'); |
|---|
| 36 | BOOST_TEST(*end == '2'); |
|---|
| 37 | } |
|---|
| 38 | }; |
|---|
| 39 | |
|---|
| 40 | void bug_001() |
|---|
| 41 | { |
|---|
| 42 | const char* text = "123"; |
|---|
| 43 | |
|---|
| 44 | ast_parse(text, text+3, access_node_d[chlit<>('1')][my_action()]); |
|---|
| 45 | ast_parse(text, text+3, access_match_d[chlit<>('1')][my_action()]); |
|---|
| 46 | } |
|---|
| 47 | |
|---|
| 48 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 49 | // |
|---|
| 50 | // bug_001 |
|---|
| 51 | // |
|---|
| 52 | // mismatch closure return type bug |
|---|
| 53 | // http://article.gmane.org/gmane.comp.parsers.spirit.general/3678 |
|---|
| 54 | // |
|---|
| 55 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 56 | #include <boost/spirit/attribute.hpp> |
|---|
| 57 | #include <string> |
|---|
| 58 | |
|---|
| 59 | typedef std::string member_type; |
|---|
| 60 | |
|---|
| 61 | struct my_closure: closure<my_closure, member_type> |
|---|
| 62 | { |
|---|
| 63 | member1 val; |
|---|
| 64 | }; |
|---|
| 65 | |
|---|
| 66 | void bug_002() |
|---|
| 67 | { |
|---|
| 68 | rule<scanner<char const*>, my_closure::context_t> my_rule = real_p; |
|---|
| 69 | BOOST_TEST(parse("1", my_rule).full); |
|---|
| 70 | } |
|---|
| 71 | |
|---|
| 72 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 73 | // |
|---|
| 74 | // bug_003 |
|---|
| 75 | // |
|---|
| 76 | // impl::detach_clear bug |
|---|
| 77 | // http://sourceforge.net/mailarchive/forum.php?thread_id=2008510&forum_id=25901 |
|---|
| 78 | // |
|---|
| 79 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 80 | #include <boost/spirit/utility/chset.hpp> |
|---|
| 81 | |
|---|
| 82 | void bug_003() |
|---|
| 83 | { |
|---|
| 84 | chset<> set; |
|---|
| 85 | set = 'a'; |
|---|
| 86 | } |
|---|
| 87 | |
|---|
| 88 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 89 | // |
|---|
| 90 | // bug_004 |
|---|
| 91 | // |
|---|
| 92 | // chset<>::operator~(range<>) bug |
|---|
| 93 | // operator&(chset<>, range<>) bug |
|---|
| 94 | // operator&(range<>, chset<>) bug |
|---|
| 95 | // |
|---|
| 96 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 97 | #include <boost/limits.hpp> |
|---|
| 98 | #include <boost/spirit/utility/chset.hpp> |
|---|
| 99 | |
|---|
| 100 | void bug_004() |
|---|
| 101 | { |
|---|
| 102 | const char min = (numeric_limits<char>::min)(); |
|---|
| 103 | const char max = (numeric_limits<char>::max)(); |
|---|
| 104 | |
|---|
| 105 | { |
|---|
| 106 | chset<> set(~range<>(min, max)); |
|---|
| 107 | BOOST_TEST(set.test(min) == false); |
|---|
| 108 | BOOST_TEST(set.test(min) == false); |
|---|
| 109 | } |
|---|
| 110 | |
|---|
| 111 | { |
|---|
| 112 | chset<> set(chset<>(anychar_p) & range<>(min, max)); |
|---|
| 113 | BOOST_TEST(set.test(min) == true); |
|---|
| 114 | BOOST_TEST(set.test(min) == true); |
|---|
| 115 | } |
|---|
| 116 | |
|---|
| 117 | { |
|---|
| 118 | chset<> set(range<>(min, max) & chset<>(anychar_p)); |
|---|
| 119 | BOOST_TEST(set.test(min) == true); |
|---|
| 120 | BOOST_TEST(set.test(min) == true); |
|---|
| 121 | } |
|---|
| 122 | } |
|---|
| 123 | |
|---|
| 124 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 125 | // |
|---|
| 126 | // bug_005 |
|---|
| 127 | // |
|---|
| 128 | // Most trailing space bug |
|---|
| 129 | // http://article.gmane.org/gmane.comp.parsers.spirit.general/4029 |
|---|
| 130 | // JDG: Oct 18, 2005. We shall revert to the previous behavior where |
|---|
| 131 | // Post skips are not allowed. The reason is that |
|---|
| 132 | // there is a valid use case where input is obtained |
|---|
| 133 | // from cin and multi_pass which results in an infinite |
|---|
| 134 | // loop while the post skipper waits for a whitespace. |
|---|
| 135 | // For examples like below, the grammar must explicitly |
|---|
| 136 | // include the post whitespace. One possible way is to |
|---|
| 137 | // place an end_p at the end of the grammar. The end_p |
|---|
| 138 | // will trigger the post-skip. |
|---|
| 139 | // |
|---|
| 140 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 141 | #include <boost/spirit/core.hpp> |
|---|
| 142 | |
|---|
| 143 | using namespace std; |
|---|
| 144 | using namespace boost; |
|---|
| 145 | using namespace spirit; |
|---|
| 146 | |
|---|
| 147 | void bug_005() |
|---|
| 148 | { |
|---|
| 149 | BOOST_TEST( |
|---|
| 150 | parse(" aaaaaaaaa ", *ch_p('a') >> end_p, space_p).full |
|---|
| 151 | ); |
|---|
| 152 | |
|---|
| 153 | BOOST_TEST( |
|---|
| 154 | parse(" aaaaaaaaa ", lexeme_d[*ch_p('a')] >> end_p, space_p).full |
|---|
| 155 | ); |
|---|
| 156 | |
|---|
| 157 | #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206)) |
|---|
| 158 | // not sure why Code Warrior 9.5 does not recognize ch_p(' ') as the |
|---|
| 159 | // same as space_p (see above) when the inputs are spaces. The |
|---|
| 160 | // tests below are redundant anyway. |
|---|
| 161 | #else |
|---|
| 162 | |
|---|
| 163 | BOOST_TEST( |
|---|
| 164 | parse(" aaaaaaaaa ", *ch_p('a') >> end_p, ch_p(' ')).full |
|---|
| 165 | ); |
|---|
| 166 | |
|---|
| 167 | BOOST_TEST( |
|---|
| 168 | parse(" aaaaaaaaa ", lexeme_d[*ch_p('a')] >> end_p, ch_p(' ')).full |
|---|
| 169 | ); |
|---|
| 170 | |
|---|
| 171 | #endif |
|---|
| 172 | } |
|---|
| 173 | |
|---|
| 174 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 175 | // |
|---|
| 176 | // bug_006 |
|---|
| 177 | // |
|---|
| 178 | // confix bug |
|---|
| 179 | // |
|---|
| 180 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 181 | #include <boost/limits.hpp> |
|---|
| 182 | #include <boost/spirit/utility/confix.hpp> |
|---|
| 183 | |
|---|
| 184 | void bug_006() |
|---|
| 185 | { |
|---|
| 186 | BOOST_TEST(parse("#some comment", comment_p('#')).full); |
|---|
| 187 | } |
|---|
| 188 | |
|---|
| 189 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 190 | // |
|---|
| 191 | // bug_007 |
|---|
| 192 | // |
|---|
| 193 | // handling of trailing whitespace bug (ast_parse/pt_parse related) |
|---|
| 194 | // JDG: Oct 18, 2005. We shall revert to the previous behavior where |
|---|
| 195 | // Post skips are not allowed. The reason is that |
|---|
| 196 | // there is a valid use case where input is obtained |
|---|
| 197 | // from cin and multi_pass which results in an infinite |
|---|
| 198 | // loop while the post skipper waits for a whitespace. |
|---|
| 199 | // For examples like below, the grammar must explicitly |
|---|
| 200 | // include the post whitespace. One possible way is to |
|---|
| 201 | // place an end_p at the end of the grammar. The end_p |
|---|
| 202 | // will trigger the post-skip. |
|---|
| 203 | // |
|---|
| 204 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 205 | #include <boost/spirit/tree/ast.hpp> |
|---|
| 206 | #include <boost/spirit/tree/parse_tree.hpp> |
|---|
| 207 | |
|---|
| 208 | void bug_007() |
|---|
| 209 | { |
|---|
| 210 | BOOST_TEST(parse("test ", str_p("test") >> end_p, space_p).full); |
|---|
| 211 | BOOST_TEST(pt_parse("test ", str_p("test") >> end_p, space_p).full); |
|---|
| 212 | BOOST_TEST(ast_parse("test ", str_p("test") >> end_p, space_p).full); |
|---|
| 213 | } |
|---|
| 214 | |
|---|
| 215 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 216 | // |
|---|
| 217 | // sf_bug_718903 |
|---|
| 218 | // |
|---|
| 219 | // see https://sourceforge.net/tracker/index.php |
|---|
| 220 | // ?func=detail&aid=718903&group_id=28447&atid=393386 |
|---|
| 221 | // |
|---|
| 222 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 223 | #include <boost/cstdlib.hpp> |
|---|
| 224 | #include <boost/spirit/utility/chset.hpp> |
|---|
| 225 | |
|---|
| 226 | void sf_bug_718903() |
|---|
| 227 | { |
|---|
| 228 | empty_match_parser<chset<char> > |
|---|
| 229 | e(epsilon_p(chset_p("abc"))); |
|---|
| 230 | } |
|---|
| 231 | |
|---|
| 232 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 233 | // |
|---|
| 234 | // sf_bug_719322 |
|---|
| 235 | // range_run bug |
|---|
| 236 | // |
|---|
| 237 | // see http://sourceforge.net/tracker/index.php |
|---|
| 238 | // ?func=detail&aid=719322&group_id=28447&atid=393386 |
|---|
| 239 | // |
|---|
| 240 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 241 | #include <boost/spirit/utility/impl/chset/basic_chset.hpp> |
|---|
| 242 | |
|---|
| 243 | void sf_bug_719322() |
|---|
| 244 | { |
|---|
| 245 | basic_chset<int> s; |
|---|
| 246 | s.set(3, 3); |
|---|
| 247 | s.set(1, 5); |
|---|
| 248 | BOOST_TEST(s.test(5)); |
|---|
| 249 | } |
|---|
| 250 | |
|---|
| 251 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 252 | // |
|---|
| 253 | // sf_bug_742038 |
|---|
| 254 | // |
|---|
| 255 | // see http://sf.net/tracker/ |
|---|
| 256 | // ?func=detail&atid=393386&aid=742038&group_id=28447 |
|---|
| 257 | // |
|---|
| 258 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 259 | #include <boost/spirit/iterator/position_iterator.hpp> |
|---|
| 260 | #include <boost/spirit/iterator/file_iterator.hpp> |
|---|
| 261 | #include <string> |
|---|
| 262 | #include <fstream> |
|---|
| 263 | #include <iostream> |
|---|
| 264 | #include <boost/detail/lightweight_test.hpp> |
|---|
| 265 | #include <stdio.h> |
|---|
| 266 | |
|---|
| 267 | template <typename IterT> |
|---|
| 268 | void test_assign(IterT b, IterT e) |
|---|
| 269 | { |
|---|
| 270 | typedef scanner<IterT> scanner_t; |
|---|
| 271 | |
|---|
| 272 | #if (defined(__GNUC__) && defined(__MINGW32__)) \ |
|---|
| 273 | || (defined(__GNUC__) && (__GNUC_MINOR__ < 20)) |
|---|
| 274 | |
|---|
| 275 | // There's a bug in g++3.x on MinGW that makes basic_string assert |
|---|
| 276 | // when assigning from IterT [f, l) where IterT is a position_iterator. |
|---|
| 277 | // This issue is discussed here: |
|---|
| 278 | // |
|---|
| 279 | // http://gcc.gnu.org/ml/libstdc++/2002-03/msg00196.html |
|---|
| 280 | // |
|---|
| 281 | // Aparently, this bug is only present on MinGW. I'm clueless as |
|---|
| 282 | // to why this is so. Regressions on linux seem to be OK! :( |
|---|
| 283 | // |
|---|
| 284 | // With, g++3.1, assigning to basic_string from IterT [f, l) is a |
|---|
| 285 | // compile error (a g++3.1 bug). |
|---|
| 286 | // |
|---|
| 287 | // In both cases above, we use a vector instead of a string. |
|---|
| 288 | |
|---|
| 289 | typedef std::vector<char> store; |
|---|
| 290 | #else |
|---|
| 291 | typedef std::string store; |
|---|
| 292 | #endif |
|---|
| 293 | |
|---|
| 294 | store dst; |
|---|
| 295 | rule<scanner_t> r = (*alpha_p)[assign_a(dst)]; |
|---|
| 296 | |
|---|
| 297 | parse(b, e, r); |
|---|
| 298 | |
|---|
| 299 | store::iterator d = dst.begin(); |
|---|
| 300 | |
|---|
| 301 | while (b != e) |
|---|
| 302 | { |
|---|
| 303 | if (*d != *b) |
|---|
| 304 | BOOST_TEST(*d == *b); |
|---|
| 305 | ++b; |
|---|
| 306 | ++d; |
|---|
| 307 | } |
|---|
| 308 | } |
|---|
| 309 | |
|---|
| 310 | void sf_bug_742038() |
|---|
| 311 | { |
|---|
| 312 | std::string src = "abcdef"; |
|---|
| 313 | const char* tmpfilename = "sf_bug_742038.tmp"; |
|---|
| 314 | |
|---|
| 315 | test_assign(src.begin(), src.end()); |
|---|
| 316 | |
|---|
| 317 | position_iterator<std::string::iterator> b(src.begin(), src.end(), ""); |
|---|
| 318 | position_iterator<std::string::iterator> e; |
|---|
| 319 | test_assign(b, e); |
|---|
| 320 | |
|---|
| 321 | std::fstream f(tmpfilename, std::ios::out); |
|---|
| 322 | f << src; |
|---|
| 323 | f.close(); |
|---|
| 324 | |
|---|
| 325 | file_iterator<> b1(tmpfilename); |
|---|
| 326 | file_iterator<> e1(b1.make_end()); |
|---|
| 327 | test_assign(b1, e1); |
|---|
| 328 | |
|---|
| 329 | ::remove(tmpfilename); |
|---|
| 330 | } |
|---|
| 331 | |
|---|
| 332 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 333 | // |
|---|
| 334 | // bug_009 |
|---|
| 335 | // |
|---|
| 336 | // limit_d bug |
|---|
| 337 | // http://article.gmane.org/gmane.comp.parsers.spirit.devel/1891/ |
|---|
| 338 | // |
|---|
| 339 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 340 | void |
|---|
| 341 | bug_009() |
|---|
| 342 | { |
|---|
| 343 | parse( |
|---|
| 344 | "test" |
|---|
| 345 | , limit_d(1U, 10U)[uint_p] | str_p("test")); |
|---|
| 346 | } |
|---|
| 347 | |
|---|
| 348 | int |
|---|
| 349 | main() |
|---|
| 350 | { |
|---|
| 351 | bug_001(); |
|---|
| 352 | bug_002(); |
|---|
| 353 | bug_003(); |
|---|
| 354 | bug_004(); |
|---|
| 355 | bug_005(); |
|---|
| 356 | bug_006(); |
|---|
| 357 | bug_007(); |
|---|
| 358 | bug_009(); |
|---|
| 359 | |
|---|
| 360 | sf_bug_718903(); |
|---|
| 361 | sf_bug_719322(); |
|---|
| 362 | sf_bug_742038(); |
|---|
| 363 | |
|---|
| 364 | return boost::report_errors(); |
|---|
| 365 | } |
|---|