| 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 | // | 
|---|
| 131 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 132 | #include <boost/spirit/core.hpp> | 
|---|
| 133 |  | 
|---|
| 134 | using namespace std; | 
|---|
| 135 | using namespace boost; | 
|---|
| 136 | using namespace spirit; | 
|---|
| 137 |  | 
|---|
| 138 | void bug_005() | 
|---|
| 139 | { | 
|---|
| 140 |     BOOST_TEST( | 
|---|
| 141 |         parse("   aaaaaaaaa     ", *ch_p('a'), space_p).full | 
|---|
| 142 |     ); | 
|---|
| 143 |  | 
|---|
| 144 |     BOOST_TEST( | 
|---|
| 145 |         parse("   aaaaaaaaa     ", lexeme_d[*ch_p('a')], space_p).full | 
|---|
| 146 |     ); | 
|---|
| 147 |  | 
|---|
| 148 | #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206)) | 
|---|
| 149 |     // not sure why Code Warrior 9.5 does not recognize ch_p(' ') as the  | 
|---|
| 150 |     // same as space_p (see above) when the inputs are spaces. The | 
|---|
| 151 |     // tests below are redundant anyway. | 
|---|
| 152 | #else | 
|---|
| 153 |  | 
|---|
| 154 |     BOOST_TEST( | 
|---|
| 155 |         parse("   aaaaaaaaa     ", *ch_p('a'), ch_p(' ')).full | 
|---|
| 156 |     ); | 
|---|
| 157 |  | 
|---|
| 158 |     BOOST_TEST( | 
|---|
| 159 |         parse("   aaaaaaaaa     ", lexeme_d[*ch_p('a')], ch_p(' ')).full | 
|---|
| 160 |     ); | 
|---|
| 161 |  | 
|---|
| 162 | #endif | 
|---|
| 163 | } | 
|---|
| 164 |  | 
|---|
| 165 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 166 | // | 
|---|
| 167 | //  bug_006 | 
|---|
| 168 | // | 
|---|
| 169 | //  confix bug | 
|---|
| 170 | // | 
|---|
| 171 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 172 | #include <boost/limits.hpp> | 
|---|
| 173 | #include <boost/spirit/utility/confix.hpp> | 
|---|
| 174 |  | 
|---|
| 175 | void bug_006() | 
|---|
| 176 | { | 
|---|
| 177 |     BOOST_TEST(parse("#some comment", comment_p('#')).full); | 
|---|
| 178 | } | 
|---|
| 179 |  | 
|---|
| 180 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 181 | // | 
|---|
| 182 | //  bug_007 | 
|---|
| 183 | // | 
|---|
| 184 | //  handling of trailing whitespace bug (ast_parse/pt_parse related) | 
|---|
| 185 | // | 
|---|
| 186 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 187 | #include <boost/spirit/tree/ast.hpp> | 
|---|
| 188 | #include <boost/spirit/tree/parse_tree.hpp> | 
|---|
| 189 |  | 
|---|
| 190 | void bug_007() | 
|---|
| 191 | { | 
|---|
| 192 |     BOOST_TEST(parse("test ", str_p("test"), space_p).full); | 
|---|
| 193 |     BOOST_TEST(pt_parse("test ", str_p("test"), space_p).full); | 
|---|
| 194 |     BOOST_TEST(ast_parse("test ", str_p("test"), space_p).full); | 
|---|
| 195 | } | 
|---|
| 196 |  | 
|---|
| 197 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 198 | // | 
|---|
| 199 | //  sf_bug_718903 | 
|---|
| 200 | // | 
|---|
| 201 | //  see https://sourceforge.net/tracker/index.php | 
|---|
| 202 | //  ?func=detail&aid=718903&group_id=28447&atid=393386 | 
|---|
| 203 | // | 
|---|
| 204 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 205 | #include <boost/cstdlib.hpp> | 
|---|
| 206 | #include <boost/spirit/utility/chset.hpp> | 
|---|
| 207 |  | 
|---|
| 208 | void sf_bug_718903() | 
|---|
| 209 | { | 
|---|
| 210 |     empty_match_parser<chset<char> > | 
|---|
| 211 |         e(epsilon_p(chset_p("abc"))); | 
|---|
| 212 | } | 
|---|
| 213 |  | 
|---|
| 214 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 215 | // | 
|---|
| 216 | //  sf_bug_719322 | 
|---|
| 217 | //  range_run bug | 
|---|
| 218 | // | 
|---|
| 219 | //  see http://sourceforge.net/tracker/index.php | 
|---|
| 220 | //  ?func=detail&aid=719322&group_id=28447&atid=393386 | 
|---|
| 221 | // | 
|---|
| 222 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 223 | #include <boost/spirit/utility/impl/chset/basic_chset.hpp> | 
|---|
| 224 |  | 
|---|
| 225 | void sf_bug_719322() | 
|---|
| 226 | { | 
|---|
| 227 |     basic_chset<int> s; | 
|---|
| 228 |     s.set(3, 3); | 
|---|
| 229 |     s.set(1, 5); | 
|---|
| 230 |     BOOST_TEST(s.test(5)); | 
|---|
| 231 | } | 
|---|
| 232 |  | 
|---|
| 233 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 234 | // | 
|---|
| 235 | //  sf_bug_742038 | 
|---|
| 236 | // | 
|---|
| 237 | //  see http://sf.net/tracker/ | 
|---|
| 238 | //  ?func=detail&atid=393386&aid=742038&group_id=28447 | 
|---|
| 239 | // | 
|---|
| 240 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 241 | #include <boost/spirit/iterator/position_iterator.hpp> | 
|---|
| 242 | #include <boost/spirit/iterator/file_iterator.hpp> | 
|---|
| 243 | #include <string> | 
|---|
| 244 | #include <fstream> | 
|---|
| 245 | #include <iostream> | 
|---|
| 246 | #include <assert.h> | 
|---|
| 247 | #include <stdio.h> | 
|---|
| 248 |  | 
|---|
| 249 | template <typename IterT> | 
|---|
| 250 | void test_assign(IterT b, IterT e) | 
|---|
| 251 | { | 
|---|
| 252 |     typedef scanner<IterT> scanner_t; | 
|---|
| 253 |  | 
|---|
| 254 | #if     (defined(__GNUC__) && defined(__MINGW32__)) \ | 
|---|
| 255 |     ||  (defined(__GNUC__) && (__GNUC_MINOR__ < 20)) | 
|---|
| 256 |  | 
|---|
| 257 | //  There's a bug in g++3.x on MinGW that makes basic_string assert | 
|---|
| 258 | //  when assigning from IterT [f, l) where IterT is a position_iterator. | 
|---|
| 259 | //  This issue is discussed here: | 
|---|
| 260 | // | 
|---|
| 261 | //  http://gcc.gnu.org/ml/libstdc++/2002-03/msg00196.html | 
|---|
| 262 | // | 
|---|
| 263 | //  Aparently, this bug is only present on MinGW. I'm clueless as | 
|---|
| 264 | //  to why this is so. Regressions on linux seem to be OK! :( | 
|---|
| 265 | // | 
|---|
| 266 | //  With, g++3.1, assigning to basic_string from IterT [f, l) is a | 
|---|
| 267 | //  compile error (a g++3.1 bug). | 
|---|
| 268 | // | 
|---|
| 269 | //  In both cases above, we use a vector instead of a string. | 
|---|
| 270 |  | 
|---|
| 271 |     typedef std::vector<char> store; | 
|---|
| 272 | #else | 
|---|
| 273 |     typedef std::string store; | 
|---|
| 274 | #endif | 
|---|
| 275 |  | 
|---|
| 276 |     store dst; | 
|---|
| 277 |     rule<scanner_t> r = (*alpha_p)[assign_a(dst)]; | 
|---|
| 278 |  | 
|---|
| 279 |     parse(b, e, r); | 
|---|
| 280 |  | 
|---|
| 281 |     store::iterator d = dst.begin(); | 
|---|
| 282 |  | 
|---|
| 283 |     while (b != e) | 
|---|
| 284 |     { | 
|---|
| 285 |         if (*d != *b) | 
|---|
| 286 |         BOOST_TEST(*d == *b); | 
|---|
| 287 |         ++b; | 
|---|
| 288 |         ++d; | 
|---|
| 289 |     } | 
|---|
| 290 | } | 
|---|
| 291 |  | 
|---|
| 292 | void sf_bug_742038() | 
|---|
| 293 | { | 
|---|
| 294 |     std::string src = "abcdef"; | 
|---|
| 295 |     const char* tmpfilename = "sf_bug_742038.tmp"; | 
|---|
| 296 |  | 
|---|
| 297 |     test_assign(src.begin(), src.end()); | 
|---|
| 298 |  | 
|---|
| 299 |     position_iterator<std::string::iterator> b(src.begin(), src.end(), ""); | 
|---|
| 300 |     position_iterator<std::string::iterator> e; | 
|---|
| 301 |     test_assign(b, e); | 
|---|
| 302 |  | 
|---|
| 303 |     std::fstream f(tmpfilename, std::ios::out); | 
|---|
| 304 |     f << src; | 
|---|
| 305 |     f.close(); | 
|---|
| 306 |  | 
|---|
| 307 |     file_iterator<> b1(tmpfilename); | 
|---|
| 308 |     file_iterator<> e1(b1.make_end()); | 
|---|
| 309 |     test_assign(b1, e1); | 
|---|
| 310 |  | 
|---|
| 311 |     ::remove(tmpfilename); | 
|---|
| 312 | } | 
|---|
| 313 |  | 
|---|
| 314 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 315 | // | 
|---|
| 316 | //  bug_009 | 
|---|
| 317 | // | 
|---|
| 318 | //  limit_d bug | 
|---|
| 319 | //  http://article.gmane.org/gmane.comp.parsers.spirit.devel/1891/ | 
|---|
| 320 | // | 
|---|
| 321 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 322 | void | 
|---|
| 323 | bug_009() | 
|---|
| 324 | { | 
|---|
| 325 |     parse( | 
|---|
| 326 |         "test" | 
|---|
| 327 |       , limit_d(1U, 10U)[uint_p] | str_p("test")); | 
|---|
| 328 | } | 
|---|
| 329 |  | 
|---|
| 330 | int | 
|---|
| 331 | main() | 
|---|
| 332 | { | 
|---|
| 333 |     bug_001(); | 
|---|
| 334 |     bug_002(); | 
|---|
| 335 |     bug_003(); | 
|---|
| 336 |     bug_004(); | 
|---|
| 337 |     bug_005(); | 
|---|
| 338 |     bug_006(); | 
|---|
| 339 |     bug_007(); | 
|---|
| 340 |     bug_009(); | 
|---|
| 341 |  | 
|---|
| 342 |     sf_bug_718903(); | 
|---|
| 343 |     sf_bug_719322(); | 
|---|
| 344 |     sf_bug_742038(); | 
|---|
| 345 |  | 
|---|
| 346 |     return boost::report_errors(); | 
|---|
| 347 | } | 
|---|