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/type_traits/is_same.hpp>
16#include <iostream>
17
18// The stream to use for debug output
19#if !defined(BOOST_SPIRIT_X3_DEBUG_OUT)
20#define BOOST_SPIRIT_X3_DEBUG_OUT std::cerr
21#endif
22
23// number of tokens to print while debugging
24#if !defined(BOOST_SPIRIT_X3_DEBUG_PRINT_SOME)
25#define BOOST_SPIRIT_X3_DEBUG_PRINT_SOME 20
26#endif
27
28// number of spaces to indent
29#if !defined(BOOST_SPIRIT_X3_DEBUG_INDENT)
30#define BOOST_SPIRIT_X3_DEBUG_INDENT 2
31#endif
32
33namespace boost { namespace spirit { namespace x3
34{
35 namespace detail
36 {
37 template <typename Char>
38 inline void token_printer(std::ostream& o, Char c)
39 {
40 // allow customization of the token printer routine
41 x3::traits::print_token(o, c);
42 }
43 }
44
45 template <int IndentSpaces = 2, int CharsToPrint = 20>
46 struct simple_trace
47 {
48 simple_trace(std::ostream& out)
49 : out(out), indent(0) {}
50
51 void print_indent(int n) const
52 {
53 n *= IndentSpaces;
54 for (int i = 0; i != n; ++i)
55 out << ' ';
56 }
57
58 template <typename Iterator>
59 void print_some(
60 char const* tag
61 , Iterator first, Iterator const& last) const
62 {
63 print_indent(n: indent);
64 out << '<' << tag << '>';
65 int const n = CharsToPrint;
66 for (int i = 0; first != last && i != n && *first; ++i, ++first)
67 detail::token_printer(out, *first);
68 out << "</" << tag << '>' << std::endl;
69
70 // $$$ FIXME convert invalid xml characters (e.g. '<') to valid
71 // character entities. $$$
72 }
73
74 template <typename Iterator, typename Attribute, typename State>
75 void operator()(
76 Iterator const& first
77 , Iterator const& last
78 , Attribute const& attr
79 , State state
80 , std::string const& rule_name) const
81 {
82 switch (state)
83 {
84 case pre_parse:
85 print_indent(n: indent++);
86 out
87 << '<' << rule_name << '>'
88 << std::endl;
89 print_some("try", first, last);
90 break;
91
92 case successful_parse:
93 print_some("success", first, last);
94 if (!is_same<Attribute, unused_type>::value)
95 {
96 print_indent(n: indent);
97 out
98 << "<attributes>";
99 traits::print_attribute(out, attr);
100 out
101 << "</attributes>";
102 out << std::endl;
103 }
104 print_indent(n: --indent);
105 out
106 << "</" << rule_name << '>'
107 << std::endl;
108 break;
109
110 case failed_parse:
111 print_indent(n: indent);
112 out << "<fail/>" << std::endl;
113 print_indent(n: --indent);
114 out
115 << "</" << rule_name << '>'
116 << std::endl;
117 break;
118 }
119 }
120
121 std::ostream& out;
122 mutable int indent;
123 };
124
125 namespace detail
126 {
127 typedef simple_trace<
128 BOOST_SPIRIT_X3_DEBUG_INDENT, BOOST_SPIRIT_X3_DEBUG_PRINT_SOME>
129 simple_trace_type;
130
131 inline simple_trace_type&
132 get_simple_trace()
133 {
134 static simple_trace_type tracer(BOOST_SPIRIT_X3_DEBUG_OUT);
135 return tracer;
136 }
137 }
138}}}
139
140#endif
141

source code of boost/libs/spirit/include/boost/spirit/home/x3/nonterminal/simple_trace.hpp