summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/spirit/classic/test/bug_fixes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/spirit/classic/test/bug_fixes.cpp')
-rw-r--r--src/boost/libs/spirit/classic/test/bug_fixes.cpp365
1 files changed, 365 insertions, 0 deletions
diff --git a/src/boost/libs/spirit/classic/test/bug_fixes.cpp b/src/boost/libs/spirit/classic/test/bug_fixes.cpp
new file mode 100644
index 00000000..69490b8b
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/bug_fixes.cpp
@@ -0,0 +1,365 @@
+/*=============================================================================
+ Copyright (c) 2003 Giovanni Bajo
+ Copyright (c) 2003 Joel de Guzman
+ Copyright (c) 2003 Vaclav Vesely
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to the Boost Software
+ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_assign_actor.hpp>
+
+using namespace boost;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// bug_001
+//
+// access_node_d[] and access_match_d[] iterator bug
+// http://sf.net/mailarchive/forum.php?thread_id=1963157&forum_id=1595
+// http://sf.net/mailarchive/forum.php?thread_id=1966224&forum_id=1595
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_ast.hpp>
+
+struct my_action
+{
+ template <typename TreeT, typename IterT>
+ void operator()(TreeT& /*t*/, IterT begin, IterT end) const
+ {
+ BOOST_TEST(*begin == '1');
+ BOOST_TEST(*end == '2');
+ }
+};
+
+void bug_001()
+{
+ const char* text = "123";
+
+ ast_parse(text, text+3, access_node_d[chlit<>('1')][my_action()]);
+ ast_parse(text, text+3, access_match_d[chlit<>('1')][my_action()]);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// bug_001
+//
+// mismatch closure return type bug
+// http://article.gmane.org/gmane.comp.parsers.spirit.general/3678
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_attribute.hpp>
+#include <string>
+
+typedef std::string member_type;
+
+struct my_closure: closure<my_closure, member_type>
+{
+ member1 val;
+};
+
+void bug_002()
+{
+ rule<scanner<char const*>, my_closure::context_t> my_rule = real_p;
+ BOOST_TEST(parse("1", my_rule).full);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// bug_003
+//
+// impl::detach_clear bug
+// http://sourceforge.net/mailarchive/forum.php?thread_id=2008510&forum_id=25901
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_chset.hpp>
+
+void bug_003()
+{
+ chset<> set;
+ set = 'a';
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// bug_004
+//
+// chset<>::operator~(range<>) bug
+// operator&(chset<>, range<>) bug
+// operator&(range<>, chset<>) bug
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/limits.hpp>
+#include <boost/spirit/include/classic_chset.hpp>
+
+void bug_004()
+{
+ const char min = (std::numeric_limits<char>::min)();
+ const char max = (std::numeric_limits<char>::max)();
+
+ {
+ chset<> set(~range<>(min, max));
+ BOOST_TEST(set.test(min) == false);
+ BOOST_TEST(set.test(min) == false);
+ }
+
+ {
+ chset<> set(chset<>(anychar_p) & range<>(min, max));
+ BOOST_TEST(set.test(min) == true);
+ BOOST_TEST(set.test(min) == true);
+ }
+
+ {
+ chset<> set(range<>(min, max) & chset<>(anychar_p));
+ BOOST_TEST(set.test(min) == true);
+ BOOST_TEST(set.test(min) == true);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// bug_005
+//
+// Most trailing space bug
+// http://article.gmane.org/gmane.comp.parsers.spirit.general/4029
+// JDG: Oct 18, 2005. We shall revert to the previous behavior where
+// Post skips are not allowed. The reason is that
+// there is a valid use case where input is obtained
+// from cin and multi_pass which results in an infinite
+// loop while the post skipper waits for a whitespace.
+// For examples like below, the grammar must explicitly
+// include the post whitespace. One possible way is to
+// place an end_p at the end of the grammar. The end_p
+// will trigger the post-skip.
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_core.hpp>
+
+using namespace boost;
+using namespace spirit;
+
+void bug_005()
+{
+ BOOST_TEST(
+ parse(" aaaaaaaaa ", *ch_p('a') >> end_p, space_p).full
+ );
+
+ BOOST_TEST(
+ parse(" aaaaaaaaa ", lexeme_d[*ch_p('a')] >> end_p, space_p).full
+ );
+
+#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
+ // not sure why Code Warrior 9.5 does not recognize ch_p(' ') as the
+ // same as space_p (see above) when the inputs are spaces. The
+ // tests below are redundant anyway.
+#else
+
+ BOOST_TEST(
+ parse(" aaaaaaaaa ", *ch_p('a') >> end_p, ch_p(' ')).full
+ );
+
+ BOOST_TEST(
+ parse(" aaaaaaaaa ", lexeme_d[*ch_p('a')] >> end_p, ch_p(' ')).full
+ );
+
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// bug_006
+//
+// confix bug
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/limits.hpp>
+#include <boost/spirit/include/classic_confix.hpp>
+
+void bug_006()
+{
+ BOOST_TEST(parse("#some comment", comment_p('#')).full);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// bug_007
+//
+// handling of trailing whitespace bug (ast_parse/pt_parse related)
+// JDG: Oct 18, 2005. We shall revert to the previous behavior where
+// Post skips are not allowed. The reason is that
+// there is a valid use case where input is obtained
+// from cin and multi_pass which results in an infinite
+// loop while the post skipper waits for a whitespace.
+// For examples like below, the grammar must explicitly
+// include the post whitespace. One possible way is to
+// place an end_p at the end of the grammar. The end_p
+// will trigger the post-skip.
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_ast.hpp>
+#include <boost/spirit/include/classic_parse_tree.hpp>
+
+void bug_007()
+{
+ BOOST_TEST(parse("test ", str_p("test") >> end_p, space_p).full);
+ BOOST_TEST(pt_parse("test ", str_p("test") >> end_p, space_p).full);
+ BOOST_TEST(ast_parse("test ", str_p("test") >> end_p, space_p).full);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// sf_bug_718903
+//
+// see https://sourceforge.net/tracker/index.php
+// ?func=detail&aid=718903&group_id=28447&atid=393386
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/cstdlib.hpp>
+#include <boost/spirit/include/classic_chset.hpp>
+
+void sf_bug_718903()
+{
+ empty_match_parser<chset<char> >
+ e(epsilon_p(chset_p("abc")));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// sf_bug_719322
+// range_run bug
+//
+// see http://sourceforge.net/tracker/index.php
+// ?func=detail&aid=719322&group_id=28447&atid=393386
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_basic_chset.hpp>
+
+void sf_bug_719322()
+{
+ basic_chset<int> s;
+ s.set(3, 3);
+ s.set(1, 5);
+ BOOST_TEST(s.test(5));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// sf_bug_742038
+//
+// see http://sf.net/tracker/
+// ?func=detail&atid=393386&aid=742038&group_id=28447
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_position_iterator.hpp>
+#include <boost/spirit/include/classic_file_iterator.hpp>
+#include <string>
+#include <fstream>
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+#include <stdio.h>
+
+template <typename IterT>
+void test_assign(IterT b, IterT e)
+{
+ typedef scanner<IterT> scanner_t;
+
+#if (defined(__GNUC__) && defined(__MINGW32__)) \
+ || (defined(__GNUC__) && (__GNUC_MINOR__ < 20))
+
+// There's a bug in g++3.x on MinGW that makes basic_string assert
+// when assigning from IterT [f, l) where IterT is a position_iterator.
+// This issue is discussed here:
+//
+// http://gcc.gnu.org/ml/libstdc++/2002-03/msg00196.html
+//
+// Aparently, this bug is only present on MinGW. I'm clueless as
+// to why this is so. Regressions on linux seem to be OK! :(
+//
+// With, g++3.1, assigning to basic_string from IterT [f, l) is a
+// compile error (a g++3.1 bug).
+//
+// In both cases above, we use a vector instead of a string.
+
+ typedef std::vector<char> store;
+#else
+ typedef std::string store;
+#endif
+
+ store dst;
+ rule<scanner_t> r = (*alpha_p)[assign_a(dst)];
+
+ parse(b, e, r);
+
+ store::iterator d = dst.begin();
+
+ while (b != e)
+ {
+ if (*d != *b)
+ BOOST_TEST(*d == *b);
+ ++b;
+ ++d;
+ }
+}
+
+void sf_bug_742038()
+{
+ std::string src = "abcdef";
+ const char* tmpfilename = "sf_bug_742038.tmp";
+
+ test_assign(src.begin(), src.end());
+
+ position_iterator<std::string::iterator> b(src.begin(), src.end(), "");
+ position_iterator<std::string::iterator> e;
+ test_assign(b, e);
+
+ {
+ std::fstream f(tmpfilename, std::ios::out);
+ f << src;
+ f.close();
+
+ file_iterator<> b1(tmpfilename);
+ file_iterator<> e1(b1.make_end());
+ test_assign(b1, e1);
+ }
+
+ std::remove(tmpfilename);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// bug_009
+//
+// limit_d bug
+// http://article.gmane.org/gmane.comp.parsers.spirit.devel/1891/
+//
+///////////////////////////////////////////////////////////////////////////////
+void
+bug_009()
+{
+ parse(
+ "test"
+ , limit_d(1U, 10U)[uint_p] | str_p("test"));
+}
+
+int
+main()
+{
+ bug_001();
+ bug_002();
+ bug_003();
+ bug_004();
+ bug_005();
+ bug_006();
+ bug_007();
+ bug_009();
+
+ sf_bug_718903();
+ sf_bug_719322();
+ sf_bug_742038();
+
+ return boost::report_errors();
+}