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