1 // Copyright (c) 2001-2011 Hartmut Kaiser 2 // Copyright (c) 2001-2011 Joel de Guzman 3 // 4 // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 7 #if !defined(BOOST_SPIRIT_KARMA_SIMPLE_TRACE_APR_21_2010_0155PM) 8 #define BOOST_SPIRIT_KARMA_SIMPLE_TRACE_APR_21_2010_0155PM 9 10 #if defined(_MSC_VER) 11 #pragma once 12 #endif 13 14 #include <boost/spirit/home/support/unused.hpp> 15 #include <boost/spirit/home/karma/nonterminal/debug_handler_state.hpp> 16 #include <boost/fusion/include/out.hpp> 17 #include <iostream> 18 19 // The stream to use for debug output 20 #if !defined(BOOST_SPIRIT_DEBUG_OUT) 21 #define BOOST_SPIRIT_DEBUG_OUT std::cerr 22 #endif 23 24 // number of tokens to print while debugging 25 #if !defined(BOOST_SPIRIT_DEBUG_PRINT_SOME) 26 #define BOOST_SPIRIT_DEBUG_PRINT_SOME 20 27 #endif 28 29 // number of spaces to indent 30 #if !defined(BOOST_SPIRIT_DEBUG_INDENT) 31 #define BOOST_SPIRIT_DEBUG_INDENT 2 32 #endif 33 34 namespace boost { namespace spirit { namespace karma 35 { 36 struct simple_trace 37 { get_indentboost::spirit::karma::simple_trace38 int& get_indent() const 39 { 40 static int indent = 0; 41 return indent; 42 } 43 print_indentboost::spirit::karma::simple_trace44 void print_indent() const 45 { 46 int n = get_indent(); 47 n *= BOOST_SPIRIT_DEBUG_INDENT; 48 for (int i = 0; i != n; ++i) 49 BOOST_SPIRIT_DEBUG_OUT << ' '; 50 } 51 52 template <typename Buffer> print_someboost::spirit::karma::simple_trace53 void print_some(char const* tag, Buffer const& buffer) const 54 { 55 print_indent(); 56 BOOST_SPIRIT_DEBUG_OUT << '<' << tag << '>' << std::flush; 57 { 58 std::ostreambuf_iterator<char> out(BOOST_SPIRIT_DEBUG_OUT); 59 buffer.buffer_copy_to(out, BOOST_SPIRIT_DEBUG_PRINT_SOME); 60 } 61 BOOST_SPIRIT_DEBUG_OUT << "</" << tag << '>' << std::endl; 62 } 63 64 template <typename OutputIterator, typename Context, typename State 65 , typename Buffer> operator ()boost::spirit::karma::simple_trace66 void operator()( 67 OutputIterator&, Context const& context 68 , State state, std::string const& rule_name 69 , Buffer const& buffer) const 70 { 71 switch (state) 72 { 73 case pre_generate: 74 print_indent(); 75 ++get_indent(); 76 BOOST_SPIRIT_DEBUG_OUT 77 << '<' << rule_name << '>' << std::endl; 78 print_indent(); 79 ++get_indent(); 80 BOOST_SPIRIT_DEBUG_OUT << "<try>" << std::endl;; 81 print_indent(); 82 BOOST_SPIRIT_DEBUG_OUT << "<attributes>"; 83 traits::print_attribute( 84 BOOST_SPIRIT_DEBUG_OUT, 85 context.attributes 86 ); 87 BOOST_SPIRIT_DEBUG_OUT << "</attributes>" << std::endl; 88 if (!fusion::empty(context.locals)) 89 { 90 print_indent(); 91 BOOST_SPIRIT_DEBUG_OUT 92 << "<locals>" << context.locals << "</locals>" 93 << std::endl; 94 } 95 --get_indent(); 96 print_indent(); 97 BOOST_SPIRIT_DEBUG_OUT << "</try>" << std::endl;; 98 break; 99 100 case successful_generate: 101 print_indent(); 102 ++get_indent(); 103 BOOST_SPIRIT_DEBUG_OUT << "<success>" << std::endl; 104 print_some("result", buffer); 105 if (!fusion::empty(context.locals)) 106 { 107 print_indent(); 108 BOOST_SPIRIT_DEBUG_OUT 109 << "<locals>" << context.locals << "</locals>" 110 << std::endl; 111 } 112 --get_indent(); 113 print_indent(); 114 BOOST_SPIRIT_DEBUG_OUT << "</success>" << std::endl; 115 --get_indent(); 116 print_indent(); 117 BOOST_SPIRIT_DEBUG_OUT 118 << "</" << rule_name << '>' << std::endl; 119 break; 120 121 case failed_generate: 122 print_indent(); 123 BOOST_SPIRIT_DEBUG_OUT << "<fail/>" << std::endl; 124 --get_indent(); 125 print_indent(); 126 BOOST_SPIRIT_DEBUG_OUT 127 << "</" << rule_name << '>' << std::endl; 128 break; 129 } 130 } 131 }; 132 }}} 133 134 #endif 135