/*============================================================================= Copyright (c) 2001-2010 Joel de Guzman Copyright (c) 2001-2010 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_SIMPLE_TRACE_DECEMBER_06_2008_1102AM) #define BOOST_SPIRIT_SIMPLE_TRACE_DECEMBER_06_2008_1102AM #if defined(_MSC_VER) #pragma once #endif #include #include #include #include #include #include #include #include // The stream to use for debug output #if !defined(BOOST_SPIRIT_DEBUG_OUT) #define BOOST_SPIRIT_DEBUG_OUT std::cerr #endif // number of tokens to print while debugging #if !defined(BOOST_SPIRIT_DEBUG_PRINT_SOME) #define BOOST_SPIRIT_DEBUG_PRINT_SOME 20 #endif // number of spaces to indent #if !defined(BOOST_SPIRIT_DEBUG_INDENT) #define BOOST_SPIRIT_DEBUG_INDENT 2 #endif namespace boost { namespace spirit { namespace qi { namespace detail { template inline void token_printer(std::ostream& o, Char c) { // allow to customize the token printer routine spirit::traits::print_token(o, c); } } struct simple_trace { int& get_indent() const { static int indent = 0; return indent; } void print_indent(int n) const { n *= BOOST_SPIRIT_DEBUG_INDENT; for (int i = 0; i != n; ++i) BOOST_SPIRIT_DEBUG_OUT << ' '; } template void print_some( char const* tag , int indent , Iterator first, Iterator const& last) const { print_indent(get_indent()); BOOST_SPIRIT_DEBUG_OUT << '<' << tag << '>'; int const n = BOOST_SPIRIT_DEBUG_PRINT_SOME; for (int i = 0; first != last && i != n && *first; ++i, ++first) detail::token_printer(BOOST_SPIRIT_DEBUG_OUT, *first); BOOST_SPIRIT_DEBUG_OUT << "' << std::endl; // $$$ FIXME convert invalid xml characters (e.g. '<') to valid // character entities. $$$ } template void operator()( Iterator const& first , Iterator const& last , Context const& context , State state , std::string const& rule_name) const { switch (state) { case pre_parse: print_indent(get_indent()++); BOOST_SPIRIT_DEBUG_OUT << '<' << rule_name << '>' << std::endl; print_some("try", get_indent(), first, last); break; case successful_parse: print_some("success", get_indent(), first, last); print_indent(get_indent()); BOOST_SPIRIT_DEBUG_OUT << ""; traits::print_attribute( BOOST_SPIRIT_DEBUG_OUT, context.attributes ); BOOST_SPIRIT_DEBUG_OUT << ""; if (!fusion::empty(context.locals)) BOOST_SPIRIT_DEBUG_OUT << "" << context.locals << ""; BOOST_SPIRIT_DEBUG_OUT << std::endl; print_indent(--get_indent()); BOOST_SPIRIT_DEBUG_OUT << "' << std::endl; break; case failed_parse: print_indent(get_indent()); BOOST_SPIRIT_DEBUG_OUT << "" << std::endl; print_indent(--get_indent()); BOOST_SPIRIT_DEBUG_OUT << "' << std::endl; break; } } }; }}} #endif