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