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