// Copyright (c) 2001-2010 Hartmut Kaiser // Copyright (c) 2001-2010 Joel de Guzman // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #if !defined(BOOST_SPIRIT_KARMA_DEBUG_HANDLER_APR_21_2010_0148PM) #define BOOST_SPIRIT_KARMA_DEBUG_HANDLER_APR_21_2010_0148PM #if defined(_MSC_VER) #pragma once #endif #include #include #include #include #include #include #include #include namespace boost { namespace spirit { namespace karma { template < typename OutputIterator, typename Context, typename Delimiter , typename Properties, typename F> struct debug_handler { typedef detail::output_iterator output_iterator; typedef detail::enable_buffering buffer_type; typedef function function_type; debug_handler(function_type subject, F f, std::string const& rule_name) : subject(subject) , f(f) , rule_name(rule_name) {} bool operator()(output_iterator& sink, Context& context , Delimiter const& delim) const { buffer_type buffer(sink); bool r = false; f (sink, context, pre_generate, rule_name, buffer); { detail::disable_counting nocount(sink); r = subject(sink, context, delim); } if (r) { f (sink, context, successful_generate, rule_name, buffer); buffer.buffer_copy(); return true; } f (sink, context, failed_generate, rule_name, buffer); return false; } function_type subject; F f; std::string rule_name; }; template void debug(rule& r, F f) { typedef rule rule_type; typedef debug_handler< OutputIterator , typename rule_type::context_type , typename rule_type::delimiter_type , typename rule_type::properties , F> debug_handler; r.f = debug_handler(r.f, f, r.name()); } struct simple_trace; namespace detail { // This class provides an extra level of indirection through a // template to produce the simple_trace type. This way, the use // of simple_trace below is hidden behind a dependent type, so // that compilers eagerly type-checking template definitions // won't complain that simple_trace is incomplete. template struct get_simple_trace { typedef simple_trace type; }; } template void debug(rule& r) { typedef rule rule_type; typedef debug_handler< OutputIterator , typename rule_type::context_type , typename rule_type::delimiter_type , typename rule_type::properties , simple_trace> debug_handler; typedef typename karma::detail::get_simple_trace::type trace; r.f = debug_handler(r.f, trace(), r.name()); } }}} /////////////////////////////////////////////////////////////////////////////// // Utility macro for easy enabling of rule and grammar debugging #if !defined(BOOST_SPIRIT_DEBUG_NODE) #if defined(BOOST_SPIRIT_KARMA_DEBUG) #define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r); debug(r) #else #define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r); #endif #endif #endif