]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/spirit/home/qi/nonterminal/simple_trace.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / spirit / home / qi / nonterminal / simple_trace.hpp
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