blob: 98dab3849e3686f0506f5f4cdfde6be8a1c560f1 [file] [log] [blame]
/*=============================================================================
Copyright (c) 2001-2009 Hartmut Kaiser
Copyright (c) 2001-2007 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_DEBUG_HANDLER_NOV_12_2007_0926AM)
#define BOOST_SPIRIT_DEBUG_HANDLER_NOV_12_2007_0926AM
#include <boost/spirit/home/qi/nonterminal/virtual_component_base.hpp>
namespace boost { namespace spirit { namespace qi { namespace debug
{
namespace detail
{
///////////////////////////////////////////////////////////////////////////
// This class is to avoid linker problems and to ensure a real singleton
// 'level' variable
static int& get_trace_level()
{
static int level = 0;
return level;
}
struct trace_level
{
trace_level(int &level)
: level(level)
{
++level;
}
~trace_level()
{
--level;
}
int& level;
};
///////////////////////////////////////////////////////////////////////////
template <
typename Iterator, typename Context, typename Skipper,
typename PreParseF, typename PostParseF
>
struct debug_handler
: virtual_component_base<Iterator, Context, Skipper>
{
typedef
virtual_component_base<Iterator, Context, Skipper>
base_type;
typedef intrusive_ptr<base_type> pointer_type;
typedef typename base_type::skipper_type skipper_type;
debug_handler(pointer_type subject, std::string const& name,
bool trace, PreParseF preF, PostParseF postF)
: subject(subject), name(name), trace(trace),
preF(preF), postF(postF)
{
}
template <typename Skipper_>
bool parse_main(
Iterator& first
, Iterator const& last
, Context& context
, Skipper_ const& skipper)
{
// execute embedded parser if tracing is disabled or if the
// pre-parse hook returns true
bool r = false;
if (!trace || preF(name, subject, get_trace_level(), first, last))
{
{
trace_level level(get_trace_level());
// do the actual parsing
Iterator i = first;
r = subject->parse(i, last, context, skipper);
if (r)
first = i;
}
// the post-parse hook gets executed only if tracing is enabled
if (trace)
postF(r, name, subject, get_trace_level(), first, last);
}
return r;
}
virtual bool
parse(
Iterator& first
, Iterator const& last
, Context& context
, skipper_type const& skipper)
{
return parse_main(first, last, context, skipper);
}
virtual bool
parse(
Iterator& first
, Iterator const& last
, Context& context
, no_skipper)
{
return parse_main(first, last, context, unused);
}
pointer_type subject;
std::string const& name;
bool trace;
PreParseF preF;
PostParseF postF;
};
}
}}}}
#endif