/*============================================================================= Copyright (c) 2001-2014 Joel de Guzman Copyright (c) 2001-2011 Hartmut Kaiser Distributed under 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) ==============================================================================*/ #if !defined(BOOST_SPIRIT_X3_SIMPLE_TRACE_DECEMBER_06_2008_1102AM) #define BOOST_SPIRIT_X3_SIMPLE_TRACE_DECEMBER_06_2008_1102AM #include #include #include #include #include #include #include // The stream to use for debug output #if !defined(BOOST_SPIRIT_X3_DEBUG_OUT) #define BOOST_SPIRIT_X3_DEBUG_OUT std::cerr #endif // number of tokens to print while debugging #if !defined(BOOST_SPIRIT_X3_DEBUG_PRINT_SOME) #define BOOST_SPIRIT_X3_DEBUG_PRINT_SOME 20 #endif // number of spaces to indent #if !defined(BOOST_SPIRIT_X3_DEBUG_INDENT) #define BOOST_SPIRIT_X3_DEBUG_INDENT 2 #endif namespace boost { namespace spirit { namespace x3 { namespace detail { template inline void token_printer(std::ostream& o, Char c) { // allow customization of the token printer routine x3::traits::print_token(o, c); } } template struct simple_trace { simple_trace(std::ostream& out) : out(out), indent(0) {} void print_indent(int n) const { n *= IndentSpaces; for (int i = 0; i != n; ++i) out << ' '; } template void print_some( char const* tag , Iterator first, Iterator const& last) const { print_indent(indent); out << '<' << tag << '>'; int const n = CharsToPrint; for (int i = 0; first != last && i != n && *first; ++i, ++first) detail::token_printer(out, *first); out << "' << std::endl; // $$$ FIXME convert invalid xml characters (e.g. '<') to valid // character entities. $$$ } template void operator()( Iterator const& first , Iterator const& last , Attribute const& attr , State state , std::string const& rule_name) const { switch (state) { case pre_parse: print_indent(indent++); out << '<' << rule_name << '>' << std::endl; print_some("try", first, last); break; case successful_parse: print_some("success", first, last); if (!is_same::value) { print_indent(indent); out << ""; traits::print_attribute(out, attr); out << ""; out << std::endl; } //~ if (!fusion::empty(context.locals)) //~ out //~ << "" //~ << context.locals //~ << ""; print_indent(--indent); out << "' << std::endl; break; case failed_parse: print_indent(indent); out << "" << std::endl; print_indent(--indent); out << "' << std::endl; break; } } std::ostream& out; mutable int indent; }; namespace detail { typedef simple_trace< BOOST_SPIRIT_X3_DEBUG_INDENT, BOOST_SPIRIT_X3_DEBUG_PRINT_SOME> simple_trace_type; inline simple_trace_type& get_simple_trace() { static simple_trace_type tracer(BOOST_SPIRIT_X3_DEBUG_OUT); return tracer; } } }}} #endif