• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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