2
0
mirror of https://github.com/boostorg/wave.git synced 2026-01-19 04:42:16 +00:00

Removed Wave from the sanbox CVS.

[SVN r2599]
This commit is contained in:
Hartmut Kaiser
2005-05-07 12:47:30 +00:00
parent f2662d1b13
commit 02b2b73c71
51 changed files with 0 additions and 15529 deletions

View File

@@ -1,21 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(WAVE_HPP_DCA0EA51_EF5B_4BF1_88A8_461DBC5F292B_INCLUDED)
#define WAVE_HPP_DCA0EA51_EF5B_4BF1_88A8_461DBC5F292B_INCLUDED
#include <boost/wave/wave_config.hpp>
#include <boost/wave/cpp_exceptions.hpp>
#include <boost/wave/cpplexer/cpplexer_exceptions.hpp>
#include <boost/wave/token_ids.hpp>
#include <boost/wave/cpp_context.hpp>
#endif // !defined(WAVE_HPP_DCA0EA51_EF5B_4BF1_88A8_461DBC5F292B_INCLUDED)

View File

@@ -1,300 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Definition of the preprocessor context
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_CONTEXT_HPP_907485E2_6649_4A87_911B_7F7225F3E5B8_INCLUDED)
#define CPP_CONTEXT_HPP_907485E2_6649_4A87_911B_7F7225F3E5B8_INCLUDED
#include <string>
#include <vector>
#include <stack>
#include <boost/concept_check.hpp>
#include <boost/wave/wave_config.hpp>
#include <boost/wave/token_ids.hpp>
#include <boost/wave/util/unput_queue_iterator.hpp>
#include <boost/wave/util/cpp_ifblock.hpp>
#include <boost/wave/util/cpp_include_pathes.hpp>
#include <boost/wave/util/iteration_context.hpp>
#include <boost/wave/util/cpp_iterator.hpp>
#include <boost/wave/util/cpp_macromap.hpp>
#include <boost/wave/preprocessing_hooks.hpp>
#include <boost/wave/cpp_iteration_context.hpp>
#include <boost/wave/language_support.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
///////////////////////////////////////////////////////////////////////////////
//
// The C preprocessor context template class
//
// The boost::wave::context template is the main interface class to
// control the behaviour of the preprocessing engine.
//
// The following template parameters has to be supplied:
//
// IteratorT The iterator type of the underlying input stream
// LexIteratorT The lexer iterator type to use as the token factory
// InputPolicyT The input policy type to use for loading the files
// to be included. This template parameter is optional and
// defaults to the
// iteration_context_policies::load_file_to_string
// type
// TraceT The trace policy to use for trace and include file
// notification callback.
//
///////////////////////////////////////////////////////////////////////////////
template <
typename IteratorT,
typename LexIteratorT,
typename InputPolicyT = iteration_context_policies::load_file_to_string,
typename TraceT = context_policies::default_preprocessing_hooks
>
class context {
public:
// concept checks
// the given iterator shall be at least a forward iterator type
BOOST_CLASS_REQUIRE(IteratorT, boost, ForwardIteratorConcept);
// public typedefs
typedef typename LexIteratorT::token_type token_type;
typedef context<IteratorT, LexIteratorT, InputPolicyT, TraceT>
self_type;
typedef IteratorT target_iterator_type;
typedef LexIteratorT lexer_type;
typedef pp_iterator<self_type> iterator_type;
typedef InputPolicyT input_policy_type;
typedef typename token_type::position_type position_type;
// type of a token sequence
typedef std::list<token_type, boost::fast_pool_allocator<token_type> >
token_sequence_type;
// types of the policies
typedef TraceT trace_policy_type;
private:
// stack of shared_ptr's to the pending iteration contexts
typedef boost::shared_ptr<base_iteration_context<lexer_type> >
iteration_ptr_type;
typedef boost::wave::util::iteration_context_stack<iteration_ptr_type>
iteration_context_stack_type;
typedef typename iteration_context_stack_type::size_type iter_size_type;
public:
context(target_iterator_type const &first_, target_iterator_type const &last_,
char const *fname = "<Unknown>", TraceT const &trace_ = TraceT())
: first(first_), last(last_), filename(fname)
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
, current_filename(fname)
#endif
, macros(*this), language(boost::wave::support_cpp), trace(trace_)
{
macros.init_predefined_macros();
includes.init_initial_path();
includes.set_current_directory(filename.c_str());
}
// iterator interface
iterator_type begin()
{
return iterator_type(*this, first, last, position_type(filename.c_str()),
get_language());
}
iterator_type end() const
{ return iterator_type(); }
// maintain include paths
bool add_include_path(char const *path_)
{ return includes.add_include_path(path_, false);}
bool add_sysinclude_path(char const *path_)
{ return includes.add_include_path(path_, true);}
void set_sysinclude_delimiter() { includes.set_sys_include_delimiter(); }
typename iteration_context_stack_type::size_type get_iteration_depth() const
{ return iter_ctxs.size(); }
// maintain defined macros
#if BOOST_WAVE_ENABLE_COMMANDLINE_MACROS != 0
bool add_macro_definition(std::string macrostring,
bool is_predefined = false)
{ return boost::wave::util::add_macro_definition(*this, macrostring,
is_predefined, get_language()); }
#endif
bool add_macro_definition(token_type const &name, bool has_params,
std::vector<token_type> &parameters, token_sequence_type &definition,
bool is_predefined = false)
{ return macros.add_macro(name, has_params, parameters, definition,
is_predefined); }
template <typename IteratorT2>
bool is_defined_macro(IteratorT2 const &begin, IteratorT2 const &end)
{ return macros.is_defined(begin, end); }
bool remove_macro_definition(typename token_type::string_type const &name,
bool even_predefined = false)
{ return macros.remove_macro(name, even_predefined); }
void reset_macro_definitions()
{ macros.reset_macromap(); macros.init_predefined_macros(); }
// get the pp-iterator version information
static std::string get_version()
{ return boost::wave::util::predefined_macros::get_fullversion(false); }
static std::string get_version_string()
{ return boost::wave::util::predefined_macros::get_versionstr(false); }
void set_language(boost::wave::language_support language_)
{
language = language_;
reset_macro_definitions();
}
boost::wave::language_support get_language() const { return language; }
// change and ask for maximal possible include nesting depth
void set_max_include_nesting_depth(iter_size_type new_depth)
{ iter_ctxs.set_max_include_nesting_depth(new_depth); }
iter_size_type get_max_include_nesting_depth() const
{ return iter_ctxs.get_max_include_nesting_depth(); }
// access the trace policy
trace_policy_type &get_trace_policy()
{ return trace; }
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
protected:
friend class boost::wave::pp_iterator<
boost::wave::context<IteratorT, lexer_type, InputPolicyT, TraceT> >;
friend class boost::wave::impl::pp_iterator_functor<
boost::wave::context<IteratorT, lexer_type, InputPolicyT, TraceT> >;
#endif
// maintain include pathes (helper functions)
bool find_include_file (std::string &s, bool is_system,
char const *current_file) const
{ return includes.find_include_file(s, is_system, current_file); }
void set_current_directory(char const *path_)
{ includes.set_current_directory(path_); }
// conditional compilation contexts
bool get_if_block_status() const { return ifblocks.get_status(); }
void enter_if_block(bool new_status)
{ ifblocks.enter_if_block(new_status); }
bool enter_elif_block(bool new_status)
{ return ifblocks.enter_elif_block(new_status); }
bool enter_else_block() { return ifblocks.enter_else_block(); }
bool exit_if_block() { return ifblocks.exit_if_block(); }
typename boost::wave::util::if_block_stack::size_type get_if_block_depth() const
{ return ifblocks.get_if_block_depth(); }
// stack of iteration contexts
iteration_ptr_type pop_iteration_context()
{ iteration_ptr_type top = iter_ctxs.top(); iter_ctxs.pop(); return top; }
void push_iteration_context(position_type const &act_pos, iteration_ptr_type iter_ctx)
{ iter_ctxs.push(act_pos, iter_ctx); }
position_type &get_main_pos() { return macros.get_main_pos(); }
///////////////////////////////////////////////////////////////////////////////
//
// expand_tokensequence():
// expands all macros contained in a given token sequence, handles '##'
// and '#' pp operators and re-scans the resulting sequence
// (essentially preprocesses the token sequence).
//
// The expand_undefined parameter is true during macro expansion inside
// a C++ expression given for a #if or #elif statement.
//
///////////////////////////////////////////////////////////////////////////////
template <typename IteratorT2>
token_type expand_tokensequence(IteratorT2 &first, IteratorT2 const &last,
token_sequence_type &pending, token_sequence_type &expanded,
bool expand_undefined = false)
{
return macros.expand_tokensequence(first, last, pending, expanded,
expand_undefined);
}
template <typename IteratorT2>
void expand_whole_tokensequence(IteratorT2 &first, IteratorT2 const &last,
token_sequence_type &expanded, bool expand_undefined = true)
{
macros.expand_whole_tokensequence(expanded, first, last,
expand_undefined);
// remove any contained placeholder
boost::wave::util::impl::remove_placeholders(expanded);
}
public:
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
// support for #pragma once
// maintain the real name of the current preprocessed file
void set_current_filename(char const *real_name)
{ current_filename = real_name; }
std::string const &get_current_filename() const
{ return current_filename; }
// maintain the list of known headers containing #pragma once
bool has_pragma_once(std::string const &filename)
{ return includes.has_pragma_once(filename); }
bool add_pragma_once_header(std::string const &filename)
{ return includes.add_pragma_once_header(filename); }
#endif
// forwarding functions for the context policy hooks
template <typename ContainerT>
bool interpret_pragma(ContainerT &pending, token_type const &option,
ContainerT const &values, token_type const &act_token)
{
return trace.interpret_pragma(*this, pending, option, values,
act_token);
}
template <typename ParametersT, typename DefinitionT>
void defined_macro(token_type const &name, bool is_functionlike,
ParametersT const &parameters, DefinitionT const &definition,
bool is_predefined)
{
trace.defined_macro(name, is_functionlike, parameters, definition,
is_predefined);
}
void undefined_macro(typename token_type::string_type const &name)
{
trace.undefined_macro(name);
}
private:
// the main input stream
target_iterator_type first; // underlying input stream
target_iterator_type last;
std::string filename; // associated main filename
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
std::string current_filename; // real name of current preprocessed file
#endif
boost::wave::util::if_block_stack ifblocks; // conditional compilation contexts
boost::wave::util::include_pathes includes; // lists of include directories to search
iteration_context_stack_type iter_ctxs; // iteration contexts
boost::wave::util::macromap<self_type> macros; // map of defined macros
boost::wave::language_support language; // supported language/extensions
trace_policy_type trace; // trace policy instance
};
///////////////////////////////////////////////////////////////////////////////
} // namespace wave
} // namespace boost
#endif // !defined(CPP_CONTEXT_HPP_907485E2_6649_4A87_911B_7F7225F3E5B8_INCLUDED)

View File

@@ -1,282 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_EXCEPTIONS_HPP_5190E447_A781_4521_A275_5134FF9917D7_INCLUDED)
#define CPP_EXCEPTIONS_HPP_5190E447_A781_4521_A275_5134FF9917D7_INCLUDED
#include <exception>
#include <string>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/wave/wave_config.hpp>
///////////////////////////////////////////////////////////////////////////////
// helper macro for throwing exceptions
#if !defined(BOOST_WAVE_THROW)
#ifdef BOOST_NO_STRINGSTREAM
#include <strstream>
#define BOOST_WAVE_THROW(cls, code, msg, act_pos) \
{ \
using namespace boost::wave; \
std::strstream stream; \
stream << cls::severity_text(cls::code) << ": " \
<< cls::error_text(cls::code); \
if ((msg)[0] != 0) stream << ": " << (msg); \
stream << std::ends; \
std::string throwmsg = stream.str(); stream.freeze(false); \
throw cls(throwmsg.c_str(), cls::code, (act_pos).get_line(), \
(act_pos).get_column(), (act_pos).get_file().c_str()); \
} \
/**/
#else
#include <sstream>
#define BOOST_WAVE_THROW(cls, code, msg, act_pos) \
{ \
using namespace boost::wave; \
std::stringstream stream; \
stream << cls::severity_text(cls::code) << ": " \
<< cls::error_text(cls::code); \
if ((msg)[0] != 0) stream << ": " << (msg); \
stream << std::ends; \
throw cls(stream.str().c_str(), cls::code, (act_pos).get_line(), \
(act_pos).get_column(), (act_pos).get_file().c_str()); \
} \
/**/
#endif // BOOST_NO_STRINGSTREAM
#endif // BOOST_WAVE_THROW
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
///////////////////////////////////////////////////////////////////////////////
// exception severity
namespace util {
enum severity {
severity_remark = 0,
severity_warning,
severity_error,
severity_fatal,
severity_commandline_error
};
inline char const *
get_severity(severity level)
{
static char const *severity_text[] =
{
"remark", // severity_remark
"warning", // severity_warning
"error", // severity_error
"fatal error", // severity_fatal
"command line error" // severity_commandline_error
};
BOOST_ASSERT(severity_remark <= level &&
level <= severity_commandline_error);
return severity_text[level];
}
}
///////////////////////////////////////////////////////////////////////////////
// cpp_exception, the base class for all specific C preprocessor exceptions
class cpp_exception
: public std::exception
{
public:
cpp_exception(int line_, int column_, char const *filename_) throw()
: line(line_), column(column_)
{
unsigned int off = 0;
while (off < sizeof(filename) && *filename_)
filename[off++] = *filename_++;
filename[off] = 0;
}
~cpp_exception() throw() {}
virtual char const *what() const throw() = 0; // to be overloaded
virtual char const *description() const throw() = 0;
int line_no() const throw() { return line; }
int column_no() const throw() { return column; }
char const *file_name() const throw() { return filename; }
protected:
char filename[512];
int line;
int column;
};
///////////////////////////////////////////////////////////////////////////////
// preprocessor error
class preprocess_exception :
public cpp_exception
{
public:
enum error_code {
unexpected_error = 0,
macro_redefinition,
macro_insertion_error,
bad_include_file,
bad_include_statement,
ill_formed_directive,
error_directive,
warning_directive,
ill_formed_expression,
missing_matching_if,
missing_matching_endif,
ill_formed_operator,
bad_define_statement,
too_few_macroarguments,
too_many_macroarguments,
improperly_terminated_macro,
bad_line_statement,
bad_undefine_statement,
bad_macro_definition,
illegal_redefinition,
duplicate_parameter_name,
invalid_concat,
last_line_not_terminated,
ill_formed_pragma_option,
include_nesting_too_deep,
misplaced_operator,
alreadydefined_name,
undefined_macroname,
invalid_macroname,
unexpected_qualified_name,
division_by_zero
};
preprocess_exception(char const *what_, error_code code, int line_,
int column_, char const *filename_) throw()
: cpp_exception(line_, column_, filename_), level(severity_level(code))
{
unsigned int off = 0;
while (off < sizeof(buffer) && *what_)
buffer[off++] = *what_++;
buffer[off] = 0;
}
~preprocess_exception() throw() {}
virtual char const *what() const throw()
{
return "boost::wave::preprocess_exception";
}
virtual char const *description() const throw()
{
return buffer;
}
util::severity get_severity()
{
return level;
}
static char const *error_text(int code)
{
// error texts in this array must appear in the same order as the items in
// the error enum above
static char const *preprocess_exception_errors[] = {
"unexpected error (should not happen)", // unexpected_error
"illegal macro redefinition", // macro_redefinition
"macro definition failed (out of memory?)", // macro_insertion_error
"could not find include file", // bad_include_file
"ill formed #include directive", // bad_include_statement
"ill formed preprocessor directive", // ill_formed_directive
"encountered #error directive or #pragma wave stop()", // error_directive
"encountered #warning directive", // warning_directive
"ill formed preprocessor expression", // ill_formed_expression
"the #if for this directive is missing", // missing_matching_if
"detected at least one missing #endif directive", // missing_matching_endif
"ill formed preprocessing operator", // ill_formed_operator
"ill formed #define directive", // bad_define_statement
"too few macro arguments", // too_few_macroarguments
"too many macro arguments", // too_many_macroarguments
"improperly terminated macro invocation "
"or replacement-list terminates in partial "
"macro expansion (not supported yet)", // improperly_terminated_macro
"ill formed #line directive", // bad_line_statement
"#undef may not be used on this predefined name", // bad_undefine_statement
"invalid macro definition", // bad_macro_definition
"this predefined name may not be redefined", // illegal_redefinition
"duplicate macro parameter name", // duplicate_parameter_name
"pasting the following two tokens does not "
"give a valid preprocessing token", // invalid_concat
"last line of file ends without a newline", // last_line_not_terminated
"unknown or illformed pragma option", // ill_formed_pragma_option
"include files nested too deep", // include_nesting_too_deep
"misplaced operator defined()", // misplaced_operator
"the name is already used in this scope as "
"a macro or scope name", // alreadydefined_name
"undefined macro or scope name may not be imported", // undefined_macroname
"ill formed macro name", // invalid_macroname
"qualified names are supported in C++0x mode only", // unexpected_qualified_name
"division by zero in preprocessor expression" // division_by_zero
};
BOOST_ASSERT(unexpected_error <= code &&
code <= division_by_zero);
return preprocess_exception_errors[code];
}
static util::severity severity_level(int code)
{
static util::severity preprocess_exception_severity[] = {
util::severity_fatal, // unexpected_error
util::severity_warning, // macro_redefinition
util::severity_fatal, // macro_insertion_error
util::severity_error, // bad_include_file
util::severity_error, // bad_include_statement
util::severity_error, // ill_formed_directive
util::severity_fatal, // error_directive
util::severity_warning, // warning_directive
util::severity_error, // ill_formed_expression
util::severity_error, // missing_matching_if
util::severity_error, // missing_matching_endif
util::severity_error, // ill_formed_operator
util::severity_error, // bad_define_statement
util::severity_warning, // too_few_macroarguments
util::severity_warning, // too_many_macroarguments
util::severity_error, // improperly_terminated_macro
util::severity_warning, // bad_line_statement
util::severity_warning, // bad_undefine_statement
util::severity_commandline_error, // bad_macro_definition
util::severity_warning, // illegal_redefinition
util::severity_error, // duplicate_parameter_name
util::severity_error, // invalid_concat
util::severity_warning, // last_line_not_terminated
util::severity_warning, // ill_formed_pragma_option
util::severity_fatal, // include_nesting_too_deep
util::severity_error, // misplaced_operator
util::severity_error, // alreadydefined_name
util::severity_error, // undefined_macroname
util::severity_error, // invalid_macroname
util::severity_error, // unexpected_qualified_name
util::severity_fatal // division_by_zero
};
BOOST_ASSERT(unexpected_error <= code &&
code <= division_by_zero);
return preprocess_exception_severity[code];
}
static char const *severity_text(int code)
{
return util::get_severity(severity_level(code));
}
private:
char buffer[512];
util::severity level;
};
///////////////////////////////////////////////////////////////////////////////
} // namespace wave
} // namespace boost
#endif // !defined(CPP_EXCEPTIONS_HPP_5190E447_A781_4521_A275_5134FF9917D7_INCLUDED)

View File

@@ -1,193 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Definition of the preprocessor context
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_ITERATION_CONTEXT_HPP_00312288_9DDB_4668_AFE5_25D3994FD095_INCLUDED)
#define CPP_ITERATION_CONTEXT_HPP_00312288_9DDB_4668_AFE5_25D3994FD095_INCLUDED
#include <iterator>
#include <fstream>
#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
#include <sstream>
#endif
#include <boost/wave/wave_config.hpp>
#include <boost/wave/cpp_exceptions.hpp>
#include <boost/wave/language_support.hpp>
#include <boost/wave/util/file_position.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace iteration_context_policies {
///////////////////////////////////////////////////////////////////////////////
//
// The iteration_context_policies templates are policies for the
// boost::wave::iteration_context which allows to control, how a given input file
// is to be represented by a pair of iterators pointing to the begin and
// the end of the resulting input sequence.
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
// load_file_to_string
//
// Loads a file into a string and returns the iterators pointing to
// the beginning and the end of the loaded string.
//
///////////////////////////////////////////////////////////////////////////
struct load_file_to_string {
template <typename IterContextT>
class inner {
public:
template <typename PositionT>
static
void init_iterators(IterContextT &iter_ctx,
PositionT const &act_pos)
{
typedef typename IterContextT::iterator_type iterator_type;
std::ifstream instream(iter_ctx.filename.c_str());
if (!instream.is_open()) {
BOOST_WAVE_THROW(preprocess_exception, bad_include_file,
iter_ctx.filename, act_pos);
}
instream.unsetf(std::ios::skipws);
#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
// this is known to be very slow for large files on some systems
std::copy (istream_iterator<char>(instream),
istream_iterator<char>(),
std::inserter(iter_ctx.instring, iter_ctx.instring.end()));
#else
iter_ctx.instring = std::string(
std::istreambuf_iterator<char>(instream.rdbuf()),
std::istreambuf_iterator<char>());
#endif // defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
iter_ctx.first = iterator_type(iter_ctx.instring.begin(),
iter_ctx.instring.end(), PositionT(iter_ctx.filename),
iter_ctx.language);
iter_ctx.last = iterator_type();
}
private:
std::string instring;
};
};
///////////////////////////////////////////////////////////////////////////////
//
// load_file
//
// The load_file policy opens a given file and returns the wrapped
// istreambuf_iterators.
//
///////////////////////////////////////////////////////////////////////////////
struct load_file {
template <typename IterContextT>
class inner {
public:
~inner() { if (instream.is_open()) instream.close(); }
template <typename PositionT>
static
void init_iterators(IterContextT &iter_ctx,
PositionT const &act_pos)
{
typedef typename IterContextT::iterator_type iterator_type;
iter_ctx.instream.open(iter_ctx.filename.c_str());
if (!iter_ctx.instream.is_open()) {
BOOST_WAVE_THROW(preprocess_exception, bad_include_file,
iter_ctx.filename, act_pos);
}
iter_ctx.instream.unsetf(std::ios::skipws);
using boost::spirit::make_multi_pass;
iter_ctx.first = iterator_type(
make_multi_pass(std::istreambuf_iterator<char>(
iter_ctx.instream.rdbuf())),
make_multi_pass(std::istreambuf_iterator<char>()),
PositionT(iter_ctx.filename), iter_ctx.language);
iter_ctx.last = iterator_type();
}
private:
std::ifstream instream;
};
};
} // namespace iterattion_context_policies
///////////////////////////////////////////////////////////////////////////////
//
template <typename IteratorT>
struct base_iteration_context {
public:
base_iteration_context(BOOST_WAVE_STRINGTYPE const &fname)
: real_filename(fname), filename(fname), line(1), emitted_lines(1)
{}
base_iteration_context(IteratorT const &first_, IteratorT const &last_,
BOOST_WAVE_STRINGTYPE const &fname)
: first(first_), last(last_), real_filename(fname), filename(fname),
line(1), emitted_lines(1)
{}
// the actual input stream
IteratorT first; // actual input stream position
IteratorT last; // end of input stream
BOOST_WAVE_STRINGTYPE real_filename; // real name of the current file
BOOST_WAVE_STRINGTYPE filename; // actual processed file
int line; // line counter of underlying stream
int emitted_lines; // count of emitted newlines
};
///////////////////////////////////////////////////////////////////////////////
//
template <
typename IteratorT,
typename InputPolicyT =
iteration_context_policies::load_file_to_string
>
struct iteration_context
: public base_iteration_context<IteratorT>,
public InputPolicyT::template
inner<iteration_context<IteratorT, InputPolicyT> >
{
typedef IteratorT iterator_type;
typedef typename IteratorT::token_type::position_type position_type;
typedef iteration_context<IteratorT, InputPolicyT> self_type;
iteration_context(BOOST_WAVE_STRINGTYPE const &fname,
position_type const &act_pos,
boost::wave::language_support language_)
: base_iteration_context<IteratorT>(fname),
language(language_)
{
InputPolicyT::template inner<self_type>::init_iterators(*this, act_pos);
}
boost::wave::language_support language;
};
///////////////////////////////////////////////////////////////////////////////
} // namespace wave
} // namespace boost
#endif // !defined(CPP_ITERATION_CONTEXT_HPP_00312288_9DDB_4668_AFE5_25D3994FD095_INCLUDED)

View File

@@ -1,81 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Definition of the abstract lexer interface
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_LEX_INTERFACE_HPP_E83F52A4_90AC_4FBE_A9A7_B65F7F94C497_INCLUDED)
#define CPP_LEX_INTERFACE_HPP_E83F52A4_90AC_4FBE_A9A7_B65F7F94C497_INCLUDED
#include <boost/wave/util/file_position.hpp>
#include <boost/wave/language_support.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace cpplexer {
///////////////////////////////////////////////////////////////////////////////
//
// new_lexer_gen: generates a new instance of the required C++ lexer
//
///////////////////////////////////////////////////////////////////////////////
template <typename TokenT> struct lex_input_interface;
template <
typename IteratorT,
typename PositionT = boost::wave::util::file_position_type
>
struct new_lexer_gen
{
// The NewLexer function allows the opaque generation of a new lexer object.
// It is coupled to the token type to allow to decouple the lexer/token
// configurations at compile time.
static lex_input_interface<lex_token<PositionT> > *
new_lexer(IteratorT const &first, IteratorT const &last,
PositionT const &pos, boost::wave::language_support language);
};
///////////////////////////////////////////////////////////////////////////////
//
// The lex_input_interface decouples the lex_iterator_shim from the actual
// lexer. This is done to allow compile time reduction.
// Thanks to JCAB for having this idea.
//
///////////////////////////////////////////////////////////////////////////////
template <typename TokenT>
struct lex_input_interface
{
typedef typename TokenT::position_type position_type;
virtual TokenT get() = 0;
virtual void set_position(position_type const &pos) = 0;
virtual ~lex_input_interface() {}
// The new_lexer function allows the opaque generation of a new lexer object.
// It is coupled to the token type to allow to distinguish different
// lexer/token configurations at compile time.
template <typename IteratorT>
static lex_input_interface *
new_lexer(IteratorT const &first, IteratorT const &last,
position_type const &pos, boost::wave::language_support language)
{
return new_lexer_gen<IteratorT, position_type>::new_lexer (first, last,
pos, language);
}
};
///////////////////////////////////////////////////////////////////////////////
} // namespace cpplexer
} // namespace wave
} // namespace boost
#endif // !defined(CPP_LEX_INTERFACE_HPP_E83F52A4_90AC_4FBE_A9A7_B65F7F94C497_INCLUDED)

View File

@@ -1,139 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Definition of the lexer iterator
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_LEX_ITERATOR_HPP_AF0C37E3_CBD8_4F33_A225_51CF576FA61F_INCLUDED)
#define CPP_LEX_ITERATOR_HPP_AF0C37E3_CBD8_4F33_A225_51CF576FA61F_INCLUDED
#include <string>
#include <iostream>
#include <boost/assert.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/spirit/iterator/multi_pass.hpp>
#include <boost/wave/util/file_position.hpp>
#include <boost/wave/util/functor_input.hpp>
#include <boost/wave/cpplexer/cpp_lex_interface.hpp>
#include <boost/wave/language_support.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace cpplexer {
namespace impl {
///////////////////////////////////////////////////////////////////////////////
//
// lex_iterator_functor_shim
//
///////////////////////////////////////////////////////////////////////////////
template <typename TokenT>
class lex_iterator_functor_shim
{
public:
template <typename IteratorT>
lex_iterator_functor_shim(IteratorT const &first, IteratorT const &last,
typename TokenT::position_type const &pos,
boost::wave::language_support language)
: functor_ptr(lex_input_interface<TokenT>
::new_lexer(first, last, pos, language))
{}
// interface to the boost::spirit::multi_pass_policies::functor_input policy
typedef TokenT result_type;
static result_type const eof;
result_type operator()()
{
BOOST_ASSERT(0 != functor_ptr.get());
return functor_ptr->get();
}
void set_position(typename TokenT::position_type const &pos)
{
BOOST_ASSERT(0 != functor_ptr.get());
functor_ptr->set_position(pos);
}
private:
boost::shared_ptr<lex_input_interface<TokenT> > functor_ptr;
};
///////////////////////////////////////////////////////////////////////////////
// eof token
template <typename LexT>
typename lex_iterator_functor_shim<LexT>::result_type const
lex_iterator_functor_shim<LexT>::eof;
///////////////////////////////////////////////////////////////////////////////
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
//
// lex_iterator
//
// A generic C++ lexer interface class, which allows to plug in different
// lexer implementations. The interface between the lexer tzpe used and
// the preprocessor component depends on the token type only (template
// parameter TokenT).
// Additionally, the following requirements apply:
//
// - the lexer type should have a function implemented, which returnes
// the next lexed token from the input stream:
// typename TokenT get();
// - at the end of the input stream this function should return the
// eof token equivalent
// - the lexer should implement a constructor taking two iterators
// pointing to the beginning and the end of the input stream,
// a third parameter containing the name of the parsed input file
// and a 4th parameter of the type boost::wave::language_support
// which specifies, which language subset should be supported (C++,
// C99, C++0x etc.).
//
///////////////////////////////////////////////////////////////////////////////
template <typename TokenT>
class lex_iterator
: public boost::spirit::multi_pass<
impl::lex_iterator_functor_shim<TokenT>,
boost::wave::util::functor_input
>
{
typedef impl::lex_iterator_functor_shim<TokenT> input_policy_type;
typedef
boost::spirit::multi_pass<input_policy_type,
boost::wave::util::functor_input>
base_t;
typedef lex_iterator<TokenT> self_type;
public:
typedef TokenT token_type;
lex_iterator()
{}
template <typename IteratorT>
lex_iterator(IteratorT const &first, IteratorT const &last,
typename TokenT::position_type const &pos,
boost::wave::language_support language)
: base_t(input_policy_type(first, last, pos, language))
{}
};
///////////////////////////////////////////////////////////////////////////////
} // namespace cpplexer
} // namespace wave
} // namespace boost
#endif // !defined(CPP_LEX_ITERATOR_HPP_AF0C37E3_CBD8_4F33_A225_51CF576FA61F_INCLUDED)

View File

@@ -1,108 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
A generic C++ lexer token definition
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_TOKEN_HPP_53A13BD2_FBAA_444B_9B8B_FCB225C2BBA8_INCLUDED)
#define CPP_TOKEN_HPP_53A13BD2_FBAA_444B_9B8B_FCB225C2BBA8_INCLUDED
#include <boost/wave/wave_config.hpp>
#include <boost/wave/util/file_position.hpp>
#include <boost/wave/token_ids.hpp>
#include <boost/wave/language_support.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace cpplexer {
///////////////////////////////////////////////////////////////////////////////
// forward declaration of the token type
template <typename PositionT = boost::wave::util::file_position_type>
class lex_token;
///////////////////////////////////////////////////////////////////////////////
//
// lex_token
//
///////////////////////////////////////////////////////////////////////////////
template <typename PositionT>
class lex_token
{
public:
typedef BOOST_WAVE_STRINGTYPE string_type;
typedef PositionT position_type;
lex_token()
: id(T_EOI)
{}
lex_token(token_id id_, string_type const &value_, PositionT const &pos_)
: id(id_), value(value_), pos(pos_)
{}
// accessors
operator token_id() const { return id; }
string_type const &get_value() const { return value; }
position_type const &get_position() const { return pos; }
void set_token_id (token_id id_) { id = id_; }
void set_value (string_type const &newval) { value = newval; }
void set_position (position_type const &pos_) { pos = pos_; }
// debug support
#if BOOST_WAVE_DUMP_PARSE_TREE != 0
// access functions for the tree_to_xml functionality
static int get_token_id(lex_token const &t)
{ return ID_FROM_TOKEN(token_id(t)); }
static string_type get_token_value(lex_token const &t)
{ return t.get_value(); }
#endif
#if defined(BOOST_SPIRIT_DEBUG)
// debug support
void print (std::ostream &stream) const
{
stream << get_token_name(id) << "(";
for (std::size_t i = 0; i < value.size(); ++i) {
switch (value[i]) {
case '\r': stream << "\\r"; break;
case '\n': stream << "\\n"; break;
default:
stream << value[i];
break;
}
}
stream << ")";
}
#endif // defined(BOOST_SPIRIT_DEBUG)
private:
token_id id; // the token id
string_type value; // the text, which was parsed into this token
PositionT pos; // the original file position
};
#if defined(BOOST_SPIRIT_DEBUG)
template <typename PositionT>
inline std::ostream &
operator<< (std::ostream &stream, lex_token<PositionT> const &object)
{
object.print(stream);
return stream;
}
#endif // defined(BOOST_SPIRIT_DEBUG)
///////////////////////////////////////////////////////////////////////////////
} // namespace cpplexer
} // namespace wave
} // namespace boost
#endif // !defined(CPP_TOKEN_HPP_53A13BD2_FBAA_444B_9B8B_FCB225C2BBA8_INCLUDED)

View File

@@ -1,194 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPPLEXER_EXCEPTIONS_HPP_1A09DE1A_6D1F_4091_AF7F_5F13AB0D31AB_INCLUDED)
#define CPPLEXER_EXCEPTIONS_HPP_1A09DE1A_6D1F_4091_AF7F_5F13AB0D31AB_INCLUDED
#include <exception>
#include <string>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/wave/wave_config.hpp>
///////////////////////////////////////////////////////////////////////////////
// helper macro for throwing exceptions
#if !defined(BOOST_WAVE_LEXER_THROW)
#ifdef BOOST_NO_STRINGSTREAM
#include <strstream>
#define BOOST_WAVE_LEXER_THROW(cls, code, msg, line, column, name) \
{ \
using namespace boost::wave; \
std::strstream stream; \
stream << cls::severity_text(cls::code) << ": " \
<< cls::error_text(cls::code); \
if (msg[0] != 0) stream << ": " << msg; \
stream << std::ends; \
std::string throwmsg = stream.str(); stream.freeze(false); \
throw cls(throwmsg.c_str(), cls::code, line, column, name); \
} \
/**/
#else
#include <sstream>
#define BOOST_WAVE_LEXER_THROW(cls, code, msg, line, column, name) \
{ \
using namespace boost::wave; \
std::stringstream stream; \
stream << cls::severity_text(cls::code) << ": " \
<< cls::error_text(cls::code); \
if (msg[0] != 0) stream << ": " << msg; \
stream << std::ends; \
throw cls(stream.str().c_str(), cls::code, line, column, name); \
} \
/**/
#endif // BOOST_NO_STRINGSTREAM
#endif // BOOST_WAVE_LEXER_THROW
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace cpplexer {
///////////////////////////////////////////////////////////////////////////////
// exception severity
namespace util {
enum severity {
severity_remark = 0,
severity_warning,
severity_error,
severity_fatal
};
inline char const *
get_severity(severity level)
{
static char const *severity_text[] =
{
"remark", // severity_remark
"warning", // severity_warning
"error", // severity_error
"fatal error" // severity_fatal
};
BOOST_ASSERT(severity_remark <= level && level <= severity_fatal);
return severity_text[level];
}
}
///////////////////////////////////////////////////////////////////////////////
// cpplexer_exception, the base class for all specific C++ lexer exceptions
class cpplexer_exception
: public std::exception
{
public:
cpplexer_exception(int line_, int column_, char const *filename_) throw()
: line(line_), column(column_)
{
unsigned int off = 0;
while (off < sizeof(filename) && *filename_)
filename[off++] = *filename_++;
filename[off] = 0;
}
~cpplexer_exception() throw() {}
virtual char const *what() const throw() = 0; // to be overloaded
virtual char const *description() const throw() = 0;
int line_no() const throw() { return line; }
int column_no() const throw() { return column; }
char const *file_name() const throw() { return filename; }
protected:
char filename[512];
int line;
int column;
};
///////////////////////////////////////////////////////////////////////////////
// lexing_exception error
class lexing_exception :
public cpplexer_exception
{
public:
enum error_code {
unexpected_error = 0,
universal_char_invalid = 1,
universal_char_base_charset = 2,
universal_char_not_allowed = 3,
generic_lexing_error = 4
};
lexing_exception(char const *what_, error_code code, int line_,
int column_, char const *filename_) throw()
: cpplexer_exception(line_, column_, filename_),
level(severity_level(code))
{
unsigned int off = 0;
while (off < sizeof(buffer) && *what_)
buffer[off++] = *what_++;
buffer[off] = 0;
}
~lexing_exception() throw() {}
virtual char const *what() const throw()
{
return "boost::wave::lexing_exception";
}
virtual char const *description() const throw()
{
return buffer;
}
util::severity get_severity()
{
return level;
}
static char const *error_text(int code)
{
// error texts in this array must appear in the same order as the items in
// the error enum above
static char const *preprocess_exception_errors[] = {
"unexpected error (should not happen)", // unexpected_error
"universal character name specifies an invalid character", // universal_char_invalid
"a universal character name cannot designate a character in the "
"basic character set", // universal_char_base_charset
"this universal character is not allowed in an identifier", // universal_char_not_allowed
"generic lexing error" // generic_lexing_error
};
return preprocess_exception_errors[code];
}
static util::severity severity_level(int code)
{
static util::severity preprocess_exception_severity[] = {
util::severity_fatal, // unexpected_error
util::severity_error, // universal_char_invalid
util::severity_error, // universal_char_base_charset
util::severity_error, // universal_char_not_allowed
util::severity_error // generic_lexing_error
};
return preprocess_exception_severity[code];
}
static char const *severity_text(int code)
{
return util::get_severity(severity_level(code));
}
private:
char buffer[512];
util::severity level;
};
///////////////////////////////////////////////////////////////////////////////
} // namespace cpplexer
} // namespace wave
} // namespace boost
#endif // !defined(CPPLEXER_EXCEPTIONS_HPP_1A09DE1A_6D1F_4091_AF7F_5F13AB0D31AB_INCLUDED)

View File

@@ -1,52 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001 Daniel C. Nuffer.
Copyright (c) 2001-2005 Hartmut Kaiser.
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(AQ_HPP_A21D9145_B643_44C0_81E7_DB346DD67EE1_INCLUDED)
#define AQ_HPP_A21D9145_B643_44C0_81E7_DB346DD67EE1_INCLUDED
#include <cstdlib>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace cpplexer {
namespace re2clex {
typedef std::size_t aq_stdelement;
typedef struct tag_aq_queuetype
{
std::size_t head;
std::size_t tail;
std::size_t size;
std::size_t max_size;
aq_stdelement* queue;
} aq_queuetype;
typedef aq_queuetype* aq_queue;
int aq_enqueue(aq_queue q, aq_stdelement e);
int aq_enqueue_front(aq_queue q, aq_stdelement e);
int aq_serve(aq_queue q, aq_stdelement *e);
int aq_pop(aq_queue q);
#define AQ_EMPTY(q) (q->size == 0)
#define AQ_FULL(q) (q->size == q->max_size)
aq_queue aq_create(void);
void aq_terminate(aq_queue q);
int aq_grow(aq_queue q);
///////////////////////////////////////////////////////////////////////////////
} // namespace re2clex
} // namespace cpplexer
} // namespace wave
} // namespace boost
#endif // !defined(AQ_HPP_A21D9145_B643_44C0_81E7_DB346DD67EE1_INCLUDED)

View File

@@ -1,34 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Re2C based C++ lexer
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_RE_HPP_B76C4F5E_63E9_4B8A_9975_EC32FA6BF027_INCLUDED)
#define CPP_RE_HPP_B76C4F5E_63E9_4B8A_9975_EC32FA6BF027_INCLUDED
#include <boost/wave/token_ids.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace cpplexer {
namespace re2clex {
///////////////////////////////////////////////////////////////////////////////
// The scanner function to call whenever a new token is requested
boost::wave::token_id scan(Scanner *s);
///////////////////////////////////////////////////////////////////////////////
} // namespace re2clex
} // namespace cpplexer
} // namespace wave
} // namespace boost
#endif // !defined(CPP_RE_HPP_B76C4F5E_63E9_4B8A_9975_EC32FA6BF027_INCLUDED)

View File

@@ -1,307 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Re2C based C++ lexer
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_RE2C_LEXER_HPP_B81A2629_D5B1_4944_A97D_60254182B9A8_INCLUDED)
#define CPP_RE2C_LEXER_HPP_B81A2629_D5B1_4944_A97D_60254182B9A8_INCLUDED
#include <string>
#include <cstdio>
#include <cstdarg>
#if defined(BOOST_SPIRIT_DEBUG)
#include <iostream>
#endif // defined(BOOST_SPIRIT_DEBUG)
#include <boost/concept_check.hpp>
#include <boost/assert.hpp>
#include <boost/spirit/core.hpp>
#include <boost/wave/wave_config.hpp>
#include <boost/wave/language_support.hpp>
#include <boost/wave/token_ids.hpp>
#include <boost/wave/util/file_position.hpp>
#include <boost/wave/cpplexer/validate_universal_char.hpp>
#include <boost/wave/cpplexer/cpplexer_exceptions.hpp>
#include <boost/wave/cpplexer/token_cache.hpp>
#include <boost/wave/cpplexer/cpp_lex_token.hpp>
#include <boost/wave/cpplexer/cpp_lex_interface.hpp>
#include <boost/wave/cpplexer/re2clex/scanner.hpp>
#include <boost/wave/cpplexer/re2clex/cpp.re.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace cpplexer {
namespace re2clex {
///////////////////////////////////////////////////////////////////////////////
//
// encapsulation of the re2c based cpp lexer
//
///////////////////////////////////////////////////////////////////////////////
template <typename IteratorT, typename PositionT = boost::wave::util::file_position_type>
class lexer
{
public:
typedef char char_t;
typedef Scanner base_t;
typedef lex_token<PositionT> token_type;
typedef typename token_type::string_type string_type;
lexer(IteratorT const &first, IteratorT const &last,
PositionT const &pos, boost::wave::language_support language);
~lexer();
lex_token<PositionT> get();
void set_position(PositionT const &pos)
{
filename = pos.get_file();
scanner.line = pos.get_line();
scanner.file_name = filename.c_str();
}
// error reporting from the re2c generated lexer
static int report_error(Scanner *s, char *, ...);
private:
static char const *tok_names[];
Scanner scanner;
string_type filename;
string_type value;
bool at_eof;
static token_cache<string_type> const cache;
};
///////////////////////////////////////////////////////////////////////////////
// initialize cpp lexer
template <typename IteratorT, typename PositionT>
inline
lexer<IteratorT, PositionT>::lexer(IteratorT const &first,
IteratorT const &last, PositionT const &pos,
boost::wave::language_support language)
: filename(pos.get_file()), at_eof(false)
{
memset(&scanner, '\0', sizeof(Scanner));
scanner.fd = -1;
scanner.eol_offsets = aq_create();
scanner.first = scanner.act = (uchar *)&(*first);
scanner.last = scanner.first + std::distance(first, last);
scanner.line = 1; // start with line_no 1
scanner.error_proc = report_error;
scanner.file_name = filename.c_str();
#if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
scanner.enable_ms_extensions = 1;
#else
scanner.enable_ms_extensions = 0;
#endif
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
scanner.act_in_c99_mode = boost::wave::need_c99(language);
#endif
boost::ignore_unused_variable_warning(language);
}
template <typename IteratorT, typename PositionT>
inline
lexer<IteratorT, PositionT>::~lexer()
{
aq_terminate(scanner.eol_offsets);
free(scanner.bot);
}
///////////////////////////////////////////////////////////////////////////////
// get the next token from the input stream
template <typename IteratorT, typename PositionT>
inline lex_token<PositionT>
lexer<IteratorT, PositionT>::get()
{
if (at_eof)
return lex_token<PositionT>(); // return T_EOI
token_id id = token_id(scan(&scanner));
switch (id) {
case T_IDENTIFIER:
// test identifier characters for validity (throws if invalid chars found)
value = string_type((char const *)scanner.tok, scanner.cur-scanner.tok);
impl::validate_identifier_name(value, scanner.line, -1, filename);
break;
case T_STRINGLIT:
case T_CHARLIT:
// test literal characters for validity (throws if invalid chars found)
value = string_type((char const *)scanner.tok, scanner.cur-scanner.tok);
impl::validate_literal(value, scanner.line, -1, filename);
break;
#if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
case T_PP_HHEADER:
case T_PP_QHEADER:
case T_PP_INCLUDE:
// convert to the corresponding ..._next token, if appropriate
value = string_type((char const *)scanner.tok, scanner.cur-scanner.tok);
if (string_type::npos != value.find("include_"))
id = token_id(id | AltTokenType);
break;
#endif
case T_OCTALINT:
case T_DECIMALINT:
case T_HEXAINT:
case T_INTLIT:
case T_FLOATLIT:
case T_FIXEDPOINTLIT:
case T_CCOMMENT:
case T_CPPCOMMENT:
case T_SPACE:
case T_SPACE2:
case T_ANY:
value = string_type((char const *)scanner.tok, scanner.cur-scanner.tok);
break;
case T_EOF:
// T_EOF is returned as a valid token, the next call will return T_EOI,
// i.e. the actual end of input
at_eof = true;
break;
default:
if (CATEGORY_FROM_TOKEN(id) != EXTCATEGORY_FROM_TOKEN(id) ||
IS_CATEGORY(id, UnknownTokenType))
{
value = string_type((char const *)scanner.tok, scanner.cur-scanner.tok);
}
else {
value = cache.get_token_value(id);
}
break;
}
return lex_token<PositionT>(id, value,
PositionT(filename, scanner.line, -1));
}
template <typename IteratorT, typename PositionT>
inline int
lexer<IteratorT, PositionT>::report_error(Scanner *s, char *msg, ...)
{
BOOST_ASSERT(0 != s);
BOOST_ASSERT(0 != msg);
using namespace std; // some system have vsprintf in namespace std
char buffer[200]; // should be large enough
va_list params;
va_start(params, msg);
vsprintf(buffer, msg, params);
va_end(params);
BOOST_WAVE_LEXER_THROW(lexing_exception, generic_lexing_error, buffer, s->line, -1,
s->file_name);
return 0; // unreachable code;
}
///////////////////////////////////////////////////////////////////////////////
//
// lex_functor
//
///////////////////////////////////////////////////////////////////////////////
template <typename IteratorT, typename PositionT = boost::wave::util::file_position_type>
class lex_functor
: public lex_input_interface<typename lexer<IteratorT, PositionT>::token_type>
{
public:
typedef typename lexer<IteratorT, PositionT>::token_type token_type;
lex_functor(IteratorT const &first, IteratorT const &last,
PositionT const &pos, boost::wave::language_support language)
: lexer(first, last, pos, language)
{}
virtual ~lex_functor() {}
// get the next token from the input stream
token_type get() { return lexer.get(); }
void set_position(PositionT const &pos)
{ lexer.set_position(pos); }
private:
lexer<IteratorT, PositionT> lexer;
};
///////////////////////////////////////////////////////////////////////////////
template <typename IteratorT, typename PositionT>
token_cache<typename lexer<IteratorT, PositionT>::string_type> const
lexer<IteratorT, PositionT>::cache =
token_cache<typename lexer<IteratorT, PositionT>::string_type>();
} // namespace re2clex
///////////////////////////////////////////////////////////////////////////////
//
// The new_lexer_gen<>::new_lexer function (declared in cpp_lex_interface.hpp)
// should be defined inline, if the lex_functor shouldn't be instantiated
// separately from the lex_iterator.
//
// Separate (explicit) instantiation helps to reduce compilation time.
//
///////////////////////////////////////////////////////////////////////////////
#if BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION != 0
#define BOOST_WAVE_RE2C_NEW_LEXER_INLINE
#else
#define BOOST_WAVE_RE2C_NEW_LEXER_INLINE inline
#endif
///////////////////////////////////////////////////////////////////////////////
//
// The 'new_lexer' function allows the opaque generation of a new lexer object.
// It is coupled to the iterator type to allow to decouple the lexer/iterator
// configurations at compile time.
//
// This function is declared inside the cpp_slex_token.hpp file, which is
// referenced by the source file calling the lexer and the source file, which
// instantiates the lex_functor. But is is defined here, so it will be
// instantiated only while compiling the source file, which instantiates the
// lex_functor. While the cpp_re2c_token.hpp file may be included everywhere,
// this file (cpp_re2c_lexer.hpp) should be included only once. This allows
// to decouple the lexer interface from the lexer implementation and reduces
// compilation time.
//
///////////////////////////////////////////////////////////////////////////////
template <typename IteratorT, typename PositionT>
BOOST_WAVE_RE2C_NEW_LEXER_INLINE
lex_input_interface<lex_token<PositionT> > *
new_lexer_gen<IteratorT, PositionT>::new_lexer(IteratorT const &first,
IteratorT const &last, PositionT const &pos,
boost::wave::language_support language)
{
return new re2clex::lex_functor<IteratorT, PositionT>(first, last, pos,
language);
}
#undef BOOST_WAVE_RE2C_NEW_LEXER_INLINE
///////////////////////////////////////////////////////////////////////////////
} // namespace cpplexer
} // namespace wave
} // namespace boost
#endif // !defined(CPP_RE2C_LEXER_HPP_B81A2629_D5B1_4944_A97D_60254182B9A8_INCLUDED)

View File

@@ -1,58 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001 Daniel C. Nuffer.
Copyright (c) 2001-2005 Hartmut Kaiser.
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(SCANNER_HPP_F4FB01EB_E75C_4537_A146_D34B9895EF37_INCLUDED)
#define SCANNER_HPP_F4FB01EB_E75C_4537_A146_D34B9895EF37_INCLUDED
#include <boost/wave/cpplexer/re2clex/aq.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace cpplexer {
namespace re2clex {
struct Scanner;
typedef unsigned char uchar;
typedef int (* ReportErrorProc)(struct Scanner *, char *, ...);
typedef struct Scanner {
int fd; /* file descriptor */
uchar* first; /* start of input buffer (if fd == -1) */
uchar* act; /* act position of input buffer (if fd == -1) */
uchar* last; /* end (one past last char) of input buffer (if fd == -1) */
uchar* bot; /* beginning of the current buffer */
uchar* top; /* top of the current buffer */
uchar* eof; /* when we read in the last buffer, will point 1 past the
end of the file, otherwise 0 */
uchar* tok; /* points to the beginning of the current token */
uchar* ptr; /* used for YYMARKER - saves backtracking info */
uchar* cur; /* saves the cursor (maybe is redundant with tok?) */
uchar* lim; /* used for YYLIMIT - points to the end of the buffer */
/* (lim == top) except for the last buffer, it points to
the end of the input (lim == eof - 1) */
unsigned int line; /* current line being lexed */
ReportErrorProc error_proc; /* if != 0 this function is called to
report an error */
char const *file_name; /* name of the lexed file */
aq_queue eol_offsets;
int enable_ms_extensions; /* enable MS extensions */
int act_in_c99_mode; /* lexer works in C99 mode */
int act_in_cpp0x_mode; /* lexer works in C++0x mode */
} Scanner;
///////////////////////////////////////////////////////////////////////////////
} // namespace re2clex
} // namespace cpplexer
} // namespace wave
} // namespace boost
#endif // !defined(SCANNER_HPP_F4FB01EB_E75C_4537_A146_D34B9895EF37_INCLUDED)

View File

@@ -1,50 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(TOKEN_CACHE_HPP_4D2320B7_1D56_4113_A114_397E70FA438C_INCLUDED)
#define TOKEN_CACHE_HPP_4D2320B7_1D56_4113_A114_397E70FA438C_INCLUDED
#include <boost/wave/token_ids.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace cpplexer {
template <typename StringT>
class token_cache
{
public:
token_cache()
: cache(T_LAST_TOKEN - T_FIRST_TOKEN)
{
typename std::vector<StringT>::iterator it = cache.begin();
typename std::vector<StringT>::iterator end = cache.end();
for (unsigned int i = T_FIRST_TOKEN; i < T_LAST_TOKEN; ++i, ++it)
{
*it = StringT(boost::wave::get_token_value(token_id(i)));
}
}
StringT const &get_token_value(token_id id) const
{
return cache[BASEID_FROM_TOKEN(id) - T_FIRST_TOKEN];
}
private:
std::vector<StringT> cache;
};
///////////////////////////////////////////////////////////////////////////////
} // namespace cpplexer
} // namespace wave
} // namespace boost
#endif // !defined(TOKEN_CACHE_HPP_4D2320B7_1D56_4113_A114_397E70FA438C_INCLUDED)

View File

@@ -1,314 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Grammar for universal character validation (see C++ standard: Annex E)
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(VALIDATE_UNIVERSAL_CHAR_HPP_55F1B811_CD76_4C72_8344_CBC69CF3B339_INCLUDED)
#define VALIDATE_UNIVERSAL_CHAR_HPP_55F1B811_CD76_4C72_8344_CBC69CF3B339_INCLUDED
#include <boost/spirit/core.hpp>
#include <boost/wave/util/file_position.hpp>
#include <boost/wave/cpplexer/cpplexer_exceptions.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace cpplexer {
namespace impl {
enum universal_char_type {
universal_char_type_valid = 0,
universal_char_type_invalid = 1,
universal_char_type_base_charset = 2,
universal_char_type_not_allowed_for_identifiers = 3,
};
namespace {
///////////////////////////////////////////////////////////////////////////
//
// is_range is a helper function for the classification by brute force
// below
//
///////////////////////////////////////////////////////////////////////////
inline bool
in_range(unsigned long ch, unsigned long l, unsigned long u)
{
return (l <= ch && ch <= u);
}
}
///////////////////////////////////////////////////////////////////////////////
//
// classify_universal_char
//
// This function classifies an universal character value into 4 subranges:
// universal_char_type_valid
// the universal character value is valid for identifiers
// universal_char_type_invalid
// the universal character value is not valid for its usage inside
// identifiers (see C++ Standard: 2.2.2 [lex.charset])
// universal_char_type_base_charset
// the universal character value designates a character from the base
// character set
// universal_char_type_not_allowed_for_identifiers
// the universal character value is not allowed in an identifier
//
// Implementation note:
// This classification isn't implemented very effectively here. This
// function should be rewritten with some range run matching algorithm.
//
///////////////////////////////////////////////////////////////////////////////
inline universal_char_type
classify_universal_char (unsigned long ch)
{
// test for invalid characters
if (ch <= 0x0020 || in_range(ch, 0x007f, 0x009f))
return universal_char_type_invalid;
// test for characters in the range of the base character set
if (in_range(ch, 0x0021, 0x005f) || in_range(ch, 0x0061, 0x007e))
return universal_char_type_base_charset;
// test for additional valid character values (see C++ Standard: Annex E)
if (in_range(ch, 0x00c0, 0x00d6) || in_range(ch, 0x00d8, 0x00f6) ||
in_range(ch, 0x00f8, 0x01f5) || in_range(ch, 0x01fa, 0x0217) ||
in_range(ch, 0x0250, 0x02a8) || in_range(ch, 0x1e00, 0x1e9a) ||
in_range(ch, 0x1ea0, 0x1ef9))
{
return universal_char_type_valid; // Latin
}
if (0x0384 == ch || in_range(ch, 0x0388, 0x038a) ||
0x038c == ch || in_range(ch, 0x038e, 0x03a1) ||
in_range(ch, 0x03a3, 0x03ce) || in_range(ch, 0x03d0, 0x03d6) ||
0x03da == ch || 0x03dc == ch || 0x03de == ch || 0x03e0 == ch ||
in_range(ch, 0x03e2, 0x03f3) || in_range(ch, 0x1f00, 0x1f15) ||
in_range(ch, 0x1f18, 0x1f1d) || in_range(ch, 0x1f20, 0x1f45) ||
in_range(ch, 0x1f48, 0x1f4d) || in_range(ch, 0x1f50, 0x1f57) ||
0x1f59 == ch || 0x1f5b == ch || 0x1f5d == ch ||
in_range(ch, 0x1f5f, 0x1f7d) || in_range(ch, 0x1f80, 0x1fb4) ||
in_range(ch, 0x1fb6, 0x1fbc) || in_range(ch, 0x1fc2, 0x1fc4) ||
in_range(ch, 0x1fc6, 0x1fcc) || in_range(ch, 0x1fd0, 0x1fd3) ||
in_range(ch, 0x1fd6, 0x1fdb) || in_range(ch, 0x1fe0, 0x1fec) ||
in_range(ch, 0x1ff2, 0x1ff4) || in_range(ch, 0x1ff6, 0x1ffc))
{
return universal_char_type_valid; // Greek
}
if (in_range(ch, 0x0401, 0x040d) || in_range(ch, 0x040f, 0x044f) ||
in_range(ch, 0x0451, 0x045c) || in_range(ch, 0x045e, 0x0481) ||
in_range(ch, 0x0490, 0x04c4) || in_range(ch, 0x04c7, 0x04c8) ||
in_range(ch, 0x04cb, 0x04cc) || in_range(ch, 0x04d0, 0x04eb) ||
in_range(ch, 0x04ee, 0x04f5) || in_range(ch, 0x04f8, 0x04f9))
{
return universal_char_type_valid; // Cyrillic
}
if (in_range(ch, 0x0531, 0x0556) || in_range(ch, 0x0561, 0x0587))
return universal_char_type_valid; // Armenian
if (in_range(ch, 0x05d0, 0x05ea) || in_range(ch, 0x05f0, 0x05f4))
return universal_char_type_valid; // Hebrew
if (in_range(ch, 0x0621, 0x063a) || in_range(ch, 0x0640, 0x0652) ||
in_range(ch, 0x0670, 0x06b7) || in_range(ch, 0x06ba, 0x06be) ||
in_range(ch, 0x06c0, 0x06ce) || in_range(ch, 0x06e5, 0x06e7))
{
return universal_char_type_valid; // Arabic
}
if (in_range(ch, 0x0905, 0x0939) || in_range(ch, 0x0958, 0x0962))
return universal_char_type_valid; // Devanagari
if (in_range(ch, 0x0985, 0x098c) || in_range(ch, 0x098f, 0x0990) ||
in_range(ch, 0x0993, 0x09a8) || in_range(ch, 0x09aa, 0x09b0) ||
0x09b2 == ch || in_range(ch, 0x09b6, 0x09b9) ||
in_range(ch, 0x09dc, 0x09dd) || in_range(ch, 0x09df, 0x09e1) ||
in_range(ch, 0x09f0, 0x09f1))
{
return universal_char_type_valid; // Bengali
}
if (in_range(ch, 0x0a05, 0x0a0a) || in_range(ch, 0x0a0f, 0x0a10) ||
in_range(ch, 0x0a13, 0x0a28) || in_range(ch, 0x0a2a, 0x0a30) ||
in_range(ch, 0x0a32, 0x0a33) || in_range(ch, 0x0a35, 0x0a36) ||
in_range(ch, 0x0a38, 0x0a39) || in_range(ch, 0x0a59, 0x0a5c) ||
0x0a5e == ch)
{
return universal_char_type_valid; // Gurmukhi
}
if (in_range(ch, 0x0a85, 0x0a8b) || 0x0a8d == ch ||
in_range(ch, 0x0a8f, 0x0a91) || in_range(ch, 0x0a93, 0x0aa8) ||
in_range(ch, 0x0aaa, 0x0ab0) || in_range(ch, 0x0ab2, 0x0ab3) ||
in_range(ch, 0x0ab5, 0x0ab9) || 0x0ae0 == ch)
{
return universal_char_type_valid; // Gujarati
}
if (in_range(ch, 0x0b05, 0x0b0c) || in_range(ch, 0x0b0f, 0x0b10) ||
in_range(ch, 0x0b13, 0x0b28) || in_range(ch, 0x0b2a, 0x0b30) ||
in_range(ch, 0x0b32, 0x0b33) || in_range(ch, 0x0b36, 0x0b39) ||
in_range(ch, 0x0b5c, 0x0b5d) || in_range(ch, 0x0b5f, 0x0b61))
{
return universal_char_type_valid; // Oriya
}
if (in_range(ch, 0x0b85, 0x0b8a) || in_range(ch, 0x0b8e, 0x0b90) ||
in_range(ch, 0x0b92, 0x0b95) || in_range(ch, 0x0b99, 0x0b9a) ||
0x0b9c == ch || in_range(ch, 0x0b9e, 0x0b9f) ||
in_range(ch, 0x0ba3, 0x0ba4) || in_range(ch, 0x0ba8, 0x0baa) ||
in_range(ch, 0x0bae, 0x0bb5) || in_range(ch, 0x0bb7, 0x0bb9))
{
return universal_char_type_valid; // Tamil
}
if (in_range(ch, 0x0c05, 0x0c0c) || in_range(ch, 0x0c0e, 0x0c10) ||
in_range(ch, 0x0c12, 0x0c28) || in_range(ch, 0x0c2a, 0x0c33) ||
in_range(ch, 0x0c35, 0x0c39) || in_range(ch, 0x0c60, 0x0c61))
{
return universal_char_type_valid; // Telugu
}
if (in_range(ch, 0x0c85, 0x0c8c) || in_range(ch, 0x0c8e, 0x0c90) ||
in_range(ch, 0x0c92, 0x0ca8) || in_range(ch, 0x0caa, 0x0cb3) ||
in_range(ch, 0x0cb5, 0x0cb9) || in_range(ch, 0x0ce0, 0x0ce1))
{
return universal_char_type_valid; // Kannada
}
if (in_range(ch, 0x0d05, 0x0d0c) || in_range(ch, 0x0d0e, 0x0d10) ||
in_range(ch, 0x0d12, 0x0d28) || in_range(ch, 0x0d2a, 0x0d39) ||
in_range(ch, 0x0d60, 0x0d61))
{
return universal_char_type_valid; // Malayalam
}
if (in_range(ch, 0x0e01, 0x0e30) || in_range(ch, 0x0e32, 0x0e33) ||
in_range(ch, 0x0e40, 0x0e46) || in_range(ch, 0x0e4f, 0x0e5b))
{
return universal_char_type_valid; // Thai
}
return universal_char_type_not_allowed_for_identifiers;
}
///////////////////////////////////////////////////////////////////////////////
//
// validate_identifier_name
//
// The validate_identifier_name function tests a given identifier name for
// its validity in regard to eventually contained universal characters.
// These should be in valid ranges (see the function
// classify_universal_char above).
//
// If the identifier name contains invalid or not allowed universal
// characters a corresponding lexing_exception is thrown.
//
///////////////////////////////////////////////////////////////////////////////
template <typename StringT>
inline void
validate_identifier_name (StringT const &name, int line, int column,
StringT const &file_name)
{
using namespace std; // some systems have strtoul in namespace std::
typename StringT::size_type pos = name.find_first_of('\\');
while (StringT::npos != pos) {
// the identifier name contains a backslash (must be universal char)
BOOST_SPIRIT_ASSERT('u' == name[pos+1] || 'U' == name[pos+1]);
StringT uchar_val(name.substr(pos+2, ('u' == name[pos+1]) ? 4 : 8));
universal_char_type type =
classify_universal_char(strtoul(uchar_val.c_str(), 0, 16));
if (universal_char_type_valid != type) {
// an invalid char was found, so throw an exception
StringT error_uchar(name.substr(pos, ('u' == name[pos+1]) ? 6 : 10));
if (universal_char_type_invalid == type) {
BOOST_WAVE_LEXER_THROW(lexing_exception, universal_char_invalid,
error_uchar, line, column, file_name.c_str());
}
else if (universal_char_type_base_charset == type) {
BOOST_WAVE_LEXER_THROW(lexing_exception, universal_char_base_charset,
error_uchar, line, column, file_name.c_str());
}
else {
BOOST_WAVE_LEXER_THROW(lexing_exception, universal_char_not_allowed,
error_uchar, line, column, file_name.c_str());
}
}
// find next universal char (if appropriate)
pos = name.find_first_of('\\', pos+2);
}
}
///////////////////////////////////////////////////////////////////////////////
//
// validate_literal
//
// The validate_literal function tests a given string or character literal
// for its validity in regard to eventually contained universal
// characters. These should be in valid ranges (see the function
// classify_universal_char above).
//
// If the string or character literal contains invalid or not allowed
// universal characters a corresponding lexing_exception is thrown.
//
///////////////////////////////////////////////////////////////////////////////
template <typename StringT>
inline void
validate_literal (StringT const &name, int line, int column,
StringT const &file_name)
{
using namespace std; // some systems have strtoul in namespace std::
typename StringT::size_type pos = name.find_first_of('\\');
while (StringT::npos != pos) {
// the literal contains a backslash (may be universal char)
if ('u' == name[pos+1] || 'U' == name[pos+1]) {
StringT uchar_val(name.substr(pos+2, ('u' == name[pos+1]) ? 4 : 8));
universal_char_type type =
classify_universal_char(strtoul(uchar_val.c_str(), 0, 16));
if (universal_char_type_valid != type &&
universal_char_type_not_allowed_for_identifiers != type)
{
// an invalid char was found, so throw an exception
StringT error_uchar(name.substr(pos, ('u' == name[pos+1]) ? 6 : 10));
if (universal_char_type_invalid == type) {
BOOST_WAVE_LEXER_THROW(lexing_exception, universal_char_invalid,
error_uchar, line, column, file_name.c_str());
}
else {
BOOST_WAVE_LEXER_THROW(lexing_exception, universal_char_base_charset,
error_uchar, line, column, file_name.c_str());
}
}
}
// find next universal char (if appropriate)
pos = name.find_first_of('\\', pos+2);
}
}
///////////////////////////////////////////////////////////////////////////////
} // namespace impl
} // namespace cpplexer
} // namespace wave
} // namespace boost
#endif // !defined(VALIDATE_UNIVERSAL_CHAR_HPP_55F1B811_CD76_4C72_8344_CBC69CF3B339_INCLUDED)

View File

@@ -1,229 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_CHLIT_GRAMMAR_HPP_9527D349_6592_449A_A409_42A001E6C64C_INCLUDED)
#define CPP_CHLIT_GRAMMAR_HPP_9527D349_6592_449A_A409_42A001E6C64C_INCLUDED
#include <boost/spirit/core.hpp>
#include <boost/spirit/attribute/closure.hpp>
#include <boost/spirit/phoenix/operators.hpp>
#include <boost/spirit/phoenix/primitives.hpp>
#include <boost/spirit/phoenix/statements.hpp>
#include <boost/spirit/phoenix/functions.hpp>
#include <boost/wave/wave_config.hpp>
#include <boost/wave/cpp_exceptions.hpp>
#include <boost/wave/grammars/cpp_literal_grammar_gen.hpp>
///////////////////////////////////////////////////////////////////////////////
//
// Reusable grammar to parse a C++ style character literal
//
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace grammars {
namespace closures {
struct chlit_closure
: boost::spirit::closure<chlit_closure, unsigned int>
{
member1 value;
};
}
namespace impl {
///////////////////////////////////////////////////////////////////////////////
//
// compose a multibyte character literal
//
///////////////////////////////////////////////////////////////////////////////
struct compose_character_literal {
template <typename ResultT, typename ArgT>
struct result {
typedef unsigned int type;
};
unsigned int
operator()(unsigned int res, unsigned int character) const
{
unsigned int retval = (res << 8) | (character & 0xff);
return retval;
}
};
phoenix::function<compose_character_literal> const compose;
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// define, whether the rule's should generate some debug output
#define TRACE_CHLIT_GRAMMAR \
bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CHLIT_GRAMMAR) \
/**/
struct chlit_grammar :
public boost::spirit::grammar<chlit_grammar,
closures::chlit_closure::context_t>
{
chlit_grammar()
{
BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "chlit_grammar",
TRACE_CHLIT_GRAMMAR);
}
template <typename ScannerT>
struct definition
{
typedef
boost::spirit::rule<ScannerT, closures::chlit_closure::context_t>
rule_t;
rule_t ch_lit;
definition(chlit_grammar const &self)
{
using namespace boost::spirit;
using namespace phoenix;
ch_lit
= !ch_p('L')
>> ch_p('\'')[self.value = val(0)]
>> +( (
ch_p('\\')
>> ( ch_p('a') // BEL
[
self.value = impl::compose(self.value, val(0x07))
]
| ch_p('b') // BS
[
self.value = impl::compose(self.value, val(0x08))
]
| ch_p('t') // HT
[
self.value = impl::compose(self.value, val(0x09))
]
| ch_p('n') // NL
[
self.value = impl::compose(self.value, val(0x0a))
]
| ch_p('v') // VT
[
self.value = impl::compose(self.value, val(0x0b))
]
| ch_p('f') // FF
[
self.value = impl::compose(self.value, val(0x0c))
]
| ch_p('r') // CR
[
self.value = impl::compose(self.value, val(0x0d))
]
| ch_p('?')
[
self.value = impl::compose(self.value, val('?'))
]
| ch_p('\'')
[
self.value = impl::compose(self.value, val('\''))
]
| ch_p('\"')
[
self.value = impl::compose(self.value, val('\"'))
]
| ch_p('\\')
[
self.value = impl::compose(self.value, val('\\'))
]
| ch_p('x')
>> uint_parser<unsigned int, 16, 2, 2>()
[
self.value = impl::compose(self.value, arg1)
]
| ch_p('u')
>> uint_parser<unsigned int, 16, 4, 4>()
[
self.value = impl::compose(self.value, arg1)
]
| ch_p('U')
>> uint_parser<unsigned int, 16, 8, 8>()
[
self.value = impl::compose(self.value, arg1)
]
| uint_parser<unsigned int, 8, 1, 3>()
[
self.value = impl::compose(self.value, arg1)
]
)
)
| ~eps_p(ch_p('\'')) >> anychar_p
[
self.value = impl::compose(self.value, arg1)
]
)
>> ch_p('\'')
;
BOOST_SPIRIT_DEBUG_TRACE_RULE(ch_lit, TRACE_CHLIT_GRAMMAR);
}
// start rule of this grammar
rule_t const& start() const
{ return ch_lit; }
};
};
#undef TRACE_CHLIT_GRAMMAR
///////////////////////////////////////////////////////////////////////////////
//
// The following function is defined here, to allow the separation of
// the compilation of the intlit_grammap from the function using it.
//
///////////////////////////////////////////////////////////////////////////////
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
#define BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE
#else
#define BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE inline
#endif
template <typename TokenT>
BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE
unsigned int
chlit_grammar_gen<TokenT>::evaluate(TokenT const &token)
{
using namespace boost::spirit;
static chlit_grammar g;
unsigned int result = 0;
typename TokenT::string_type const &token_val = token.get_value();
parse_info<typename TokenT::string_type::const_iterator> hit =
parse(token_val.begin(), token_val.end(), g[spirit_assign_actor(result)]);
if (!hit.hit) {
BOOST_WAVE_THROW(preprocess_exception, ill_formed_expression,
token_val, token.get_position());
}
return result;
}
#undef BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE
///////////////////////////////////////////////////////////////////////////////
} // namespace grammars
} // namespace wave
} // namespace boost
#endif // !defined(CPP_CHLIT_GRAMMAR_HPP_9527D349_6592_449A_A409_42A001E6C64C_INCLUDED)

View File

@@ -1,172 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_DEFINED_GRAMMAR_HPP_F48287B2_DC67_40A8_B4A1_800EFBD67869_INCLUDED)
#define CPP_DEFINED_GRAMMAR_HPP_F48287B2_DC67_40A8_B4A1_800EFBD67869_INCLUDED
#include <boost/assert.hpp>
#include <boost/spirit/core.hpp>
#include <boost/spirit/attribute/closure.hpp>
#if SPIRIT_VERSION >= 0x1700
#include <boost/spirit/actor/assign_actor.hpp>
#include <boost/spirit/actor/push_back_actor.hpp>
#endif // SPIRIT_VERSION >= 0x1700
#include <boost/wave/wave_config.hpp>
#include <boost/wave/token_ids.hpp>
#include <boost/wave/util/pattern_parser.hpp>
#include <boost/wave/grammars/cpp_defined_grammar_gen.hpp>
#if !defined(spirit_append_actor)
#if SPIRIT_VERSION >= 0x1700
#define spirit_append_actor(actor) boost::spirit::push_back_a(actor)
#define spirit_assign_actor(actor) boost::spirit::assign_a(actor)
#else
#define spirit_append_actor(actor) boost::spirit::append(actor)
#define spirit_assign_actor(actor) boost::spirit::assign(actor)
#endif // SPIRIT_VERSION >= 0x1700
#endif // !defined(spirit_append_actor)
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace grammars {
///////////////////////////////////////////////////////////////////////////////
// define, whether the rule's should generate some debug output
#define TRACE_CPP_DEFINED_GRAMMAR \
bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_DEFINED_GRAMMAR) \
/**/
template <typename ContainerT>
struct defined_grammar :
public boost::spirit::grammar<defined_grammar<ContainerT> >
{
defined_grammar(ContainerT &result_seq_)
: result_seq(result_seq_)
{
BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "defined_grammar",
TRACE_CPP_DEFINED_GRAMMAR);
}
template <typename ScannerT>
struct definition
{
typedef boost::spirit::rule<ScannerT> rule_t;
rule_t defined_op;
rule_t identifier;
definition(defined_grammar const &self)
{
using namespace boost::spirit;
using namespace boost::wave;
using namespace boost::wave::util;
defined_op // parens not required, see C++ standard 16.1.1
= ch_p(T_IDENTIFIER) // token contains 'defined'
>> (
( ch_p(T_LEFTPAREN)
>> identifier
>> ch_p(T_RIGHTPAREN)
)
| identifier
)
;
identifier
= ch_p(T_IDENTIFIER)
[
spirit_append_actor(self.result_seq)
]
| pattern_p(KeywordTokenType, TokenTypeMask)
[
spirit_append_actor(self.result_seq)
]
;
BOOST_SPIRIT_DEBUG_TRACE_RULE(defined_op, TRACE_CPP_DEFINED_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(identifier, TRACE_CPP_DEFINED_GRAMMAR);
}
// start rule of this grammar
rule_t const& start() const
{ return defined_op; }
};
ContainerT &result_seq;
};
///////////////////////////////////////////////////////////////////////////////
#undef TRACE_CPP_DEFINED_GRAMMAR
///////////////////////////////////////////////////////////////////////////////
//
// The following parse function is defined here, to allow the separation of
// the compilation of the defined_grammar from the function
// using it.
//
///////////////////////////////////////////////////////////////////////////////
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
#define BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
#else
#define BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE inline
#endif
// The parse_operator_define function is instantiated manually twice to
// simplify the explicit specialization of this template. This way the user
// has only to specify one template parameter (the lexer type) to correctly
// formulate the required explicit specialization.
// This results in no code overhead, because otherwise the function would be
// generated by the compiler twice anyway.
template <typename LexIteratorT>
BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
boost::spirit::parse_info<
typename defined_grammar_gen<LexIteratorT>::iterator1_t
>
defined_grammar_gen<LexIteratorT>::parse_operator_defined (
iterator1_t const &first, iterator1_t const &last,
token_sequence_type &found_qualified_name)
{
using namespace boost::spirit;
using namespace boost::wave;
defined_grammar<token_sequence_type> g(found_qualified_name);
return boost::spirit::parse (
first, last, g, ch_p(T_SPACE) | ch_p(T_CCOMMENT));
}
template <typename LexIteratorT>
BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
boost::spirit::parse_info<
typename defined_grammar_gen<LexIteratorT>::iterator2_t
>
defined_grammar_gen<LexIteratorT>::parse_operator_defined (
iterator2_t const &first, iterator2_t const &last,
token_sequence_type &found_qualified_name)
{
using namespace boost::spirit;
using namespace boost::wave;
defined_grammar<token_sequence_type> g(found_qualified_name);
return boost::spirit::parse (
first, last, g, ch_p(T_SPACE) | ch_p(T_CCOMMENT));
}
#undef BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
///////////////////////////////////////////////////////////////////////////////
} // namespace grammars
} // namespace wave
} // namespace boost
#endif // !defined(CPP_DEFINED_GRAMMAR_HPP_F48287B2_DC67_40A8_B4A1_800EFBD67869_INCLUDED)

View File

@@ -1,63 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_DEFINED_GRAMMAR_GEN_HPP_825BE9F5_98A3_400D_A97C_AD76B3B08632_INCLUDED)
#define CPP_DEFINED_GRAMMAR_GEN_HPP_825BE9F5_98A3_400D_A97C_AD76B3B08632_INCLUDED
#include <list>
#include <boost/spirit/core/parser.hpp>
#include <boost/pool/pool_alloc.hpp>
#include <boost/wave/util/unput_queue_iterator.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace grammars {
template <typename LexIteratorT>
struct defined_grammar_gen
{
typedef typename LexIteratorT::token_type token_type;
typedef std::list<token_type, boost::fast_pool_allocator<token_type> >
token_sequence_type;
// The parse_operator_define function is instantiated manually twice to
// simplify the explicit specialization of this template. This way the user
// has only to specify one template parameter (the lexer iterator type) to
// correctly formulate the required explicit specialization.
// This results in no code overhead, because otherwise the function would be
// generated by the compiler twice anyway.
typedef boost::wave::util::unput_queue_iterator<
typename token_sequence_type::iterator, token_type, token_sequence_type>
iterator1_t;
typedef boost::wave::util::unput_queue_iterator<
LexIteratorT, token_type, token_sequence_type>
iterator2_t;
// parse the operator defined and return the found qualified name
static boost::spirit::parse_info<iterator1_t>
parse_operator_defined (iterator1_t const &first, iterator1_t const &last,
token_sequence_type &found_qualified_name);
static boost::spirit::parse_info<iterator2_t>
parse_operator_defined (iterator2_t const &first, iterator2_t const &last,
token_sequence_type &found_qualified_name);
};
///////////////////////////////////////////////////////////////////////////////
} // namespace grammars
} // namespace wave
} // namespace boost
#endif // !defined(CPP_DEFINED_GRAMMAR_GEN_HPP_825BE9F5_98A3_400D_A97C_AD76B3B08632_INCLUDED)

View File

@@ -1,710 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_EXPRESSION_GRAMMAR_HPP_099CD1A4_A6C0_44BE_8F24_0B00F5BE5674_INCLUDED)
#define CPP_EXPRESSION_GRAMMAR_HPP_099CD1A4_A6C0_44BE_8F24_0B00F5BE5674_INCLUDED
#include <boost/assert.hpp>
#include <boost/spirit/core.hpp>
#include <boost/spirit/attribute/closure.hpp>
#include <boost/spirit/dynamic/if.hpp>
#if SPIRIT_VERSION >= 0x1700
#include <boost/spirit/actor/assign_actor.hpp>
#include <boost/spirit/actor/push_back_actor.hpp>
#endif // SPIRIT_VERSION >= 0x1700
#include <boost/spirit/phoenix/functions.hpp>
#include <boost/spirit/phoenix/operators.hpp>
#include <boost/spirit/phoenix/primitives.hpp>
#include <boost/spirit/phoenix/statements.hpp>
#include <boost/spirit/phoenix/casts.hpp>
#include <boost/wave/wave_config.hpp>
#include <boost/wave/token_ids.hpp>
#include <boost/wave/cpp_exceptions.hpp>
#include <boost/wave/grammars/cpp_expression_grammar_gen.hpp>
#include <boost/wave/grammars/cpp_literal_grammar_gen.hpp>
#include <boost/wave/grammars/cpp_expression_value.hpp>
#include <boost/wave/util/pattern_parser.hpp>
#include <boost/wave/util/macro_helpers.hpp>
#if !defined(spirit_append_actor)
#if SPIRIT_VERSION >= 0x1700
#define spirit_append_actor(actor) boost::spirit::push_back_a(actor)
#define spirit_assign_actor(actor) boost::spirit::assign_a(actor)
#else
#define spirit_append_actor(actor) boost::spirit::append(actor)
#define spirit_assign_actor(actor) boost::spirit::assign(actor)
#endif // SPIRIT_VERSION >= 0x1700
#endif // !defined(spirit_append_actor)
///////////////////////////////////////////////////////////////////////////////
//
// Encapsulation of the grammar for evaluation of constant preprocessor
// expressions
//
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace grammars {
namespace closures {
///////////////////////////////////////////////////////////////////////////////
//
// define the closure type used throughout the C++ expression grammar
//
// Throughout this grammar all literal tokens are stored into a
// closure_value variables, which converts the types appropriately, where
// required.
//
///////////////////////////////////////////////////////////////////////////////
struct cpp_expr_closure
: boost::spirit::closure<cpp_expr_closure, closure_value>
{
member1 val;
};
} // namespace closures
namespace impl {
///////////////////////////////////////////////////////////////////////////////
//
// convert the given tokenvalue (integer literal) to a unsigned long
//
///////////////////////////////////////////////////////////////////////////////
struct convert_intlit {
template <typename ArgT>
struct result {
typedef boost::wave::grammars::closures::closure_value type;
};
template <typename TokenT>
boost::wave::grammars::closures::closure_value
operator()(TokenT const &token) const
{
typedef boost::wave::grammars::closures::closure_value return_t;
bool is_unsigned = false;
unsigned long ul = intlit_grammar_gen<TokenT>::evaluate(token,
is_unsigned);
return is_unsigned ? return_t(ul) : return_t(static_cast<long>(ul));
}
};
phoenix::function<convert_intlit> const as_intlit;
///////////////////////////////////////////////////////////////////////////////
//
// convert the given tokenvalue (character literal) to a unsigned int
//
///////////////////////////////////////////////////////////////////////////////
struct convert_chlit {
template <typename ArgT>
struct result {
typedef boost::wave::grammars::closures::closure_value type;
};
template <typename TokenT>
boost::wave::grammars::closures::closure_value
operator()(TokenT const &token) const
{
typedef boost::wave::grammars::closures::closure_value return_t;
return return_t(chlit_grammar_gen<TokenT>::evaluate(token));
}
};
phoenix::function<convert_chlit> const as_chlit;
////////////////////////////////////////////////////////////////////////////////
//
// Handle the ?: operator with correct type propagation
//
////////////////////////////////////////////////////////////////////////////////
struct operator_questionmark {
template <typename CondT, typename Arg1T, typename Arg2T>
struct result {
typedef boost::wave::grammars::closures::closure_value type;
};
template <typename CondT, typename Arg1T, typename Arg2T>
boost::wave::grammars::closures::closure_value
operator()(CondT const &cond, Arg1T &val1, Arg2T const &val2) const
{
typedef boost::wave::grammars::closures::closure_value return_t;
return return_t(val1.handle_questionmark(cond, val2));
}
};
phoenix::function<operator_questionmark> const questionmark;
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// define, whether the rule's should generate some debug output
#define TRACE_CPP_EXPR_GRAMMAR \
bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_EXPR_GRAMMAR) \
/**/
struct expression_grammar :
public boost::spirit::grammar<
expression_grammar,
closures::cpp_expr_closure::context_t
>
{
expression_grammar()
{
BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "expression_grammar",
TRACE_CPP_EXPR_GRAMMAR);
}
template <typename ScannerT>
struct definition
{
typedef closures::cpp_expr_closure closure_type;
typedef boost::spirit::rule<ScannerT, closure_type::context_t> rule_t;
typedef boost::spirit::rule<ScannerT> simple_rule_t;
simple_rule_t pp_expression;
rule_t const_exp;
rule_t logical_or_exp, logical_and_exp;
rule_t inclusive_or_exp, exclusive_or_exp, and_exp;
rule_t cmp_equality, cmp_relational;
rule_t shift_exp;
rule_t add_exp, multiply_exp;
rule_t unary_exp, primary_exp, constant;
rule_t const_exp_nocalc;
rule_t logical_or_exp_nocalc, logical_and_exp_nocalc;
rule_t inclusive_or_exp_nocalc, exclusive_or_exp_nocalc, and_exp_nocalc;
rule_t cmp_equality_nocalc, cmp_relational_nocalc;
rule_t shift_exp_nocalc;
rule_t add_exp_nocalc, multiply_exp_nocalc;
rule_t unary_exp_nocalc, primary_exp_nocalc, constant_nocalc;
boost::spirit::subrule<0, closure_type::context_t> const_exp_subrule;
definition(expression_grammar const &self)
{
using namespace boost::spirit;
using namespace phoenix;
using namespace boost::wave;
using boost::wave::util::pattern_p;
pp_expression
= const_exp[self.val = arg1]
;
const_exp
= logical_or_exp[const_exp.val = arg1]
>> !(const_exp_subrule =
ch_p(T_QUESTION_MARK)
>> const_exp
[
const_exp_subrule.val = arg1
]
>> ch_p(T_COLON)
>> const_exp
[
const_exp_subrule.val =
impl::questionmark(const_exp.val,
const_exp_subrule.val, arg1)
]
)[const_exp.val = arg1]
;
logical_or_exp
= logical_and_exp[logical_or_exp.val = arg1]
>> *( if_p(static_cast_<bool>(logical_or_exp.val))
[
// if one of the || operators is true, no more
// evaluation is required
pattern_p(T_OROR, MainTokenMask)
>> logical_and_exp_nocalc
[
logical_or_exp.val =
static_cast_<bool>(logical_or_exp.val)
]
]
.else_p
[
pattern_p(T_OROR, MainTokenMask)
>> logical_and_exp
[
logical_or_exp.val =
logical_or_exp.val || arg1
]
]
)
;
logical_and_exp
= inclusive_or_exp[logical_and_exp.val = arg1]
>> *( if_p(static_cast_<bool>(logical_and_exp.val))
[
pattern_p(T_ANDAND, MainTokenMask)
>> inclusive_or_exp
[
logical_and_exp.val =
logical_and_exp.val && arg1
]
]
.else_p
[
// if one of the && operators is false, no more
// evaluation is required
pattern_p(T_ANDAND, MainTokenMask)
>> inclusive_or_exp_nocalc
[
logical_and_exp.val =
static_cast_<bool>(logical_and_exp.val)
]
]
)
;
inclusive_or_exp
= exclusive_or_exp[inclusive_or_exp.val = arg1]
>> *( pattern_p(T_OR, MainTokenMask)
>> exclusive_or_exp
[
inclusive_or_exp.val =
static_cast_<unsigned int>(inclusive_or_exp.val)
| static_cast_<unsigned int>(arg1)
]
)
;
exclusive_or_exp
= and_exp[exclusive_or_exp.val = arg1]
>> *( pattern_p(T_XOR, MainTokenMask)
>> and_exp
[
exclusive_or_exp.val =
static_cast_<unsigned int>(exclusive_or_exp.val)
^ static_cast_<unsigned int>(arg1)
]
)
;
and_exp
= cmp_equality[and_exp.val = arg1]
>> *( pattern_p(T_AND, MainTokenMask)
>> cmp_equality
[
and_exp.val =
static_cast_<unsigned int>(and_exp.val)
& static_cast_<unsigned int>(arg1)
]
)
;
cmp_equality
= cmp_relational[cmp_equality.val = arg1]
>> *( ch_p(T_EQUAL)
>> cmp_relational
[
cmp_equality.val =
cmp_equality.val == arg1
]
| pattern_p(T_NOTEQUAL, MainTokenMask)
>> cmp_relational
[
cmp_equality.val =
cmp_equality.val != arg1
]
)
;
cmp_relational
= shift_exp[cmp_relational.val = arg1]
>> *( ch_p(T_LESSEQUAL)
>> shift_exp
[
cmp_relational.val =
cmp_relational.val <= arg1
]
| ch_p(T_GREATEREQUAL)
>> shift_exp
[
cmp_relational.val =
cmp_relational.val >= arg1
]
| ch_p(T_LESS)
>> shift_exp
[
cmp_relational.val =
cmp_relational.val < arg1
]
| ch_p(T_GREATER)
>> shift_exp
[
cmp_relational.val =
cmp_relational.val > arg1
]
)
;
shift_exp
= add_exp[shift_exp.val = arg1]
>> *( ch_p(T_SHIFTLEFT)
>> add_exp
[
shift_exp.val <<= arg1
]
| ch_p(T_SHIFTRIGHT)
>> add_exp
[
shift_exp.val >>= arg1
]
)
;
add_exp
= multiply_exp[add_exp.val = arg1]
>> *( ch_p(T_PLUS)
>> multiply_exp
[
add_exp.val += arg1
]
| ch_p(T_MINUS)
>> multiply_exp
[
add_exp.val -= arg1
]
)
;
multiply_exp
= unary_exp[multiply_exp.val = arg1]
>> *( ch_p(T_STAR)
>> unary_exp
[
multiply_exp.val *= arg1
]
| ch_p(T_DIVIDE)
>> unary_exp
[
multiply_exp.val /= arg1
]
| ch_p(T_PERCENT)
>> unary_exp
[
multiply_exp.val =
static_cast_<int>(multiply_exp.val)
% static_cast_<int>(arg1)
]
)
;
unary_exp
= primary_exp[unary_exp.val = arg1]
| ch_p(T_PLUS) >> unary_exp
[
unary_exp.val = static_cast_<int>(arg1)
]
| ch_p(T_MINUS) >> unary_exp
[
unary_exp.val = -static_cast_<int>(arg1)
]
| pattern_p(T_COMPL, MainTokenMask) >> unary_exp
[
unary_exp.val = ~static_cast_<unsigned int>(arg1)
]
| pattern_p(T_NOT, MainTokenMask) >> unary_exp
[
unary_exp.val = !static_cast_<bool>(arg1)
]
;
primary_exp
= constant[primary_exp.val = arg1]
| ch_p(T_LEFTPAREN)
>> const_exp[primary_exp.val = arg1]
>> ch_p(T_RIGHTPAREN)
;
constant
= ch_p(T_INTLIT)
[
constant.val = impl::as_intlit(arg1)
]
| ch_p(T_CHARLIT)
[
constant.val = impl::as_chlit(arg1)
]
;
// here follows the same grammar, but without any embedded
// calculations
const_exp_nocalc
= logical_or_exp_nocalc
>> !( ch_p(T_QUESTION_MARK)
>> const_exp_nocalc
>> ch_p(T_COLON)
>> const_exp_nocalc
)
;
logical_or_exp_nocalc
= logical_and_exp_nocalc
>> *( pattern_p(T_OROR, MainTokenMask)
>> logical_and_exp_nocalc
)
;
logical_and_exp_nocalc
= inclusive_or_exp_nocalc
>> *( pattern_p(T_ANDAND, MainTokenMask)
>> inclusive_or_exp_nocalc
)
;
inclusive_or_exp_nocalc
= exclusive_or_exp_nocalc
>> *( pattern_p(T_OR, MainTokenMask)
>> exclusive_or_exp_nocalc
)
;
exclusive_or_exp_nocalc
= and_exp_nocalc
>> *( pattern_p(T_XOR, MainTokenMask)
>> and_exp_nocalc
)
;
and_exp_nocalc
= cmp_equality_nocalc
>> *( pattern_p(T_AND, MainTokenMask)
>> cmp_equality_nocalc
)
;
cmp_equality_nocalc
= cmp_relational_nocalc
>> *( ch_p(T_EQUAL)
>> cmp_relational_nocalc
| pattern_p(T_NOTEQUAL, MainTokenMask)
>> cmp_relational_nocalc
)
;
cmp_relational_nocalc
= shift_exp_nocalc
>> *( ch_p(T_LESSEQUAL)
>> shift_exp_nocalc
| ch_p(T_GREATEREQUAL)
>> shift_exp_nocalc
| ch_p(T_LESS)
>> shift_exp_nocalc
| ch_p(T_GREATER)
>> shift_exp_nocalc
)
;
shift_exp_nocalc
= add_exp_nocalc
>> *( ch_p(T_SHIFTLEFT)
>> add_exp_nocalc
| ch_p(T_SHIFTRIGHT)
>> add_exp_nocalc
)
;
add_exp_nocalc
= multiply_exp_nocalc
>> *( ch_p(T_PLUS)
>> multiply_exp_nocalc
| ch_p(T_MINUS)
>> multiply_exp_nocalc
)
;
multiply_exp_nocalc
= unary_exp_nocalc
>> *( ch_p(T_STAR)
>> unary_exp_nocalc
| ch_p(T_DIVIDE)
>> unary_exp_nocalc
| ch_p(T_PERCENT)
>> unary_exp_nocalc
)
;
unary_exp_nocalc
= primary_exp_nocalc
| ch_p(T_PLUS) >> unary_exp_nocalc
| ch_p(T_MINUS) >> unary_exp_nocalc
| pattern_p(T_COMPL, MainTokenMask) >> unary_exp_nocalc
| pattern_p(T_NOT, MainTokenMask) >> unary_exp_nocalc
;
primary_exp_nocalc
= constant_nocalc
| ch_p(T_LEFTPAREN)
>> const_exp_nocalc
>> ch_p(T_RIGHTPAREN)
;
constant_nocalc
= ch_p(T_INTLIT)
| ch_p(T_CHARLIT)
;
BOOST_SPIRIT_DEBUG_TRACE_RULE(pp_expression, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(const_exp, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_or_exp, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_and_exp, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(inclusive_or_exp, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(exclusive_or_exp, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(and_exp, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_equality, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_relational, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(shift_exp, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(add_exp, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(multiply_exp, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(unary_exp, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(primary_exp, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(constant, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(const_exp_subrule, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(const_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_or_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_and_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(inclusive_or_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(exclusive_or_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(and_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_equality_nocalc, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_relational_nocalc, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(shift_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(add_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(multiply_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(unary_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(primary_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(constant_nocalc, TRACE_CPP_EXPR_GRAMMAR);
}
// start rule of this grammar
simple_rule_t const& start() const
{ return pp_expression; }
};
};
///////////////////////////////////////////////////////////////////////////////
#undef TRACE_CPP_EXPR_GRAMMAR
///////////////////////////////////////////////////////////////////////////////
//
// The following function is defined here, to allow the separation of
// the compilation of the expression_grammar from the function using it.
//
///////////////////////////////////////////////////////////////////////////////
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
#define BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE
#else
#define BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE inline
#endif
template <typename TokenT>
BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE
bool
expression_grammar_gen<TokenT>::evaluate(
typename token_sequence_type::const_iterator const &first,
typename token_sequence_type::const_iterator const &last,
typename token_type::position_type const &act_pos,
bool if_block_status)
{
using namespace boost::spirit;
using namespace boost::wave;
typedef typename token_sequence_type::const_iterator iterator_type;
static expression_grammar g; // expression grammar
boost::wave::grammars::closures::closure_value result; // expression result
parse_info<iterator_type> hit = parse (first, last, g[spirit_assign_actor(result)],
ch_p(T_SPACE) | ch_p(T_CCOMMENT) | ch_p(T_CPPCOMMENT));
if (!hit.hit) {
// expression is illformed
if (if_block_status) {
typedef typename token_sequence_type::value_type::string_type string_type;
BOOST_WAVE_THROW(preprocess_exception, ill_formed_expression,
boost::wave::util::impl::as_string<string_type>(first, last), act_pos);
}
else {
// as the if_block_status is false any errors will not be reported
return false;
}
}
if (!hit.full) {
// The token list starts with a valid expression, but there remains
// something. If the remainder consists out of whitespace only, the
// expression is still valid.
iterator_type next = hit.stop;
while (next != last) {
switch (token_id(*next)) {
case T_SPACE:
case T_SPACE2:
case T_CCOMMENT:
break; // ok continue
case T_NEWLINE:
case T_EOF:
case T_CPPCOMMENT: // contains newline
return bool(result); // expression is valid
default:
// expression is illformed
if (if_block_status) {
typedef typename token_sequence_type::value_type::string_type
string_type;
BOOST_WAVE_THROW(preprocess_exception, ill_formed_expression,
boost::wave::util::impl::as_string<string_type>(first, last),
act_pos);
}
else {
// as the if_block_status is false any errors will not be
// reported
return false;
}
}
++next;
}
}
if (!result.is_valid()) {
// division by zero occured
typedef typename token_sequence_type::value_type::string_type string_type;
BOOST_WAVE_THROW(preprocess_exception, division_by_zero,
boost::wave::util::impl::as_string<string_type>(first, last),
act_pos);
}
// token sequence is a valid expression
return bool(result);
}
#undef BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE
///////////////////////////////////////////////////////////////////////////////
} // namespace grammars
} // namespace wave
} // namespace boost
#endif // !defined(CPP_EXPRESSION_GRAMMAR_HPP_099CD1A4_A6C0_44BE_8F24_0B00F5BE5674_INCLUDED)

View File

@@ -1,53 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_EXPRESSION_GRAMMAR_GEN_HPP_42399258_6CDC_4101_863D_5C7D95B5A6CA_INCLUDED)
#define CPP_EXPRESSION_GRAMMAR_GEN_HPP_42399258_6CDC_4101_863D_5C7D95B5A6CA_INCLUDED
#include <list>
#include <boost/pool/pool_alloc.hpp>
#include <boost/wave/cpp_iteration_context.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace grammars {
///////////////////////////////////////////////////////////////////////////////
//
// expression_grammar_gen template class
//
// This template helps separating the compilation of the
// expression_grammar class from the compilation of the main
// pp_iterator. This is done to safe compilation time.
//
///////////////////////////////////////////////////////////////////////////////
template <typename TokenT>
struct expression_grammar_gen {
typedef TokenT token_type;
typedef std::list<token_type, boost::fast_pool_allocator<token_type> >
token_sequence_type;
static bool evaluate(
typename token_sequence_type::const_iterator const &first,
typename token_sequence_type::const_iterator const &last,
typename token_type::position_type const &tok,
bool if_block_status);
};
///////////////////////////////////////////////////////////////////////////////
} // namespace grammars
} // namespace wave
} // namespace boost
#endif // !defined(CPP_EXPRESSION_GRAMMAR_GEN_HPP_42399258_6CDC_4101_863D_5C7D95B5A6CA_INCLUDED)

View File

@@ -1,585 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_EXPRESSION_VALUE_HPP_452FE66D_8754_4107_AF1E_E42255A0C18A_INCLUDED)
#define CPP_EXPRESSION_VALUE_HPP_452FE66D_8754_4107_AF1E_E42255A0C18A_INCLUDED
#if defined (BOOST_SPIRIT_DEBUG)
#include <iostream>
#endif // defined(BOOST_SPIRIT_DEBUG)
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace grammars {
namespace closures {
///////////////////////////////////////////////////////////////////////////////
//
// The closure_value class represents the closure type, which is used for the
// expression grammar.
//
// This class was introduced to allow the expression grammar to respect
// the numeric type of a numeric literal or expression result.
//
///////////////////////////////////////////////////////////////////////////////
class closure_value {
public:
enum value_type {
is_int = 1,
is_uint = 2,
is_bool = 3
};
closure_value(bool valid_ = true)
: type(is_int), valid(valid_)
{ value.i = 0; }
explicit closure_value(int i, bool valid_ = true)
: type(is_int), valid(valid_)
{ value.i = i; }
explicit closure_value(unsigned int ui, bool valid_ = true)
: type(is_uint), valid(valid_)
{ value.ui = ui; }
explicit closure_value(long i, bool valid_ = true)
: type(is_int), valid(valid_)
{ value.i = i; }
explicit closure_value(unsigned long ui, bool valid_ = true)
: type(is_uint), valid(valid_)
{ value.ui = ui; }
explicit closure_value(bool b, bool valid_ = true)
: type(is_bool), valid(valid_)
{ value.b = b; }
value_type get_type() const { return type; }
bool is_valid() const { return valid; }
// implicit conversion
operator int() const
{
switch (type) {
case is_uint: return value.ui;
case is_bool: return value.b ? 1 : 0;
case is_int: break;
}
return value.i;
}
operator unsigned int() const
{
switch (type) {
case is_uint: return value.ui;
case is_bool: return value.b ? 1 : 0;
case is_int: break;
}
return value.i;
}
operator long() const
{
switch (type) {
case is_uint: return value.ui;
case is_bool: return value.b ? 1 : 0;
case is_int: break;
}
return value.i;
}
operator unsigned long() const
{
switch (type) {
case is_uint: return value.ui;
case is_bool: return value.b ? 1 : 0;
case is_int: break;
}
return value.i;
}
operator bool() const
{
switch (type) {
case is_uint: return value.ui != 0;
case is_bool: return value.b;
case is_int: break;
}
return value.i != 0.0;
}
// assignment
closure_value &operator= (closure_value const &rhs)
{
switch (rhs.get_type()) {
case is_int:
value.i = long(rhs);
type = is_int;
break;
case is_uint:
value.ui = (unsigned long)(rhs);
type = is_uint;
break;
case is_bool:
value.b = bool(rhs);
type = is_bool;
break;
}
valid = rhs.valid;
return *this;
}
closure_value &operator= (int rhs)
{
type = is_int;
value.i = rhs;
valid = true;
return *this;
}
closure_value &operator= (unsigned int rhs)
{
type = is_uint;
value.ui = rhs;
valid = true;
return *this;
}
closure_value &operator= (long rhs)
{
type = is_int;
value.i = rhs;
valid = true;
return *this;
}
closure_value &operator= (unsigned long rhs)
{
type = is_uint;
value.ui = rhs;
valid = true;
return *this;
}
closure_value &operator= (bool rhs)
{
type = is_bool;
value.b = rhs;
valid = true;
return *this;
}
// arithmetics
closure_value &operator+= (closure_value const &rhs)
{
switch (type) {
case is_int:
switch(rhs.type) {
case is_bool: value.i += long(rhs); break;
case is_int: value.i += rhs.value.i; break;
case is_uint: value.ui += rhs.value.ui; type = is_uint; break;
}
break;
case is_uint: value.ui += (unsigned long)(rhs); break;
case is_bool:
value.i = value.b + bool(rhs);
type = is_int;
}
valid = valid && rhs.valid;
return *this;
}
closure_value &operator-= (closure_value const &rhs)
{
switch (type) {
case is_int:
switch(rhs.type) {
case is_bool: value.i -= long(rhs); break;
case is_int: value.i -= rhs.value.i; break;
case is_uint: value.ui -= rhs.value.ui; type = is_uint; break;
}
break;
case is_uint: value.ui -= (unsigned long)(rhs); break;
case is_bool:
value.i = value.b - bool(rhs);
type = is_int;
}
valid = valid && rhs.valid;
return *this;
}
closure_value &operator*= (closure_value const &rhs)
{
switch (type) {
case is_int:
switch(rhs.type) {
case is_bool: value.i *= long(rhs); break;
case is_int: value.i *= rhs.value.i; break;
case is_uint: value.ui *= rhs.value.ui; type = is_uint; break;
}
break;
case is_uint: value.ui *= (unsigned long)(rhs); break;
case is_bool:
switch (rhs.type) {
case is_int:
value.i = (value.b ? 1 : 0) * rhs.value.i;
type = is_int;
break;
case is_uint:
value.ui = (value.b ? 1 : 0) * rhs.value.ui;
type = is_uint;
break;
case is_bool:
value.b = 0 != ((value.b ? 1 : 0) * (rhs.value.b ? 1 : 0));
break;
}
}
valid = valid && rhs.valid;
return *this;
}
closure_value &operator/= (closure_value const &rhs)
{
switch (type) {
case is_int:
switch(rhs.type) {
case is_bool:
case is_int:
if (valid && long(rhs) != 0)
value.i /= long(rhs);
else
valid = false; // division by zero
break;
case is_uint:
if (valid && rhs.value.ui != 0) {
value.ui /= rhs.value.ui;
type = is_uint;
}
else {
valid = false; // division by zero
}
break;
}
break;
case is_uint:
if (valid && (unsigned long)(rhs) != 0)
value.ui /= (unsigned long)(rhs);
else
valid = false; // division by zero
break;
case is_bool:
if (valid && bool(rhs)) {
switch(rhs.type) {
case is_int:
value.i = (value.b ? 1 : 0) / rhs.value.i;
type = is_int;
break;
case is_uint:
value.i = (value.b ? 1 : 0) / rhs.value.ui;
type = is_int;
break;
case is_bool:
break;
}
}
else {
valid = false; // division by zero
}
}
return *this;
}
friend closure_value
operator- (closure_value const &rhs)
{
switch (rhs.type) {
case is_int: return closure_value(-long(rhs), rhs.valid);
case is_bool: return closure_value(!bool(rhs), rhs.valid);
case is_uint: break;
}
return closure_value(-(int)(unsigned long)(rhs), rhs.valid);
}
friend closure_value
operator! (closure_value const &rhs)
{
switch (rhs.type) {
case is_int: return closure_value(!long(rhs), rhs.valid);
case is_bool: return closure_value(!bool(rhs), rhs.valid);
case is_uint: break;
}
return closure_value(!(unsigned long)(rhs), rhs.valid);
}
// comparison
friend closure_value
operator== (closure_value const &lhs, closure_value const &rhs)
{
bool cmp = false;
switch (lhs.type) {
case is_int:
switch(rhs.type) {
case is_bool: cmp = bool(lhs) == rhs.value.b; break;
case is_int: cmp = lhs.value.i == rhs.value.i; break;
case is_uint: cmp = lhs.value.ui == rhs.value.ui; break;
}
break;
case is_uint: cmp = lhs.value.ui == (unsigned long)(rhs); break;
case is_bool: cmp = lhs.value.b == bool(rhs); break;
}
return closure_value(cmp, lhs.valid && rhs.valid);
}
friend closure_value
operator!= (closure_value const &lhs, closure_value const &rhs)
{
return closure_value(!bool(lhs == rhs), lhs.valid && rhs.valid);
}
friend closure_value
operator> (closure_value const &lhs, closure_value const &rhs)
{
bool cmp = false;
switch (lhs.type) {
case is_int:
switch(rhs.type) {
case is_bool: cmp = lhs.value.i > long(rhs); break;
case is_int: cmp = lhs.value.i > rhs.value.i; break;
case is_uint: cmp = lhs.value.ui > rhs.value.ui; break;
}
break;
case is_uint: cmp = lhs.value.ui > (unsigned long)(rhs); break;
case is_bool: cmp = lhs.value.b > bool(rhs); break;
}
return closure_value(cmp, lhs.valid && rhs.valid);
}
friend closure_value
operator< (closure_value const &lhs, closure_value const &rhs)
{
bool cmp = false;
switch (lhs.type) {
case is_int: cmp = long(lhs) < long(rhs); break;
switch(rhs.type) {
case is_bool: cmp = lhs.value.i < long(rhs); break;
case is_int: cmp = lhs.value.i < rhs.value.i; break;
case is_uint: cmp = lhs.value.ui < rhs.value.ui; break;
}
break;
case is_uint: cmp = lhs.value.ui < (unsigned long)(rhs); break;
case is_bool: cmp = bool(lhs) < bool(rhs); break;
}
return closure_value(cmp, lhs.valid && rhs.valid);
}
friend closure_value
operator<= (closure_value const &lhs, closure_value const &rhs)
{
return closure_value(!bool(lhs > rhs), lhs.valid && rhs.valid);
}
friend closure_value
operator>= (closure_value const &lhs, closure_value const &rhs)
{
return closure_value(!bool(lhs < rhs), lhs.valid && rhs.valid);
}
closure_value &
operator<<= (closure_value const &rhs)
{
switch (type) {
case is_bool:
case is_int:
switch (rhs.type) {
case is_bool:
case is_int:
{
long shift_by = long(rhs);
if (shift_by > 64)
shift_by = 64;
else if (shift_by < -64)
shift_by = -64;
value.i <<= shift_by;
}
break;
case is_uint:
{
unsigned long shift_by = (unsigned long)(rhs);
if (shift_by > 64)
shift_by = 64;
value.ui <<= shift_by;
// Note: The usual arithmetic conversions are not performed on
// bit shift operations.
}
break;
}
break;
case is_uint:
switch (rhs.type) {
case is_bool:
case is_int:
{
long shift_by = long(rhs);
if (shift_by > 64)
shift_by = 64;
else if (shift_by < -64)
shift_by = -64;
value.ui <<= shift_by;
}
break;
case is_uint:
{
unsigned long shift_by = (unsigned long)(rhs);
if (shift_by > 64)
shift_by = 64;
value.ui <<= shift_by;
}
break;
}
}
valid = valid && rhs.valid;
return *this;
}
closure_value &
operator>>= (closure_value const &rhs)
{
switch (type) {
case is_bool:
case is_int:
switch (rhs.type) {
case is_bool:
case is_int:
{
long shift_by = long(rhs);
if (shift_by > 64)
shift_by = 64;
else if (shift_by < -64)
shift_by = -64;
value.i >>= shift_by;
}
break;
case is_uint:
{
unsigned long shift_by = (unsigned long)(rhs);
if (shift_by > 64)
shift_by = 64;
value.ui >>= shift_by;
// Note: The usual arithmetic conversions are not performed on
// bit shift operations.
}
break;
}
break;
case is_uint:
switch (rhs.type) {
case is_bool:
case is_int:
{
long shift_by = long(rhs);
if (shift_by > 64)
shift_by = 64;
else if (shift_by < -64)
shift_by = -64;
value.ui >>= shift_by;
}
break;
case is_uint:
{
unsigned long shift_by = (unsigned long)(rhs);
if (shift_by > 64)
shift_by = 64;
value.ui >>= shift_by;
}
break;
}
break;
}
valid = valid && rhs.valid;
return *this;
}
friend closure_value
operator|| (closure_value const &lhs, closure_value const &rhs)
{
bool result = bool(lhs) || bool(rhs);
return closure_value(result, lhs.valid && rhs.valid);
}
friend closure_value
operator&& (closure_value const &lhs, closure_value const &rhs)
{
bool result = bool(lhs) && bool(rhs);
return closure_value(result, lhs.valid && rhs.valid);
}
// handle the ?: operator
closure_value &
handle_questionmark(closure_value const &cond, closure_value const &val2)
{
switch (type) {
case is_int:
switch (val2.type) {
case is_bool: value.b = bool(cond) ? value.b : bool(val2); break;
case is_int: value.i = bool(cond) ? value.i : long(val2); break;
case is_uint:
value.ui = bool(cond) ? value.ui : (unsigned long)(val2);
type = is_uint; // changing type!
break;
}
break;
case is_uint: value.ui = bool(cond) ? value.ui : (unsigned long)(val2); break;
case is_bool: value.b = bool(cond) ? value.b : bool(val2); break;
}
valid = bool(cond) ? valid : val2.valid;
return *this;
}
#if defined (BOOST_SPIRIT_DEBUG)
friend std::ostream&
operator<< (std::ostream &o, closure_value const &val)
{
switch (val.type) {
case is_int: o << "int(" << long(val) << ")"; break;
case is_uint: o << "unsigned int(" << (unsigned long)(val) << ")"; break;
case is_bool: o << "bool(" << bool(val) << ")"; break;
}
return o;
}
#endif // defined(BOOST_SPIRIT_DEBUG)
private:
value_type type;
union {
long i;
unsigned long ui;
bool b;
} value;
bool valid;
};
///////////////////////////////////////////////////////////////////////////////
} // namespace closures
} // namespace grammars
} // namespace wave
} // namespace boost
#endif // !defined(CPP_EXPRESSION_VALUE_HPP_452FE66D_8754_4107_AF1E_E42255A0C18A_INCLUDED)

View File

@@ -1,692 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED)
#define CPP_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED
#include <boost/spirit/core.hpp>
#include <boost/spirit/tree/parse_tree.hpp>
#include <boost/spirit/tree/parse_tree_utils.hpp>
#include <boost/spirit/utility/confix.hpp>
#include <boost/spirit/utility/lists.hpp>
#include <boost/wave/wave_config.hpp>
#if BOOST_WAVE_DUMP_PARSE_TREE != 0
#include <map>
#include <boost/spirit/tree/tree_to_xml.hpp>
#endif
#include <boost/wave/token_ids.hpp>
#include <boost/wave/grammars/cpp_grammar_gen.hpp>
#include <boost/wave/util/pattern_parser.hpp>
#include <boost/wave/cpp_exceptions.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace grammars {
namespace impl {
///////////////////////////////////////////////////////////////////////////////
//
// store_position
//
// The store_position functor extracts the actual file position from the
// supplied token.
//
///////////////////////////////////////////////////////////////////////////////
template <typename PositionT>
struct store_position {
store_position(PositionT &pos_) : pos(pos_) {}
template <typename TokenT>
void operator()(TokenT const &token) const
{
pos = token.get_position();
}
PositionT &pos;
};
///////////////////////////////////////////////////////////////////////////////
//
// store_found_eof
//
// The store_found_eof functor sets a given flag if the T_EOF token was
// found during the parsing process
//
///////////////////////////////////////////////////////////////////////////////
struct store_found_eof {
store_found_eof(bool &found_eof_) : found_eof(found_eof_) {}
template <typename TokenT>
void operator()(TokenT const &token) const
{
found_eof = true;
}
bool &found_eof;
};
///////////////////////////////////////////////////////////////////////////////
//
// store_found_directive
//
// The store_found_directive functor stores the token_id of the recognized
// pp directive
//
///////////////////////////////////////////////////////////////////////////////
struct store_found_directive {
store_found_directive(boost::wave::token_id &found_directive_)
: found_directive(found_directive_) {}
template <typename TokenT>
void operator()(TokenT const &token) const
{
found_directive = boost::wave::token_id(token);
}
boost::wave::token_id &found_directive;
};
///////////////////////////////////////////////////////////////////////////////
//
// flush_underlying_parser
//
// The flush_underlying_parser flushes the underlying
// multi_pass_iterator during the normal parsing process. This is
// used at certain points during the parsing process, when it is
// clear, that no backtracking is needed anymore and the input
// gathered so far may be discarded.
//
///////////////////////////////////////////////////////////////////////////////
struct flush_underlying_parser
: public boost::spirit::parser<flush_underlying_parser>
{
typedef flush_underlying_parser this_t;
template <typename ScannerT>
typename boost::spirit::parser_result<this_t, ScannerT>::type
parse(ScannerT const& scan) const
{
scan.first.clear_queue();
return scan.empty_match();
}
};
flush_underlying_parser const
flush_underlying_parser_p = flush_underlying_parser();
} // anonymous namespace
///////////////////////////////////////////////////////////////////////////////
// define, whether the rule's should generate some debug output
#define TRACE_CPP_GRAMMAR \
bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_GRAMMAR) \
/**/
///////////////////////////////////////////////////////////////////////////////
// Encapsulation of the C++ preprocessor grammar.
template <typename PositionT>
struct cpp_grammar :
public boost::spirit::grammar<cpp_grammar<PositionT> >
{
typedef cpp_grammar<PositionT> grammar_t;
typedef impl::store_position<PositionT> store_pos_t;
typedef impl::store_found_eof store_found_eof_t;
typedef impl::store_found_directive store_found_directive_t;
template <typename ScannerT>
struct definition
{
// non-parse_tree generating rule type
typedef typename ScannerT::iteration_policy_t iteration_policy_t;
typedef boost::spirit::match_policy match_policy_t;
typedef typename ScannerT::action_policy_t action_policy_t;
typedef
boost::spirit::scanner_policies<
iteration_policy_t, match_policy_t, action_policy_t>
policies_t;
typedef
boost::spirit::scanner<typename ScannerT::iterator_t, policies_t>
non_tree_scanner_t;
typedef boost::spirit::rule<non_tree_scanner_t> no_tree_rule_t;
// 'normal' (parse_tree generating) rule type
typedef boost::spirit::rule<ScannerT> rule_t;
rule_t pp_statement;
rule_t include_file, system_include_file, macro_include_file;
rule_t plain_define, macro_definition, macro_parameters;
rule_t undefine;
rule_t ppifdef, ppifndef, ppif, ppelse, ppelif, ppendif;
rule_t ppline;
rule_t pperror;
rule_t ppwarning;
rule_t pppragma;
rule_t illformed;
rule_t ppqualifiedname;
rule_t eol_tokens;
no_tree_rule_t ppsp;
definition(cpp_grammar const &self)
{
// import the spirit and cpplexer namespaces here
using namespace boost::spirit;
using namespace boost::wave;
using namespace boost::wave::util;
// save the rule id's for later use
self.rule_ids.pp_statement_id = pp_statement.id().to_long();
self.rule_ids.include_file_id = include_file.id().to_long();
self.rule_ids.sysinclude_file_id = system_include_file.id().to_long();
self.rule_ids.macroinclude_file_id = macro_include_file.id().to_long();
self.rule_ids.plain_define_id = plain_define.id().to_long();
self.rule_ids.macro_parameters_id = macro_parameters.id().to_long();
self.rule_ids.macro_definition_id = macro_definition.id().to_long();
self.rule_ids.undefine_id = undefine.id().to_long();
self.rule_ids.ifdef_id = ppifdef.id().to_long();
self.rule_ids.ifndef_id = ppifndef.id().to_long();
self.rule_ids.if_id = ppif.id().to_long();
self.rule_ids.elif_id = ppelif.id().to_long();
self.rule_ids.else_id = ppelse.id().to_long();
self.rule_ids.endif_id = ppendif.id().to_long();
self.rule_ids.line_id = ppline.id().to_long();
self.rule_ids.error_id = pperror.id().to_long();
self.rule_ids.warning_id = ppwarning.id().to_long();
self.rule_ids.pragma_id = pppragma.id().to_long();
self.rule_ids.illformed_id = illformed.id().to_long();
self.rule_ids.ppspace_id = ppsp.id().to_long();
self.rule_ids.ppqualifiedname_id = ppqualifiedname.id().to_long();
#if BOOST_WAVE_DUMP_PARSE_TREE != 0
self.map_rule_id_to_name.init_rule_id_to_name_map(self);
#endif
// recognizes preprocessor directives only
// C++ standard 16.1: A preprocessing directive consists of a sequence
// of preprocessing tokens. The first token in the sequence is #
// preprocessing token that is either the first character in the source
// file (optionally after white space containing no new-line
// characters) or that follows white space containing at least one
// new-line character. The last token in the sequence is the first
// new-line character that follows the first token in the sequence.
pp_statement
= ( include_file
| system_include_file
| macro_include_file
| plain_define
| undefine
| ppifdef
| ppifndef
| ppif
| ppelse
| ppelif
| ppendif
| ppline
| pperror
| ppwarning
| pppragma
| illformed
)
>> eol_tokens
#if !(defined(BOOST_SPIRIT_DEBUG) && \
(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_GRAMMAR))
>> impl::flush_underlying_parser_p
#endif // !(defined(BOOST_SPIRIT_DEBUG) &&
// (BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_GRAMMAR))
;
// #include ...
include_file // include "..."
= ch_p(T_PP_QHEADER)
[ store_found_directive_t(self.found_directive) ]
#if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
| ch_p(T_PP_QHEADER_NEXT)
[ store_found_directive_t(self.found_directive) ]
#endif
;
system_include_file // include <...>
= ch_p(T_PP_HHEADER)
[ store_found_directive_t(self.found_directive) ]
#if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
| ch_p(T_PP_HHEADER_NEXT)
[ store_found_directive_t(self.found_directive) ]
#endif
;
macro_include_file // include ...anything else...
= no_node_d
[
ch_p(T_PP_INCLUDE)
[ store_found_directive_t(self.found_directive) ]
#if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
| ch_p(T_PP_INCLUDE_NEXT)
[ store_found_directive_t(self.found_directive) ]
#endif
]
>> *( anychar_p -
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
)
;
// #define FOO foo (with optional parameters)
plain_define
= no_node_d
[
ch_p(T_PP_DEFINE)
[ store_found_directive_t(self.found_directive) ]
>> +ppsp
]
>> ( ch_p(T_IDENTIFIER)
| pattern_p(KeywordTokenType, TokenTypeMask)
| pattern_p(OperatorTokenType|AltExtTokenType,
ExtTokenTypeMask) // and, bit_and etc.
)
>> ( ( no_node_d[eps_p(ch_p(T_LEFTPAREN))]
>> macro_parameters
>> !macro_definition
)
| !( no_node_d[+ppsp]
>> macro_definition
)
)
;
// parameter list
// normal C++ mode
macro_parameters
= confix_p(
no_node_d[ch_p(T_LEFTPAREN) >> *ppsp],
!list_p(
( ch_p(T_IDENTIFIER)
| pattern_p(KeywordTokenType, TokenTypeMask)
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
| ch_p(T_ELLIPSIS)
#endif
),
no_node_d[*ppsp >> ch_p(T_COMMA) >> *ppsp]
),
no_node_d[*ppsp >> ch_p(T_RIGHTPAREN)]
)
;
// macro body (anything left until eol)
macro_definition
= no_node_d[*ppsp]
>> *( anychar_p -
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
)
;
// #undef FOO
undefine
= no_node_d
[
ch_p(T_PP_UNDEF)
[ store_found_directive_t(self.found_directive) ]
>> +ppsp
]
>> ( ch_p(T_IDENTIFIER)
| pattern_p(KeywordTokenType, TokenTypeMask)
)
;
// #ifdef et.al.
ppifdef
= no_node_d
[
ch_p(T_PP_IFDEF)
[ store_found_directive_t(self.found_directive) ]
>> +ppsp
]
>> ppqualifiedname
;
ppifndef
= no_node_d
[
ch_p(T_PP_IFNDEF)
[ store_found_directive_t(self.found_directive) ]
>> +ppsp
]
>> ppqualifiedname
;
ppif
= no_node_d
[
ch_p(T_PP_IF)
[ store_found_directive_t(self.found_directive) ]
>> *ppsp
]
>> +( anychar_p -
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
)
;
ppelse
= no_node_d
[
ch_p(T_PP_ELSE)
[ store_found_directive_t(self.found_directive) ]
]
;
ppelif
= no_node_d
[
ch_p(T_PP_ELIF)
[ store_found_directive_t(self.found_directive) ]
>> *ppsp
]
>> +( anychar_p -
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
)
;
ppendif
= no_node_d
[
ch_p(T_PP_ENDIF)
[ store_found_directive_t(self.found_directive) ]
]
;
// #line ...
ppline
= no_node_d
[
ch_p(T_PP_LINE)
[ store_found_directive_t(self.found_directive) ]
>> *ppsp
]
>> +( anychar_p -
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
)
;
// # something else (ill formed preprocessor directive)
illformed // for error reporting
= no_node_d
[
pattern_p(T_POUND, MainTokenMask)
>> *ppsp
]
>> ( anychar_p -
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
)
>> no_node_d
[
*( anychar_p -
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
)
]
;
// #error
pperror
= no_node_d
[
ch_p(T_PP_ERROR)
[ store_found_directive_t(self.found_directive) ]
>> *ppsp
]
>> *( anychar_p -
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
)
;
// #warning
ppwarning
= no_node_d
[
ch_p(T_PP_WARNING)
[ store_found_directive_t(self.found_directive) ]
>> *ppsp
]
>> *( anychar_p -
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
)
;
// #pragma ...
pppragma
= no_node_d
[
ch_p(T_PP_PRAGMA)
[ store_found_directive_t(self.found_directive) ]
]
>> *( anychar_p -
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
)
;
ppqualifiedname
= no_node_d[*ppsp]
>> ( ch_p(T_IDENTIFIER)
| pattern_p(KeywordTokenType, TokenTypeMask)
)
;
// auxiliary helper rules
ppsp // valid space in a line with a preprocessor directive
= ch_p(T_SPACE) | ch_p(T_CCOMMENT)
;
// end of line tokens
eol_tokens
= no_node_d
[
*ppsp
>> ( ch_p(T_NEWLINE)
[ store_pos_t(self.pos_of_newline) ]
| ch_p(T_CPPCOMMENT)
[ store_pos_t(self.pos_of_newline) ]
| ch_p(T_EOF)
[ store_pos_t(self.pos_of_newline) ]
[ store_found_eof_t(self.found_eof) ]
)
]
;
BOOST_SPIRIT_DEBUG_TRACE_RULE(pp_statement, TRACE_CPP_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(include_file, TRACE_CPP_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(system_include_file, TRACE_CPP_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_include_file, TRACE_CPP_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(plain_define, TRACE_CPP_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_definition, TRACE_CPP_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_parameters, TRACE_CPP_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(undefine, TRACE_CPP_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppifdef, TRACE_CPP_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppifndef, TRACE_CPP_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppif, TRACE_CPP_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppelse, TRACE_CPP_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppelif, TRACE_CPP_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppendif, TRACE_CPP_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppline, TRACE_CPP_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(pperror, TRACE_CPP_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppwarning, TRACE_CPP_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(illformed, TRACE_CPP_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppsp, TRACE_CPP_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppqualifiedname, TRACE_CPP_GRAMMAR);
}
// start rule of this grammar
rule_t const& start() const
{ return pp_statement; }
};
cpp_grammar_rule_ids &rule_ids;
PositionT &pos_of_newline;
bool &found_eof;
boost::wave::token_id &found_directive;
cpp_grammar(cpp_grammar_rule_ids &rule_ids_, PositionT &pos_of_newline_,
bool &found_eof_, boost::wave::token_id &found_directive_)
: rule_ids(rule_ids_), pos_of_newline(pos_of_newline_),
found_eof(found_eof_), found_directive(found_directive_)
{
BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "cpp_grammar",
TRACE_CPP_GRAMMAR);
}
#if BOOST_WAVE_DUMP_PARSE_TREE != 0
// helper function and data to get readable names of the rules known to us
struct map_ruleid_to_name :
public std::map<boost::spirit::parser_id, std::string>
{
typedef std::map<boost::spirit::parser_id, std::string> base_t;
void init_rule_id_to_name_map(cpp_grammar const &self)
{
struct {
int parser_id;
char const *rule_name;
}
init_ruleid_name_map[] = {
{ self.rule_ids.pp_statement_id, "pp_statement" },
{ self.rule_ids.include_file_id, "include_file" },
{ self.rule_ids.sysinclude_file_id, "system_include_file" },
{ self.rule_ids.macroinclude_file_id, "macro_include_file" },
{ self.rule_ids.plain_define_id, "plain_define" },
{ self.rule_ids.macro_parameters_id, "macro_parameters" },
{ self.rule_ids.macro_definition_id, "macro_definition" },
{ self.rule_ids.undefine_id, "undefine" },
{ self.rule_ids.ifdef_id, "ppifdef" },
{ self.rule_ids.ifndef_id, "ppifndef" },
{ self.rule_ids.if_id, "ppif" },
{ self.rule_ids.elif_id, "ppelif" },
{ self.rule_ids.else_id, "ppelse" },
{ self.rule_ids.endif_id, "ppendif" },
{ self.rule_ids.line_id, "ppline" },
{ self.rule_ids.error_id, "pperror" },
{ self.rule_ids.warning_id, "ppwarning" },
{ self.rule_ids.pragma_id, "pppragma" },
{ self.rule_ids.illformed_id, "illformed" },
{ self.rule_ids.ppsp_id, "ppsp" },
{ self.rule_ids.ppqualifiedname_id, "ppqualifiedname" },
{ 0 }
};
// initialize parser_id to rule_name map
for (int i = 0; 0 != init_ruleid_name_map[i].parser_id; ++i)
base_t::insert(base_t::value_type(
boost::spirit::parser_id(init_ruleid_name_map[i].parser_id),
std::string(init_ruleid_name_map[i].rule_name))
);
}
};
mutable map_ruleid_to_name map_rule_id_to_name;
#endif // WAVE_DUMP_PARSE_TREE != 0
};
///////////////////////////////////////////////////////////////////////////////
#undef TRACE_CPP_GRAMMAR
///////////////////////////////////////////////////////////////////////////////
//
// The following parse function is defined here, to allow the separation of
// the compilation of the cpp_grammar from the function using it.
//
///////////////////////////////////////////////////////////////////////////////
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
#define BOOST_WAVE_GRAMMAR_GEN_INLINE
#else
#define BOOST_WAVE_GRAMMAR_GEN_INLINE inline
#endif
namespace {
char const *get_directivename(boost::wave::token_id id)
{
using namespace boost::wave;
switch (id) {
case T_PP_QHEADER:
case T_PP_HHEADER:
case T_PP_INCLUDE: return "#include";
case T_PP_DEFINE: return "#define";
case T_PP_UNDEF: return "#undef";
case T_PP_IFDEF: return "#ifdef";
case T_PP_IFNDEF: return "#ifndef";
case T_PP_IF: return "#if";
case T_PP_ELSE: return "#else";
case T_PP_ELIF: return "#elif";
case T_PP_ENDIF: return "#endif";
case T_PP_LINE: return "#line";
case T_PP_ERROR: return "#error";
case T_PP_WARNING: return "#warning";
case T_PP_PRAGMA: return "#pragma";
default:
return "#unknown directive";
}
}
}
template <typename LexIteratorT>
BOOST_WAVE_GRAMMAR_GEN_INLINE
boost::spirit::tree_parse_info<LexIteratorT>
cpp_grammar_gen<LexIteratorT>::parse_cpp_grammar (
LexIteratorT const &first, LexIteratorT const &last,
bool &found_eof_, position_type const &act_pos)
{
using namespace boost::spirit;
using namespace boost::wave;
pos_of_newline = position_type(); // reset position
found_eof = false; // reset flag
found_directive = T_EOF; // reset found directive
static cpp_grammar<position_type> g(
rule_ids, pos_of_newline, found_eof, found_directive);
tree_parse_info<LexIteratorT> hit = pt_parse (first, last, g);
#if BOOST_WAVE_DUMP_PARSE_TREE != 0
if (hit.match) {
tree_to_xml (BOOST_WAVE_DUMP_PARSE_TREE_OUT, hit.trees, "",
g.map_rule_id_to_name, &TokenT::get_token_id,
&TokenT::get_token_value);
}
#endif
if (!hit.match && found_directive != T_EOF) {
// recognized invalid directive
std::string directive = get_directivename(found_directive);
BOOST_WAVE_THROW(preprocess_exception, ill_formed_directive,
directive, act_pos);
}
found_eof_ = found_eof;
return hit;
}
#undef BOOST_WAVE_GRAMMAR_GEN_INLINE
///////////////////////////////////////////////////////////////////////////////
} // namespace grammars
} // namespace wave
} // namespace boost
#endif // !defined(CPP_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED)

View File

@@ -1,113 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_GRAMMAR_GEN_HPP_80CB8A59_5411_4E45_B406_62531A12FB99_INCLUDED)
#define CPP_GRAMMAR_GEN_HPP_80CB8A59_5411_4E45_B406_62531A12FB99_INCLUDED
#include <boost/spirit/tree/parse_tree.hpp>
#include <boost/wave/wave_config.hpp>
#include <boost/wave/language_support.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace grammars {
///////////////////////////////////////////////////////////////////////////////
//
// store parser_id's of all rules of the cpp_grammar here for later access
//
///////////////////////////////////////////////////////////////////////////////
struct cpp_grammar_rule_ids {
std::size_t pp_statement_id;
std::size_t include_file_id; // #include "..."
std::size_t sysinclude_file_id; // #include <...>
std::size_t macroinclude_file_id; // #include ...
std::size_t plain_define_id; // #define
std::size_t macro_parameters_id;
std::size_t macro_definition_id;
std::size_t undefine_id; // #undef
std::size_t ifdef_id; // #ifdef
std::size_t ifndef_id; // #ifndef
std::size_t if_id; // #if
std::size_t elif_id; // #elif
std::size_t else_id; // #else
std::size_t endif_id; // #endif
std::size_t line_id; // #line
std::size_t error_id; // #error
std::size_t warning_id; // #warning
std::size_t pragma_id; // #pragma
std::size_t illformed_id;
std::size_t ppspace_id;
std::size_t ppqualifiedname_id;
};
///////////////////////////////////////////////////////////////////////////////
//
// cpp_grammar_gen template class
//
// This template helps separating the compilation of the cpp_grammar
// class from the compilation of the main pp_iterator. This is done to
// safe compilation time.
//
///////////////////////////////////////////////////////////////////////////////
template <typename LexIteratorT>
struct cpp_grammar_gen
{
typedef LexIteratorT iterator_type;
typedef typename LexIteratorT::token_type token_type;
typedef typename token_type::position_type position_type;
// the parser_id's of all rules of the cpp_grammar are stored here
// note: these are valid only after the first call to parse_cpp_grammar
static cpp_grammar_rule_ids rule_ids;
// the actual position of the last matched T_NEWLINE is stored here into the
// member 'pos_of_newline'
static position_type pos_of_newline;
// the found_eof flag is set to true during the parsing, if the directive
// under inspection terminates with a T__EOF token
static bool found_eof;
// the found_directive contains the token_id of the recognized pp directive
static boost::wave::token_id found_directive;
// parse the cpp_grammar and return the resulting parse tree
static boost::spirit::tree_parse_info<iterator_type>
parse_cpp_grammar (iterator_type const &first, iterator_type const &last,
bool &found_eof_, position_type const &act_pos);
};
///////////////////////////////////////////////////////////////////////////////
// definitions of the static members
template <typename LexIteratorT>
cpp_grammar_rule_ids
cpp_grammar_gen<LexIteratorT>::rule_ids;
template <typename LexIteratorT>
typename LexIteratorT::token_type::position_type
cpp_grammar_gen<LexIteratorT>::pos_of_newline;
template <typename LexIteratorT>
bool cpp_grammar_gen<LexIteratorT>::found_eof = false;
template <typename LexIteratorT>
boost::wave::token_id cpp_grammar_gen<LexIteratorT>::found_directive =
boost::wave::T_EOF;
///////////////////////////////////////////////////////////////////////////////
} // namespace grammars
} // namespace wave
} // namespace boost
#endif // !defined(CPP_GRAMMAR_GEN_HPP_80CB8A59_5411_4E45_B406_62531A12FB99_INCLUDED)

View File

@@ -1,183 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_INTLIT_GRAMMAR_HPP_2E1E70B1_F15C_4132_8554_10A231B0D91C_INCLUDED)
#define CPP_INTLIT_GRAMMAR_HPP_2E1E70B1_F15C_4132_8554_10A231B0D91C_INCLUDED
#include <boost/spirit/core.hpp>
#include <boost/spirit/attribute/closure.hpp>
#if SPIRIT_VERSION >= 0x1700
#include <boost/spirit/actor/assign_actor.hpp>
#include <boost/spirit/actor/push_back_actor.hpp>
#endif // SPIRIT_VERSION >= 0x1700
#include <boost/spirit/phoenix/operators.hpp>
#include <boost/spirit/phoenix/primitives.hpp>
#include <boost/spirit/phoenix/statements.hpp>
#include <boost/wave/wave_config.hpp>
#include <boost/wave/cpp_exceptions.hpp>
#include <boost/wave/grammars/cpp_literal_grammar_gen.hpp>
#if !defined(spirit_append_actor)
#if SPIRIT_VERSION >= 0x1700
#define spirit_append_actor(actor) boost::spirit::push_back_a(actor)
#define spirit_assign_actor(actor) boost::spirit::assign_a(actor)
#else
#define spirit_append_actor(actor) boost::spirit::append(actor)
#define spirit_assign_actor(actor) boost::spirit::assign(actor)
#endif // SPIRIT_VERSION >= 0x1700
#endif // !defined(spirit_append_actor)
///////////////////////////////////////////////////////////////////////////////
//
// Reusable grammar for parsing of C++ style integer literals
//
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace grammars {
namespace closures {
struct intlit_closure
: boost::spirit::closure<intlit_closure, unsigned long>
{
member1 val;
};
}
///////////////////////////////////////////////////////////////////////////////
// define, whether the rule's should generate some debug output
#define TRACE_INTLIT_GRAMMAR \
bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_INTLIT_GRAMMAR) \
/**/
struct intlit_grammar :
boost::spirit::grammar<intlit_grammar, closures::intlit_closure::context_t>
{
intlit_grammar(bool &is_unsigned_) : is_unsigned(is_unsigned_)
{
BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "intlit_grammar",
TRACE_INTLIT_GRAMMAR);
}
template <typename ScannerT>
struct definition
{
typedef boost::spirit::rule<ScannerT> rule_t;
rule_t int_lit;
boost::spirit::subrule<0> sub_int_lit;
boost::spirit::subrule<1> oct_lit;
boost::spirit::subrule<2> hex_lit;
boost::spirit::subrule<3> dec_lit;
definition(intlit_grammar const &self)
{
using namespace boost::spirit;
using namespace phoenix;
int_lit = (
sub_int_lit =
( ch_p('0')[self.val = 0] >> (hex_lit | oct_lit)
| dec_lit
)
>> !as_lower_d[
(ch_p('u')[var(self.is_unsigned) = true] || ch_p('l'))
| (ch_p('l') || ch_p('u')[var(self.is_unsigned) = true])
]
,
hex_lit =
(ch_p('X') | ch_p('x'))
>> uint_parser<unsigned long, 16>()
[
self.val = arg1,
var(self.is_unsigned) = true
]
,
oct_lit =
!uint_parser<unsigned long, 8>()
[
self.val = arg1,
var(self.is_unsigned) = true
]
,
dec_lit =
int_parser<long, 10>()
[
self.val = arg1
]
)
;
BOOST_SPIRIT_DEBUG_TRACE_RULE(int_lit, TRACE_INTLIT_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(sub_int_lit, TRACE_INTLIT_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(hex_lit, TRACE_INTLIT_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(oct_lit, TRACE_INTLIT_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(dec_lit, TRACE_INTLIT_GRAMMAR);
}
// start rule of this grammar
rule_t const& start() const
{ return int_lit; }
};
bool &is_unsigned;
};
#undef TRACE_INTLIT_GRAMMAR
///////////////////////////////////////////////////////////////////////////////
//
// The following function is defined here, to allow the separation of
// the compilation of the intlit_grammap from the function using it.
//
///////////////////////////////////////////////////////////////////////////////
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
#define BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE
#else
#define BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE inline
#endif
template <typename TokenT>
BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE
unsigned long
intlit_grammar_gen<TokenT>::evaluate(TokenT const &token,
bool &is_unsigned)
{
using namespace boost::spirit;
intlit_grammar g(is_unsigned);
unsigned long result = 0;
typename TokenT::string_type const &token_val = token.get_value();
parse_info<typename TokenT::string_type::const_iterator> hit =
parse(token_val.begin(), token_val.end(), g[spirit_assign_actor(result)]);
if (!hit.hit) {
BOOST_WAVE_THROW(preprocess_exception, ill_formed_expression,
token_val, token.get_position());
}
return result;
}
#undef BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE
///////////////////////////////////////////////////////////////////////////////
} // namespace grammars
} // namespace wave
} // namespace boost
#endif // !defined(CPP_INTLIT_GRAMMAR_HPP_2E1E70B1_F15C_4132_8554_10A231B0D91C_INCLUDED)

View File

@@ -1,54 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_LITERAL_GRAMMAR_GEN_HPP_67794A6C_468A_4AAB_A757_DEDDB182F5A0_INCLUDED)
#define CPP_LITERAL_GRAMMAR_GEN_HPP_67794A6C_468A_4AAB_A757_DEDDB182F5A0_INCLUDED
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace grammars {
///////////////////////////////////////////////////////////////////////////////
//
// cpp_intlit_grammar_gen template class
//
// This template helps separating the compilation of the intlit_grammar
// class from the compilation of the expression_grammar. This is done
// to safe compilation time.
//
///////////////////////////////////////////////////////////////////////////////
template <typename TokenT>
struct intlit_grammar_gen {
static unsigned long evaluate(TokenT const &tok, bool &is_unsigned);
};
///////////////////////////////////////////////////////////////////////////////
//
// cpp_chlit_grammar_gen template class
//
// This template helps separating the compilation of the chlit_grammar
// class from the compilation of the expression_grammar. This is done
// to safe compilation time.
//
///////////////////////////////////////////////////////////////////////////////
template <typename TokenT>
struct chlit_grammar_gen {
static unsigned int evaluate(TokenT const &tok);
};
///////////////////////////////////////////////////////////////////////////////
} // namespace grammars
} // namespace wave
} // namespace boost
#endif // !defined(CPP_LITERAL_GRAMMAR_GEN_HPP_67794A6C_468A_4AAB_A757_DEDDB182F5A0_INCLUDED)

View File

@@ -1,73 +0,0 @@
/*=============================================================================
A Standard compliant C++ preprocessor
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_PREDEF_MACROS_GEN_HPP_CADB6D2C_76A4_4988_83E1_EFFC6902B9A2_INCLUDED)
#define CPP_PREDEF_MACROS_GEN_HPP_CADB6D2C_76A4_4988_83E1_EFFC6902B9A2_INCLUDED
#include <boost/spirit/tree/parse_tree.hpp>
#include <boost/wave/wave_config.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace grammars {
///////////////////////////////////////////////////////////////////////////////
//
// store parser_id's of all rules of the predefined_macros_grammar here
// for later access
//
///////////////////////////////////////////////////////////////////////////////
struct predefined_macros_grammar_rule_ids {
std::size_t plain_define_id; // #define
std::size_t macro_parameters_id;
std::size_t macro_definition_id;
};
///////////////////////////////////////////////////////////////////////////////
//
// predefined_macros_grammar_gen template class
//
// This template helps separating the compilation of the
// predefined_macros_grammar class from the compilation of the
// main pp_iterator. This is done to safe compilation time.
//
// This class helps parsing command line given macro definitions in a
// similar way, as macros are parsed by the cpp_grammar class.
//
///////////////////////////////////////////////////////////////////////////////
template <typename LexIteratorT>
struct predefined_macros_grammar_gen
{
typedef LexIteratorT iterator_type;
// the parser_id's of all rules of the cpp_grammar are stored here
// note: these are valid only after the first call to parse_cpp_grammar
static predefined_macros_grammar_rule_ids rule_ids;
// parse the cpp_grammar and return the resulting parse tree
static boost::spirit::tree_parse_info<iterator_type>
parse_predefined_macro (iterator_type const &first, iterator_type const &last);
};
///////////////////////////////////////////////////////////////////////////////
// definitions of the static members
template <typename LexIteratorT>
predefined_macros_grammar_rule_ids
predefined_macros_grammar_gen<LexIteratorT>::rule_ids;
///////////////////////////////////////////////////////////////////////////////
} // namespace grammars
} // namespace wave
} // namespace boost
#endif // !defined(CPP_PREDEF_MACROS_GEN_HPP_CADB6D2C_76A4_4988_83E1_EFFC6902B9A2_INCLUDED)

View File

@@ -1,156 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED)
#define CPP_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED
#include <boost/spirit/core.hpp>
#include <boost/spirit/tree/parse_tree.hpp>
#include <boost/spirit/utility/confix.hpp>
#include <boost/spirit/utility/lists.hpp>
#include <boost/wave/wave_config.hpp>
#include <boost/wave/token_ids.hpp>
#include <boost/wave/grammars/cpp_predef_macros_gen.hpp>
#include <boost/wave/util/pattern_parser.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace grammars {
///////////////////////////////////////////////////////////////////////////////
// define, whether the rule's should generate some debug output
#define TRACE_PREDEF_MACROS_GRAMMAR \
bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_PREDEF_MACROS_GRAMMAR) \
/**/
///////////////////////////////////////////////////////////////////////////////
// Encapsulation of the grammar for command line driven predefined macros.
struct predefined_macros_grammar :
public boost::spirit::grammar<predefined_macros_grammar>
{
template <typename ScannerT>
struct definition
{
// 'normal' (parse_tree generating) rule type
typedef boost::spirit::rule<ScannerT> rule_t;
rule_t plain_define, macro_definition, macro_parameters;
definition(predefined_macros_grammar const &self)
{
// import the spirit and cpplexer namespaces here
using namespace boost::spirit;
using namespace boost::wave;
using namespace boost::wave::util;
// save the rule id's for later use
self.rule_ids.plain_define_id = plain_define.id().to_long();
self.rule_ids.macro_parameters_id = macro_parameters.id().to_long();
self.rule_ids.macro_definition_id = macro_definition.id().to_long();
// recognizes command line defined macro syntax, i.e.
// -DMACRO
// -DMACRO=
// -DMACRO=value
// -DMACRO(x)
// -DMACRO(x)=
// -DMACRO(x)=value
// This grammar resembles the overall structure of the cpp_grammar to
// make it possible to reuse the parse tree traversal code
plain_define
= ( ch_p(T_IDENTIFIER)
| pattern_p(KeywordTokenType, TokenTypeMask)
)
>> !macro_parameters
>> !macro_definition
;
// parameter list
macro_parameters
= confix_p(
no_node_d[ch_p(T_LEFTPAREN) >> *ch_p(T_SPACE)],
!list_p(
( ch_p(T_IDENTIFIER)
| pattern_p(KeywordTokenType, TokenTypeMask)
),
no_node_d
[
*ch_p(T_SPACE) >> ch_p(T_COMMA) >> *ch_p(T_SPACE)
]
),
no_node_d[*ch_p(T_SPACE) >> ch_p(T_RIGHTPAREN)]
)
;
// macro body (anything left until eol)
macro_definition
= no_node_d[ch_p(T_ASSIGN)]
>> *anychar_p
;
BOOST_SPIRIT_DEBUG_TRACE_RULE(plain_define, TRACE_PREDEF_MACROS_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_definition, TRACE_PREDEF_MACROS_GRAMMAR);
BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_parameters, TRACE_PREDEF_MACROS_GRAMMAR);
}
// start rule of this grammar
rule_t const& start() const
{ return plain_define; }
};
predefined_macros_grammar_rule_ids &rule_ids;
predefined_macros_grammar(predefined_macros_grammar_rule_ids &rule_ids_)
: rule_ids(rule_ids_)
{
BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this,
"predefined_macros_grammar", TRACE_PREDEF_MACROS_GRAMMAR);
}
};
///////////////////////////////////////////////////////////////////////////////
#undef TRACE_PREDEF_MACROS_GRAMMAR
///////////////////////////////////////////////////////////////////////////////
//
// The following parse function is defined here, to allow the separation of
// the compilation of the cpp_predefined_macros_grammar from the function
// using it.
//
///////////////////////////////////////////////////////////////////////////////
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
#define BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE
#else
#define BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE inline
#endif
template <typename LexIteratorT>
BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE
boost::spirit::tree_parse_info<LexIteratorT>
predefined_macros_grammar_gen<LexIteratorT>::parse_predefined_macro (
LexIteratorT const &first, LexIteratorT const &last)
{
static predefined_macros_grammar g(rule_ids);
return boost::spirit::pt_parse (first, last, g);
}
#undef BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE
///////////////////////////////////////////////////////////////////////////////
} // namespace grammars
} // namespace wave
} // namespace boost
#endif // !defined(CPP_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED)

View File

@@ -1,137 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Definition of the various language support constants
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(LANGUAGE_SUPPORT_HPP_93EDD057_2DEF_44BC_BC9F_FDABB9F51AFA_INCLUDED)
#define LANGUAGE_SUPPORT_HPP_93EDD057_2DEF_44BC_BC9F_FDABB9F51AFA_INCLUDED
#include <boost/wave/wave_config.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
enum language_support {
// support flags for C++98
support_normal = 0x01,
support_cpp = support_normal,
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
// support flags for C99
support_variadics = 0x02,
support_c99 = support_variadics,
#endif
};
///////////////////////////////////////////////////////////////////////////////
//
// need_cpp
//
// Extract, if the language to support is C++98
//
///////////////////////////////////////////////////////////////////////////////
inline bool
need_cpp(language_support language)
{
return language == support_cpp;
}
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
///////////////////////////////////////////////////////////////////////////////
//
// need_variadics
//
// Extract, if the language to support needs variadics support
//
///////////////////////////////////////////////////////////////////////////////
inline bool
need_variadics(language_support language)
{
return (language & support_variadics) ? true : false;
}
///////////////////////////////////////////////////////////////////////////////
//
// enable_variadics
//
// Set variadics support in the language to support
//
///////////////////////////////////////////////////////////////////////////////
inline language_support
enable_variadics(language_support language, bool enable = true)
{
if (enable)
return static_cast<language_support>(language | support_variadics);
return static_cast<language_support>(language & ~support_variadics);
}
///////////////////////////////////////////////////////////////////////////////
//
// need_c99
//
// Extract, if the language to support is C99
//
///////////////////////////////////////////////////////////////////////////////
inline bool
need_c99(language_support language)
{
return language == support_c99;
}
///////////////////////////////////////////////////////////////////////////////
//
// enable_c99
//
// Set, whether to support C99 (alternatively C++98 is supported)
//
///////////////////////////////////////////////////////////////////////////////
inline language_support
enable_c99(bool enable = true)
{
return enable ? support_c99 : support_cpp;
}
#else // BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
///////////////////////////////////////////////////////////////////////////////
inline bool
need_variadics(language_support language)
{
return false;
}
///////////////////////////////////////////////////////////////////////////////
inline language_support
enable_variadics(language_support language, bool enable = true)
{
return language;
}
//////////////////////////////////////////////////////////////////////////////
inline bool
need_c99(language_support language)
{
return false;
}
///////////////////////////////////////////////////////////////////////////////
inline language_support
enable_c99(bool enable = true)
{
return support_cpp;
}
#endif // BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
///////////////////////////////////////////////////////////////////////////////
} // namespace wave
} // namespace boost
#endif // !defined(LANGUAGE_SUPPORT_HPP_93EDD057_2DEF_44BC_BC9F_FDABB9F51AFA_INCLUDED)

View File

@@ -1,210 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(PREPROCESSING_HOOKS_HPP_338DE478_A13C_4B63_9BA9_041C917793B8_INCLUDED)
#define PREPROCESSING_HOOKS_HPP_338DE478_A13C_4B63_9BA9_041C917793B8_INCLUDED
#include <vector>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace context_policies {
///////////////////////////////////////////////////////////////////////////////
//
// The default_preprocessing_hooks class is a placeholder for all
// preprocessing hooks called from inside the preprocessing engine
//
///////////////////////////////////////////////////////////////////////////////
struct default_preprocessing_hooks {
///////////////////////////////////////////////////////////////////////////
//
// The function 'expanding_function_like_macro' is called, whenever a
// function-like macro is to be expanded.
//
// The macroname parameter marks the position, where the macro to expand
// is defined.
// The formal_args parameter holds the formal arguments used during the
// definition of the macro.
// The definition parameter holds the macro definition for the macro to
// trace.
//
// The macro call parameter marks the position, where this macro invoked.
// The arguments parameter holds the macro arguments used during the
// invocation of the macro
//
///////////////////////////////////////////////////////////////////////////
template <typename TokenT, typename ContainerT>
void expanding_function_like_macro(
TokenT const &macrodef, std::vector<TokenT> const &formal_args,
ContainerT const &definition,
TokenT const &macrocall, std::vector<ContainerT> const &arguments)
{}
///////////////////////////////////////////////////////////////////////////
//
// The function 'expanding_object_like_macro' is called, whenever a
// object-like macro is to be expanded .
//
// The macroname parameter marks the position, where the macro to expand
// is defined.
// The definition parameter holds the macro definition for the macro to
// trace.
//
// The macro call parameter marks the position, where this macro invoked.
//
///////////////////////////////////////////////////////////////////////////
template <typename TokenT, typename ContainerT>
void expanding_object_like_macro(TokenT const &macro,
ContainerT const &definition, TokenT const &macrocall)
{}
///////////////////////////////////////////////////////////////////////////
//
// The function 'expanded_macro' is called, whenever the expansion of a
// macro is finished but before the rescanning process starts.
//
// The parameter 'result' contains the token sequence generated as the
// result of the macro expansion.
//
///////////////////////////////////////////////////////////////////////////
template <typename ContainerT>
void expanded_macro(ContainerT const &result)
{}
///////////////////////////////////////////////////////////////////////////
//
// The function 'rescanned_macro' is called, whenever the rescanning of a
// macro is finished.
//
// The parameter 'result' contains the token sequence generated as the
// result of the rescanning.
//
///////////////////////////////////////////////////////////////////////////
template <typename ContainerT>
void rescanned_macro(ContainerT const &result)
{}
///////////////////////////////////////////////////////////////////////////
//
// The function 'opened_include_file' is called, whenever a file referred
// by an #include directive was successfully located and opened.
//
// The parameter 'filename' contains the full file system path of the
// opened file.
//
// The include_depth parameter contains the current include file depth.
//
// The is_system_include parameter denotes, if the given file was found
// as a result of a #include <...> directive.
//
///////////////////////////////////////////////////////////////////////////
void
opened_include_file(std::string const &filename, std::size_t include_depth,
bool is_system_include)
{}
///////////////////////////////////////////////////////////////////////////
//
// The function 'returning_from_include_file' is called, whenever an
// included file is about to be closed after it's processing is complete.
//
///////////////////////////////////////////////////////////////////////////
void
returning_from_include_file()
{}
///////////////////////////////////////////////////////////////////////////
//
// The function 'interpret_pragma' is called, whenever a #pragma wave
// directive is found, which isn't known to the core Wave library.
//
// The parameter 'ctx' is a reference to the context object used for
// instantiating the preprocessing iterators by the user.
//
// The parameter 'pending' may be used to push tokens back into the input
// stream, which are to be used as the replacement text for the whole
// #pragma wave() directive.
//
// The parameter 'option' contains the name of the interpreted pragma.
//
// The parameter 'values' holds the values of the parameter provided to
// the pragma operator.
//
// The parameter 'act_token' contains the actual #pragma token, which may
// be used for error output.
//
// If the return value is 'false', the whole #pragma directive is
// interpreted as unknown and a corresponding error message is issued. A
// return value of 'true' signs a successful interpretation of the given
// #pragma.
//
///////////////////////////////////////////////////////////////////////////
template <typename ContextT, typename ContainerT>
bool
interpret_pragma(ContextT const &ctx, ContainerT &pending,
typename ContextT::token_type const &option, ContainerT const &values,
typename ContextT::token_type const &act_token)
{
return false;
}
///////////////////////////////////////////////////////////////////////////
//
// The function 'defined_macro' is called, whenever a macro was defined
// successfully.
//
// The parameter 'name' is a reference to the token holding the macro name.
//
// The parameter 'is_functionlike' is set to true, whenever the newly
// defined macro is defined as a function like macro.
//
// The parameter 'parameters' holds the parameter tokens for the macro
// definition. If the macro has no parameters or if it is a object like
// macro, then this container is empty.
//
// The parameter 'definition' contains the token sequence given as the
// replacement sequence (definition part) of the newly defined macro.
//
// The parameter 'is_predefined' is set to true for all macros predefined
// during the initialisation pahase of the library.
//
///////////////////////////////////////////////////////////////////////////
template <typename TokenT, typename ParametersT, typename DefinitionT>
void
defined_macro(TokenT const &macro_name, bool is_functionlike,
ParametersT const &parameters, DefinitionT const &definition,
bool is_predefined)
{}
///////////////////////////////////////////////////////////////////////////
//
// The function 'undefined_macro' is called, whenever a macro definition
// was removed successfully.
//
// The parameter 'name' holds the name of the macro, which definition was
// removed.
//
///////////////////////////////////////////////////////////////////////////
template <typename StringT>
void
undefined_macro(StringT const &macro_name)
{}
};
///////////////////////////////////////////////////////////////////////////////
} // namespace context_policies
} // namespace wave
} // namespace boost
#endif // !defined(PREPROCESSING_HOOKS_HPP_338DE478_A13C_4B63_9BA9_041C917793B8_INCLUDED)

View File

@@ -1,666 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
The definition of a default set of token identifiers and related
functions.
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(TOKEN_IDS_HPP_414E9A58_F079_4789_8AFF_513815CE475B_INCLUDED)
#define TOKEN_IDS_HPP_414E9A58_F079_4789_8AFF_513815CE475B_INCLUDED
#include <string>
#include <boost/assert.hpp>
#include <boost/wave/wave_config.hpp>
///////////////////////////////////////////////////////////////////////////////
// Allow external redefinition of the token identifiers to use
#if !defined(BOOST_WAVE_TOKEN_IDS_DEFINED)
#define BOOST_WAVE_TOKEN_IDS_DEFINED
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
///////////////////////////////////////////////////////////////////////////////
// assemble tokenid's
#define TOKEN_FROM_ID(id, cat) ((id) | (cat))
#define ID_FROM_TOKEN(tok) ((tok) & ~TokenTypeMask)
#define BASEID_FROM_TOKEN(tok) ((tok) & ~ExtTokenTypeMask)
#define CATEGORY_FROM_TOKEN(tok) ((tok) & TokenTypeMask)
#define EXTCATEGORY_FROM_TOKEN(tok) ((tok) & ExtTokenTypeMask)
#define IS_CATEGORY(tok, cat) \
((CATEGORY_FROM_TOKEN(tok) == (cat)) ? true : false) \
/**/
#define IS_EXTCATEGORY(tok, cat) \
((EXTCATEGORY_FROM_TOKEN(tok) == (cat)) ? true : false) \
/**/
///////////////////////////////////////////////////////////////////////////////
// the token_category helps to classify the different token types
enum token_category {
IdentifierTokenType = 0x10000000,
ParameterTokenType = 0x11000000,
ExtParameterTokenType = 0x11100000,
KeywordTokenType = 0x20000000,
OperatorTokenType = 0x30000000,
LiteralTokenType = 0x40000000,
IntegerLiteralTokenType = 0x41000000,
FloatingLiteralTokenType = 0x42000000,
StringLiteralTokenType = 0x43000000,
CharacterLiteralTokenType = 0x44000000,
BoolLiteralTokenType = 0x45000000,
PPTokenType = 0x50000000,
PPConditionalTokenType = 0x50100000,
UnknownTokenType = 0xA0000000,
EOLTokenType = 0xB0000000,
EOFTokenType = 0xC0000000,
WhiteSpaceTokenType = 0xD0000000,
InternalTokenType = 0xE0000000,
TokenTypeMask = 0xFF000000,
AltTokenType = 0x00100000,
TriGraphTokenType = 0x00200000,
AltExtTokenType = 0x00500000, // and, bit_and etc.
ExtTokenTypeMask = 0xFFF00000,
TokenValueMask = 0x000FFFFF,
MainTokenMask = TokenTypeMask|TokenValueMask,
};
///////////////////////////////////////////////////////////////////////////////
// the token_id assigns unique numbers to the different C++ lexemes
enum token_id {
T_FIRST_TOKEN = 256,
T_AND = TOKEN_FROM_ID(T_FIRST_TOKEN, OperatorTokenType),
T_AND_ALT = TOKEN_FROM_ID(T_FIRST_TOKEN, OperatorTokenType|AltExtTokenType),
T_ANDAND = TOKEN_FROM_ID(257, OperatorTokenType),
T_ANDAND_ALT = TOKEN_FROM_ID(257, OperatorTokenType|AltExtTokenType),
T_ASSIGN = TOKEN_FROM_ID(258, OperatorTokenType),
T_ANDASSIGN = TOKEN_FROM_ID(259, OperatorTokenType),
T_ANDASSIGN_ALT = TOKEN_FROM_ID(259, OperatorTokenType|AltExtTokenType),
T_OR = TOKEN_FROM_ID(260, OperatorTokenType),
T_OR_ALT = TOKEN_FROM_ID(260, OperatorTokenType|AltExtTokenType),
T_OR_TRIGRAPH = TOKEN_FROM_ID(260, OperatorTokenType|TriGraphTokenType),
T_ORASSIGN = TOKEN_FROM_ID(261, OperatorTokenType),
T_ORASSIGN_ALT = TOKEN_FROM_ID(261, OperatorTokenType|AltExtTokenType),
T_XOR = TOKEN_FROM_ID(262, OperatorTokenType),
T_XOR_ALT = TOKEN_FROM_ID(262, OperatorTokenType|AltExtTokenType),
T_XOR_TRIGRAPH = TOKEN_FROM_ID(262, OperatorTokenType|TriGraphTokenType),
T_XORASSIGN = TOKEN_FROM_ID(263, OperatorTokenType),
T_XORASSIGN_ALT = TOKEN_FROM_ID(263, OperatorTokenType|AltExtTokenType),
T_COMMA = TOKEN_FROM_ID(264, OperatorTokenType),
T_COLON = TOKEN_FROM_ID(265, OperatorTokenType),
T_DIVIDE = TOKEN_FROM_ID(266, OperatorTokenType),
T_DIVIDEASSIGN = TOKEN_FROM_ID(267, OperatorTokenType),
T_DOT = TOKEN_FROM_ID(268, OperatorTokenType),
T_DOTSTAR = TOKEN_FROM_ID(269, OperatorTokenType),
T_ELLIPSIS = TOKEN_FROM_ID(270, OperatorTokenType),
T_EQUAL = TOKEN_FROM_ID(271, OperatorTokenType),
T_GREATER = TOKEN_FROM_ID(272, OperatorTokenType),
T_GREATEREQUAL = TOKEN_FROM_ID(273, OperatorTokenType),
T_LEFTBRACE = TOKEN_FROM_ID(274, OperatorTokenType),
T_LEFTBRACE_ALT = TOKEN_FROM_ID(274, OperatorTokenType|AltTokenType),
T_LEFTBRACE_TRIGRAPH = TOKEN_FROM_ID(274, OperatorTokenType|TriGraphTokenType),
T_LESS = TOKEN_FROM_ID(275, OperatorTokenType),
T_LESSEQUAL = TOKEN_FROM_ID(276, OperatorTokenType),
T_LEFTPAREN = TOKEN_FROM_ID(277, OperatorTokenType),
T_LEFTBRACKET = TOKEN_FROM_ID(278, OperatorTokenType),
T_LEFTBRACKET_ALT = TOKEN_FROM_ID(278, OperatorTokenType|AltTokenType),
T_LEFTBRACKET_TRIGRAPH = TOKEN_FROM_ID(278, OperatorTokenType|TriGraphTokenType),
T_MINUS = TOKEN_FROM_ID(279, OperatorTokenType),
T_MINUSASSIGN = TOKEN_FROM_ID(280, OperatorTokenType),
T_MINUSMINUS = TOKEN_FROM_ID(281, OperatorTokenType),
T_PERCENT = TOKEN_FROM_ID(282, OperatorTokenType),
T_PERCENTASSIGN = TOKEN_FROM_ID(283, OperatorTokenType),
T_NOT = TOKEN_FROM_ID(284, OperatorTokenType),
T_NOT_ALT = TOKEN_FROM_ID(284, OperatorTokenType|AltExtTokenType),
T_NOTEQUAL = TOKEN_FROM_ID(285, OperatorTokenType),
T_NOTEQUAL_ALT = TOKEN_FROM_ID(285, OperatorTokenType|AltExtTokenType),
T_OROR = TOKEN_FROM_ID(286, OperatorTokenType),
T_OROR_ALT = TOKEN_FROM_ID(286, OperatorTokenType|AltExtTokenType),
T_PLUS = TOKEN_FROM_ID(287, OperatorTokenType),
T_PLUSASSIGN = TOKEN_FROM_ID(288, OperatorTokenType),
T_PLUSPLUS = TOKEN_FROM_ID(289, OperatorTokenType),
T_ARROW = TOKEN_FROM_ID(290, OperatorTokenType),
T_ARROWSTAR = TOKEN_FROM_ID(291, OperatorTokenType),
T_QUESTION_MARK = TOKEN_FROM_ID(292, OperatorTokenType),
T_RIGHTBRACE = TOKEN_FROM_ID(293, OperatorTokenType),
T_RIGHTBRACE_ALT = TOKEN_FROM_ID(293, OperatorTokenType|AltTokenType),
T_RIGHTBRACE_TRIGRAPH = TOKEN_FROM_ID(293, OperatorTokenType|TriGraphTokenType),
T_RIGHTPAREN = TOKEN_FROM_ID(294, OperatorTokenType),
T_RIGHTBRACKET = TOKEN_FROM_ID(295, OperatorTokenType),
T_RIGHTBRACKET_ALT = TOKEN_FROM_ID(295, OperatorTokenType|AltTokenType),
T_RIGHTBRACKET_TRIGRAPH = TOKEN_FROM_ID(295, OperatorTokenType|TriGraphTokenType),
T_COLON_COLON = TOKEN_FROM_ID(296, OperatorTokenType),
T_SEMICOLON = TOKEN_FROM_ID(297, OperatorTokenType),
T_SHIFTLEFT = TOKEN_FROM_ID(298, OperatorTokenType),
T_SHIFTLEFTASSIGN = TOKEN_FROM_ID(299, OperatorTokenType),
T_SHIFTRIGHT = TOKEN_FROM_ID(300, OperatorTokenType),
T_SHIFTRIGHTASSIGN = TOKEN_FROM_ID(301, OperatorTokenType),
T_STAR = TOKEN_FROM_ID(302, OperatorTokenType),
T_COMPL = TOKEN_FROM_ID(303, OperatorTokenType),
T_COMPL_ALT = TOKEN_FROM_ID(303, OperatorTokenType|AltExtTokenType),
T_COMPL_TRIGRAPH = TOKEN_FROM_ID(303, OperatorTokenType|TriGraphTokenType),
T_STARASSIGN = TOKEN_FROM_ID(304, OperatorTokenType),
T_ASM = TOKEN_FROM_ID(305, KeywordTokenType),
T_AUTO = TOKEN_FROM_ID(306, KeywordTokenType),
T_BOOL = TOKEN_FROM_ID(307, KeywordTokenType),
T_FALSE = TOKEN_FROM_ID(308, BoolLiteralTokenType),
T_TRUE = TOKEN_FROM_ID(309, BoolLiteralTokenType),
T_BREAK = TOKEN_FROM_ID(310, KeywordTokenType),
T_CASE = TOKEN_FROM_ID(311, KeywordTokenType),
T_CATCH = TOKEN_FROM_ID(312, KeywordTokenType),
T_CHAR = TOKEN_FROM_ID(313, KeywordTokenType),
T_CLASS = TOKEN_FROM_ID(314, KeywordTokenType),
T_CONST = TOKEN_FROM_ID(315, KeywordTokenType),
T_CONSTCAST = TOKEN_FROM_ID(316, KeywordTokenType),
T_CONTINUE = TOKEN_FROM_ID(317, KeywordTokenType),
T_DEFAULT = TOKEN_FROM_ID(318, KeywordTokenType),
T_DEFINED = TOKEN_FROM_ID(319, KeywordTokenType),
T_DELETE = TOKEN_FROM_ID(320, KeywordTokenType),
T_DO = TOKEN_FROM_ID(321, KeywordTokenType),
T_DOUBLE = TOKEN_FROM_ID(322, KeywordTokenType),
T_DYNAMICCAST = TOKEN_FROM_ID(323, KeywordTokenType),
T_ELSE = TOKEN_FROM_ID(324, KeywordTokenType),
T_ENUM = TOKEN_FROM_ID(325, KeywordTokenType),
T_EXPLICIT = TOKEN_FROM_ID(326, KeywordTokenType),
T_EXPORT = TOKEN_FROM_ID(327, KeywordTokenType),
T_EXTERN = TOKEN_FROM_ID(328, KeywordTokenType),
T_FLOAT = TOKEN_FROM_ID(329, KeywordTokenType),
T_FOR = TOKEN_FROM_ID(330, KeywordTokenType),
T_FRIEND = TOKEN_FROM_ID(331, KeywordTokenType),
T_GOTO = TOKEN_FROM_ID(332, KeywordTokenType),
T_IF = TOKEN_FROM_ID(333, KeywordTokenType),
T_INLINE = TOKEN_FROM_ID(334, KeywordTokenType),
T_INT = TOKEN_FROM_ID(335, KeywordTokenType),
T_LONG = TOKEN_FROM_ID(336, KeywordTokenType),
T_MUTABLE = TOKEN_FROM_ID(337, KeywordTokenType),
T_NAMESPACE = TOKEN_FROM_ID(338, KeywordTokenType),
T_NEW = TOKEN_FROM_ID(339, KeywordTokenType),
T_OPERATOR = TOKEN_FROM_ID(340, KeywordTokenType),
T_PRIVATE = TOKEN_FROM_ID(341, KeywordTokenType),
T_PROTECTED = TOKEN_FROM_ID(342, KeywordTokenType),
T_PUBLIC = TOKEN_FROM_ID(343, KeywordTokenType),
T_REGISTER = TOKEN_FROM_ID(344, KeywordTokenType),
T_REINTERPRETCAST = TOKEN_FROM_ID(345, KeywordTokenType),
T_RETURN = TOKEN_FROM_ID(346, KeywordTokenType),
T_SHORT = TOKEN_FROM_ID(347, KeywordTokenType),
T_SIGNED = TOKEN_FROM_ID(348, KeywordTokenType),
T_SIZEOF = TOKEN_FROM_ID(349, KeywordTokenType),
T_STATIC = TOKEN_FROM_ID(350, KeywordTokenType),
T_STATICCAST = TOKEN_FROM_ID(351, KeywordTokenType),
T_STRUCT = TOKEN_FROM_ID(352, KeywordTokenType),
T_SWITCH = TOKEN_FROM_ID(353, KeywordTokenType),
T_TEMPLATE = TOKEN_FROM_ID(354, KeywordTokenType),
T_THIS = TOKEN_FROM_ID(355, KeywordTokenType),
T_THROW = TOKEN_FROM_ID(356, KeywordTokenType),
T_TRY = TOKEN_FROM_ID(357, KeywordTokenType),
T_TYPEDEF = TOKEN_FROM_ID(358, KeywordTokenType),
T_TYPEID = TOKEN_FROM_ID(359, KeywordTokenType),
T_TYPENAME = TOKEN_FROM_ID(360, KeywordTokenType),
T_UNION = TOKEN_FROM_ID(361, KeywordTokenType),
T_UNSIGNED = TOKEN_FROM_ID(362, KeywordTokenType),
T_USING = TOKEN_FROM_ID(363, KeywordTokenType),
T_VIRTUAL = TOKEN_FROM_ID(364, KeywordTokenType),
T_VOID = TOKEN_FROM_ID(365, KeywordTokenType),
T_VOLATILE = TOKEN_FROM_ID(366, KeywordTokenType),
T_WCHART = TOKEN_FROM_ID(367, KeywordTokenType),
T_WHILE = TOKEN_FROM_ID(368, KeywordTokenType),
T_PP_DEFINE = TOKEN_FROM_ID(369, PPTokenType),
T_PP_IF = TOKEN_FROM_ID(370, PPConditionalTokenType),
T_PP_IFDEF = TOKEN_FROM_ID(371, PPConditionalTokenType),
T_PP_IFNDEF = TOKEN_FROM_ID(372, PPConditionalTokenType),
T_PP_ELSE = TOKEN_FROM_ID(373, PPConditionalTokenType),
T_PP_ELIF = TOKEN_FROM_ID(374, PPConditionalTokenType),
T_PP_ENDIF = TOKEN_FROM_ID(375, PPConditionalTokenType),
T_PP_ERROR = TOKEN_FROM_ID(376, PPTokenType),
T_PP_LINE = TOKEN_FROM_ID(377, PPTokenType),
T_PP_PRAGMA = TOKEN_FROM_ID(378, PPTokenType),
T_PP_UNDEF = TOKEN_FROM_ID(379, PPTokenType),
T_PP_WARNING = TOKEN_FROM_ID(380, PPTokenType),
T_IDENTIFIER = TOKEN_FROM_ID(381, IdentifierTokenType),
T_OCTALINT = TOKEN_FROM_ID(382, IntegerLiteralTokenType),
T_DECIMALINT = TOKEN_FROM_ID(383, IntegerLiteralTokenType),
T_HEXAINT = TOKEN_FROM_ID(384, IntegerLiteralTokenType),
T_INTLIT = TOKEN_FROM_ID(385, IntegerLiteralTokenType),
T_FLOATLIT = TOKEN_FROM_ID(386, FloatingLiteralTokenType),
T_FIXEDPOINTLIT = TOKEN_FROM_ID(386, FloatingLiteralTokenType|AltTokenType), // IDL specific
T_CCOMMENT = TOKEN_FROM_ID(387, WhiteSpaceTokenType),
T_CPPCOMMENT = TOKEN_FROM_ID(388, WhiteSpaceTokenType),
T_CHARLIT = TOKEN_FROM_ID(389, CharacterLiteralTokenType),
T_STRINGLIT = TOKEN_FROM_ID(390, StringLiteralTokenType),
T_CONTLINE = TOKEN_FROM_ID(391, EOLTokenType),
T_SPACE = TOKEN_FROM_ID(392, WhiteSpaceTokenType),
T_SPACE2 = TOKEN_FROM_ID(393, WhiteSpaceTokenType),
T_NEWLINE = TOKEN_FROM_ID(394, EOLTokenType),
T_POUND_POUND = TOKEN_FROM_ID(395, OperatorTokenType),
T_POUND_POUND_ALT = TOKEN_FROM_ID(395, OperatorTokenType|AltTokenType),
T_POUND_POUND_TRIGRAPH = TOKEN_FROM_ID(395, OperatorTokenType|TriGraphTokenType),
T_POUND = TOKEN_FROM_ID(396, OperatorTokenType),
T_POUND_ALT = TOKEN_FROM_ID(396, OperatorTokenType|AltTokenType),
T_POUND_TRIGRAPH = TOKEN_FROM_ID(396, OperatorTokenType|TriGraphTokenType),
T_ANY = TOKEN_FROM_ID(397, UnknownTokenType),
T_PP_INCLUDE = TOKEN_FROM_ID(398, PPTokenType),
T_PP_QHEADER = TOKEN_FROM_ID(399, PPTokenType),
T_PP_HHEADER = TOKEN_FROM_ID(400, PPTokenType),
T_PP_INCLUDE_NEXT = TOKEN_FROM_ID(398, PPTokenType|AltTokenType),
T_PP_QHEADER_NEXT = TOKEN_FROM_ID(399, PPTokenType|AltTokenType),
T_PP_HHEADER_NEXT = TOKEN_FROM_ID(400, PPTokenType|AltTokenType),
T_EOF = TOKEN_FROM_ID(401, EOFTokenType), // end of file reached
T_EOI = TOKEN_FROM_ID(402, EOFTokenType), // end of input reached
// MS extensions
T_MSEXT_INT8 = TOKEN_FROM_ID(403, KeywordTokenType),
T_MSEXT_INT16 = TOKEN_FROM_ID(404, KeywordTokenType),
T_MSEXT_INT32 = TOKEN_FROM_ID(405, KeywordTokenType),
T_MSEXT_INT64 = TOKEN_FROM_ID(406, KeywordTokenType),
T_MSEXT_BASED = TOKEN_FROM_ID(407, KeywordTokenType),
T_MSEXT_DECLSPEC = TOKEN_FROM_ID(408, KeywordTokenType),
T_MSEXT_CDECL = TOKEN_FROM_ID(409, KeywordTokenType),
T_MSEXT_FASTCALL = TOKEN_FROM_ID(410, KeywordTokenType),
T_MSEXT_STDCALL = TOKEN_FROM_ID(411, KeywordTokenType),
T_MSEXT_TRY = TOKEN_FROM_ID(412, KeywordTokenType),
T_MSEXT_EXCEPT = TOKEN_FROM_ID(413, KeywordTokenType),
T_MSEXT_FINALLY = TOKEN_FROM_ID(414, KeywordTokenType),
T_MSEXT_LEAVE = TOKEN_FROM_ID(415, KeywordTokenType),
T_MSEXT_INLINE = TOKEN_FROM_ID(416, KeywordTokenType),
T_MSEXT_ASM = TOKEN_FROM_ID(417, KeywordTokenType),
T_LAST_TOKEN_ID,
T_LAST_TOKEN = ID_FROM_TOKEN(T_LAST_TOKEN_ID),
// pseudo tokens to help streamlining macro replacement, these should not
// returned from the lexer nor should these be returned from the pp-iterator
T_NONREPLACABLE_IDENTIFIER = TOKEN_FROM_ID(T_LAST_TOKEN+1, IdentifierTokenType),
T_PLACEHOLDER = TOKEN_FROM_ID(T_LAST_TOKEN+2, WhiteSpaceTokenType),
T_PLACEMARKER = TOKEN_FROM_ID(T_LAST_TOKEN+3, InternalTokenType),
T_PARAMETERBASE = TOKEN_FROM_ID(T_LAST_TOKEN+4, ParameterTokenType),
T_EXTPARAMETERBASE = TOKEN_FROM_ID(T_LAST_TOKEN+5, ExtParameterTokenType),
};
///////////////////////////////////////////////////////////////////////////////
// redefine the TOKEN_FROM_ID macro to be more type safe
#undef TOKEN_FROM_ID
#define TOKEN_FROM_ID(id, cat) boost::wave::token_id((id) | (cat))
#define BASE_TOKEN(tok) \
boost::wave::token_id((tok) & MainTokenMask) \
/**/
///////////////////////////////////////////////////////////////////////////////
// return a token name
inline BOOST_WAVE_STRINGTYPE
get_token_name(token_id tokid)
{
// Table of token names
//
// Please note that the sequence of token names must match the sequence of
// token id's defined in then enum token_id above.
static char const *tok_names[] = {
/* 256 */ "AND",
/* 257 */ "ANDAND",
/* 258 */ "ASSIGN",
/* 259 */ "ANDASSIGN",
/* 260 */ "OR",
/* 261 */ "ORASSIGN",
/* 262 */ "XOR",
/* 263 */ "XORASSIGN",
/* 264 */ "COMMA",
/* 265 */ "COLON",
/* 266 */ "DIVIDE",
/* 267 */ "DIVIDEASSIGN",
/* 268 */ "DOT",
/* 269 */ "DOTSTAR",
/* 270 */ "ELLIPSIS",
/* 271 */ "EQUAL",
/* 272 */ "GREATER",
/* 273 */ "GREATEREQUAL",
/* 274 */ "LEFTBRACE",
/* 275 */ "LESS",
/* 276 */ "LESSEQUAL",
/* 277 */ "LEFTPAREN",
/* 278 */ "LEFTBRACKET",
/* 279 */ "MINUS",
/* 280 */ "MINUSASSIGN",
/* 281 */ "MINUSMINUS",
/* 282 */ "PERCENT",
/* 283 */ "PERCENTASSIGN",
/* 284 */ "NOT",
/* 285 */ "NOTEQUAL",
/* 286 */ "OROR",
/* 287 */ "PLUS",
/* 288 */ "PLUSASSIGN",
/* 289 */ "PLUSPLUS",
/* 290 */ "ARROW",
/* 291 */ "ARROWSTAR",
/* 292 */ "QUESTION_MARK",
/* 293 */ "RIGHTBRACE",
/* 294 */ "RIGHTPAREN",
/* 295 */ "RIGHTBRACKET",
/* 296 */ "COLON_COLON",
/* 297 */ "SEMICOLON",
/* 298 */ "SHIFTLEFT",
/* 299 */ "SHIFTLEFTASSIGN",
/* 300 */ "SHIFTRIGHT",
/* 301 */ "SHIFTRIGHTASSIGN",
/* 302 */ "STAR",
/* 303 */ "COMPL",
/* 304 */ "STARASSIGN",
/* 305 */ "ASM",
/* 306 */ "AUTO",
/* 307 */ "BOOL",
/* 308 */ "FALSE",
/* 309 */ "TRUE",
/* 310 */ "BREAK",
/* 311 */ "CASE",
/* 312 */ "CATCH",
/* 313 */ "CHAR",
/* 314 */ "CLASS",
/* 315 */ "CONST",
/* 316 */ "CONSTCAST",
/* 317 */ "CONTINUE",
/* 318 */ "DEFAULT",
/* 319 */ "DEFINED",
/* 320 */ "DELETE",
/* 321 */ "DO",
/* 322 */ "DOUBLE",
/* 323 */ "DYNAMICCAST",
/* 324 */ "ELSE",
/* 325 */ "ENUM",
/* 326 */ "EXPLICIT",
/* 327 */ "EXPORT",
/* 328 */ "EXTERN",
/* 329 */ "FLOAT",
/* 330 */ "FOR",
/* 331 */ "FRIEND",
/* 332 */ "GOTO",
/* 333 */ "IF",
/* 334 */ "INLINE",
/* 335 */ "INT",
/* 336 */ "LONG",
/* 337 */ "MUTABLE",
/* 338 */ "NAMESPACE",
/* 339 */ "NEW",
/* 340 */ "OPERATOR",
/* 341 */ "PRIVATE",
/* 342 */ "PROTECTED",
/* 343 */ "PUBLIC",
/* 344 */ "REGISTER",
/* 345 */ "REINTERPRETCAST",
/* 346 */ "RETURN",
/* 347 */ "SHORT",
/* 348 */ "SIGNED",
/* 349 */ "SIZEOF",
/* 350 */ "STATIC",
/* 351 */ "STATICCAST",
/* 352 */ "STRUCT",
/* 353 */ "SWITCH",
/* 354 */ "TEMPLATE",
/* 355 */ "THIS",
/* 356 */ "THROW",
/* 357 */ "TRY",
/* 358 */ "TYPEDEF",
/* 359 */ "TYPEID",
/* 360 */ "TYPENAME",
/* 361 */ "UNION",
/* 362 */ "UNSIGNED",
/* 363 */ "USING",
/* 364 */ "VIRTUAL",
/* 365 */ "VOID",
/* 366 */ "VOLATILE",
/* 367 */ "WCHART",
/* 368 */ "WHILE",
/* 369 */ "PP_DEFINE",
/* 370 */ "PP_IF",
/* 371 */ "PP_IFDEF",
/* 372 */ "PP_IFNDEF",
/* 373 */ "PP_ELSE",
/* 374 */ "PP_ELIF",
/* 375 */ "PP_ENDIF",
/* 376 */ "PP_ERROR",
/* 377 */ "PP_LINE",
/* 378 */ "PP_PRAGMA",
/* 379 */ "PP_UNDEF",
/* 380 */ "PP_WARNING",
/* 381 */ "IDENTIFIER",
/* 382 */ "OCTALINT",
/* 383 */ "DECIMALINT",
/* 384 */ "HEXAINT",
/* 385 */ "INTLIT",
/* 386 */ "FLOATLIT",
/* 387 */ "CCOMMENT",
/* 388 */ "CPPCOMMENT",
/* 389 */ "CHARLIT",
/* 390 */ "STRINGLIT",
/* 391 */ "CONTLINE",
/* 392 */ "SPACE",
/* 393 */ "SPACE2",
/* 394 */ "NEWLINE",
/* 395 */ "POUND_POUND",
/* 396 */ "POUND",
/* 397 */ "ANY",
/* 398 */ "PP_INCLUDE",
/* 399 */ "PP_QHEADER",
/* 400 */ "PP_HHEADER",
/* 401 */ "EOF",
/* 402 */ "EOI",
// MS extensions
/* 403 */ "MSEXT_INT8",
/* 404 */ "MSEXT_INT16",
/* 405 */ "MSEXT_INT32",
/* 406 */ "MSEXT_INT64",
/* 407 */ "MSEXT_BASED",
/* 408 */ "MSEXT_DECLSPEC",
/* 409 */ "MSEXT_CDECL",
/* 410 */ "MSEXT_FASTCALL",
/* 411 */ "MSEXT_STDCALL",
/* 412 */ "MSEXT_TRY",
/* 413 */ "MSEXT_EXCEPT",
/* 414 */ "MSEXT_FINALLY",
/* 415 */ "MSEXT_LEAVE",
/* 416 */ "MSEXT_INLINE",
/* 417 */ "MSEXT_ASM",
};
unsigned int id = BASEID_FROM_TOKEN(tokid)-T_FIRST_TOKEN;
BOOST_ASSERT(id < T_LAST_TOKEN-T_FIRST_TOKEN);
return tok_names[id];
}
///////////////////////////////////////////////////////////////////////////////
// return a token name
inline char const *
get_token_value(token_id tokid)
{
// Table of token values
//
// Please note that the sequence of token names must match the sequence of
// token id's defined in then enum token_id above.
static char const *tok_names[] = {
/* 256 */ "&",
/* 257 */ "&&",
/* 258 */ "=",
/* 259 */ "&=",
/* 260 */ "|",
/* 261 */ "|=",
/* 262 */ "^",
/* 263 */ "^=",
/* 264 */ ",",
/* 265 */ ":",
/* 266 */ "/",
/* 267 */ "/=",
/* 268 */ ".",
/* 269 */ ".*",
/* 270 */ "...",
/* 271 */ "==",
/* 272 */ ">",
/* 273 */ ">=",
/* 274 */ "{",
/* 275 */ "<",
/* 276 */ "<=",
/* 277 */ "(",
/* 278 */ "[",
/* 279 */ "-",
/* 280 */ "-=",
/* 281 */ "--",
/* 282 */ "%",
/* 283 */ "%=",
/* 284 */ "!",
/* 285 */ "!=",
/* 286 */ "||",
/* 287 */ "+",
/* 288 */ "+=",
/* 289 */ "++",
/* 290 */ "->",
/* 291 */ "->*",
/* 292 */ "?",
/* 293 */ "}",
/* 294 */ ")",
/* 295 */ "]",
/* 296 */ "::",
/* 297 */ ";",
/* 298 */ "<<",
/* 299 */ "<<=",
/* 300 */ ">>",
/* 301 */ ">>=",
/* 302 */ "*",
/* 303 */ "~",
/* 304 */ "*=",
/* 305 */ "asm",
/* 306 */ "auto",
/* 307 */ "bool",
/* 308 */ "false",
/* 309 */ "true",
/* 310 */ "break",
/* 311 */ "case",
/* 312 */ "catch",
/* 313 */ "char",
/* 314 */ "class",
/* 315 */ "const",
/* 316 */ "const_cast",
/* 317 */ "continue",
/* 318 */ "default",
/* 319 */ "defined",
/* 320 */ "delete",
/* 321 */ "do",
/* 322 */ "double",
/* 323 */ "dynamic_cast",
/* 324 */ "else",
/* 325 */ "enum",
/* 326 */ "explicit",
/* 327 */ "export",
/* 328 */ "extern",
/* 329 */ "float",
/* 330 */ "for",
/* 331 */ "friend",
/* 332 */ "goto",
/* 333 */ "if",
/* 334 */ "inline",
/* 335 */ "int",
/* 336 */ "long",
/* 337 */ "mutable",
/* 338 */ "namespace",
/* 339 */ "new",
/* 340 */ "operator",
/* 341 */ "private",
/* 342 */ "protected",
/* 343 */ "public",
/* 344 */ "register",
/* 345 */ "reinterpret_cast",
/* 346 */ "return",
/* 347 */ "short",
/* 348 */ "signed",
/* 349 */ "sizeof",
/* 350 */ "static",
/* 351 */ "static_cast",
/* 352 */ "struct",
/* 353 */ "switch",
/* 354 */ "template",
/* 355 */ "this",
/* 356 */ "throw",
/* 357 */ "try",
/* 358 */ "typedef",
/* 359 */ "typeid",
/* 360 */ "typename",
/* 361 */ "union",
/* 362 */ "unsigned",
/* 363 */ "using",
/* 364 */ "virtual",
/* 365 */ "void",
/* 366 */ "volatile",
/* 367 */ "wchar_t",
/* 368 */ "while",
/* 369 */ "#define",
/* 370 */ "#if",
/* 371 */ "#ifdef",
/* 372 */ "#ifndef",
/* 373 */ "#else",
/* 374 */ "#elif",
/* 375 */ "#endif",
/* 376 */ "#error",
/* 377 */ "#line",
/* 378 */ "#pragma ",
/* 379 */ "#undef ",
/* 380 */ "#warning",
/* 381 */ "", // identifier
/* 382 */ "", // octalint
/* 383 */ "", // decimalint
/* 384 */ "", // hexlit
/* 385 */ "", // intlit
/* 386 */ "", // floatlit
/* 387 */ "", // ccomment
/* 388 */ "", // cppcomment
/* 389 */ "", // charlit
/* 390 */ "", // stringlit
/* 391 */ "", // contline
/* 392 */ "", // space
/* 393 */ "", // space2
/* 394 */ "\n",
/* 395 */ "##",
/* 396 */ "#",
/* 397 */ "", // any
/* 398 */ "#include",
/* 399 */ "#include",
/* 400 */ "#include",
/* 401 */ "", // eof
/* 402 */ "", // eoi
// MS extensions
/* 403 */ "__int8",
/* 404 */ "__int16",
/* 405 */ "__int32",
/* 406 */ "__int64",
/* 407 */ "__based",
/* 408 */ "__declspec",
/* 409 */ "__cdecl",
/* 410 */ "__fastcall",
/* 411 */ "__stdcall",
/* 412 */ "__try",
/* 413 */ "__except",
/* 414 */ "__finally",
/* 415 */ "__leave",
/* 416 */ "__inline",
/* 417 */ "__asm",
};
unsigned int id = BASEID_FROM_TOKEN(tokid)-T_FIRST_TOKEN;
BOOST_ASSERT(id < T_LAST_TOKEN-T_FIRST_TOKEN);
return tok_names[id];
}
///////////////////////////////////////////////////////////////////////////////
} // namespace wave
} // namespace boost
#endif // #if !defined(BOOST_WAVE_TOKEN_IDS_DEFINED)
#endif // !defined(TOKEN_IDS_HPP_414E9A58_F079_4789_8AFF_513815CE475B_INCLUDED)

View File

@@ -1,147 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_IFBLOCK_HPP_D4676B36_00C5_41F4_BC9F_9CBBAE3B8006_INCLUDED)
#define CPP_IFBLOCK_HPP_D4676B36_00C5_41F4_BC9F_9CBBAE3B8006_INCLUDED
#include <stack>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace util {
///////////////////////////////////////////////////////////////////////////////
// the class if_blocks handles recursive conditional compilation contexts
class if_block
{
public:
if_block() :
status(true), some_part_status(true),
enclosing_status(true), is_in_else(false)
{
}
if_block(bool status_, bool enclosing_status_) :
status(status_),
some_part_status(status_),
enclosing_status(enclosing_status_),
is_in_else(false)
{
}
void set_status(bool status_)
{
status = status_;
if (status_)
some_part_status = true;
}
bool get_status() const { return status; }
bool get_some_part_status() const { return some_part_status; }
bool get_enclosing_status() const { return enclosing_status; }
bool get_in_else() const { return is_in_else; }
void set_in_else() { is_in_else = true; }
private:
bool status; // Current block is true
bool some_part_status; // One of the preceeding or current #if/#elif was true
bool enclosing_status; // Enclosing #if block is true
bool is_in_else; // Inside the #else part
};
///////////////////////////////////////////////////////////////////////////////
// stack of conditional compilation contexts
class if_block_stack
: private std::stack<if_block>
{
public:
typedef std::stack<if_block>::size_type size_type;
void enter_if_block(bool new_status)
{
// If enclosing block is false, then this block is also false
bool enclosing_status = get_status();
this->push (value_type (new_status && enclosing_status, enclosing_status));
}
bool enter_elif_block(bool new_status)
{
if (!is_inside_ifpart())
return false; // #elif without matching #if
if (get_enclosing_status()) {
if (get_status()) {
// entered a (false) #elif block from a true block
this->top().set_status(false);
}
else if (new_status && !this->top().get_some_part_status()) {
// Entered true #elif block and no previous block was true
this->top().set_status(new_status);
}
}
return true;
}
bool enter_else_block()
{
if (!is_inside_ifpart())
return false; // #else without matching #if
if (get_enclosing_status()) {
if (!this->top().get_some_part_status()) {
// Entered (true) #else block and no previous block was true
this->top().set_status(true);
}
else if (get_status()) {
// Entered (false) #else block from true block
this->top().set_status(false);
}
// Set else flag
this->top().set_in_else();
}
return true;
}
bool exit_if_block()
{
if (0 == this->size())
return false; // #endif without matching #if
this->pop();
return true;
}
// return, wether the top (innermost) condition is true or false
bool get_status() const
{
return 0 == this->size() || this->top().get_status();
}
size_type get_if_block_depth() const { return this->size(); }
protected:
bool get_enclosing_status() const
{
return 0 == this->size() || this->top().get_enclosing_status();
}
bool is_inside_ifpart() const
{
return 0 != this->size() && !this->top().get_in_else();
}
bool is_inside_elsepart() const
{
return 0 != this->size() && this->top().get_in_else();
}
};
///////////////////////////////////////////////////////////////////////////////
} // namespace util
} // namespace wave
} // namespace boost
#endif // !defined(CPP_IFBLOCK_HPP_D4676B36_00C5_41F4_BC9F_9CBBAE3B8006_INCLUDED)

View File

@@ -1,218 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_INCLUDE_PATHES_HPP_AF620DA4_B3D2_4221_AD91_8A1ABFFB6944_INCLUDED)
#define CPP_INCLUDE_PATHES_HPP_AF620DA4_B3D2_4221_AD91_8A1ABFFB6944_INCLUDED
#include <string>
#include <list>
#include <set>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/wave/wave_config.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace util {
///////////////////////////////////////////////////////////////////////////////
//
// include_pathes - controlling the include path search order
//
// General notes:
//
// Any directories specified with the 'add_include_path()' function before
// the function 'set_sys_include_delimiter()' is called are searched only
// for the case of '#include "file"' directives, they are not searched for
// '#include <file>' directives. If additional directories are specified
// with the 'add_include_path()' function after a call to the function
// 'set_sys_include_delimiter()', these directories are searched for all
// '#include' directives.
//
// In addition, a call to the function 'set_sys_include_delimiter()'
// inhibits the use of the current directory as the first search directory
// for '#include "file"' directives. Therefore, the current directory is
// searched only if it is requested explicitly with a call to the function
// 'add_include_path(".")'.
//
// Calling both functions, the 'set_sys_include_delimiter()' and
// 'add_include_path(".")' allows you to control precisely which
// directories are searched before the current one and which are searched
// after.
//
///////////////////////////////////////////////////////////////////////////////
class include_pathes
{
typedef std::list<boost::filesystem::path> include_list_t;
typedef std::set<std::string> pragma_once_set_t;
public:
include_pathes()
: was_sys_include_path(false),
current_dir(boost::filesystem::initial_path())
{}
bool add_include_path(char const *path_, bool is_system = false)
{
return add_include_path(path_, (is_system || was_sys_include_path) ?
system_include_pathes : user_include_pathes);
}
void set_sys_include_delimiter() { was_sys_include_path = true; }
bool find_include_file (std::string &s, bool is_system,
char const *current_file) const;
void set_current_directory(char const *path_);
void init_initial_path() { boost::filesystem::initial_path(); }
protected:
bool find_include_file (std::string &s, include_list_t const &pathes,
char const *) const;
bool add_include_path(char const *path_, include_list_t &pathes_);
private:
include_list_t user_include_pathes;
include_list_t system_include_pathes;
bool was_sys_include_path; // saw a set_sys_include_delimiter()
boost::filesystem::path current_dir;
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
public:
bool has_pragma_once(std::string const &filename)
{
return pragma_once_files.find(filename) != pragma_once_files.end();
}
bool add_pragma_once_header(std::string const &filename)
{
return pragma_once_files.insert(filename).second;
}
private:
pragma_once_set_t pragma_once_files;
#endif
};
///////////////////////////////////////////////////////////////////////////////
// Add an include path to one of the search lists (user include path or system
// include path).
inline
bool include_pathes::add_include_path (
char const *path_, include_list_t &pathes_)
{
namespace fs = boost::filesystem;
if (path_) {
fs::path newpath = fs::complete(fs::path(path_, fs::native), current_dir);
if (!fs::exists(newpath) || !fs::is_directory(newpath)) {
// the given path does not form a name of a valid file system directory
// item
return false;
}
pathes_.push_back (newpath);
return true;
}
return false;
}
///////////////////////////////////////////////////////////////////////////////
// Find an include file by traversing the list of include directories
inline
bool include_pathes::find_include_file (std::string &s,
include_list_t const &pathes, char const *current_file) const
{
namespace fs = boost::filesystem;
typedef include_list_t::const_iterator const_include_list_iter_t;
const_include_list_iter_t include_pathes_end = pathes.end();
for (const_include_list_iter_t it = pathes.begin();
it != include_pathes_end; ++it)
{
fs::path currpath (*it);
currpath /= s; // append filename
if (fs::exists(currpath) &&
( 0 == current_file ||
strcmp(currpath.native_file_string().c_str(), current_file)
)
)
{
// found the required file
s = currpath.string();
return true;
}
}
return false;
}
///////////////////////////////////////////////////////////////////////////////
// Find an include file by searching the user and system includes in the
// correct sequence (as it was configured by the user of the driver program)
inline bool
include_pathes::find_include_file (std::string &s, bool is_system,
char const *current_file) const
{
namespace fs = boost::filesystem;
// if not system include (<...>), then search current directory first
if (!is_system) {
if (!was_sys_include_path) { // set_sys_include_delimiter() not called
// first look in the current directory
fs::path currpath = current_dir;
currpath /= s;
if (fs::exists(currpath) &&
( 0 == current_file ||
strcmp(currpath.native_file_string().c_str(), current_file)
)
)
{
s = currpath.string(); // found in local directory
return true;
}
// iterate all user include file directories to find the file
return find_include_file(s, user_include_pathes, current_file);
}
// iterate all user include file directories to find the file
if (find_include_file(s, user_include_pathes, current_file))
return true;
// if nothing found, fall through
// ...
}
// iterate all system include file directories to find the file
return find_include_file (s, system_include_pathes, current_file);
}
///////////////////////////////////////////////////////////////////////////////
// Set current directory from a given file name
inline
void include_pathes::set_current_directory(char const *path_)
{
namespace fs = boost::filesystem;
fs::path filename = fs::complete(fs::path(path_, fs::native), current_dir);
if (fs::exists(filename) && fs::is_directory(filename))
current_dir = filename;
else
current_dir = filename.branch_path();
}
///////////////////////////////////////////////////////////////////////////////
} // namespace util
} // namespace wave
} // namespace boost
#endif // !defined(CPP_INCLUDE_PATHES_HPP_AF620DA4_B3D2_4221_AD91_8A1ABFFB6944_INCLUDED)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,249 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Definition of the predefined macros
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_MACROMAP_PREDEF_HPP_HK041119)
#define CPP_MACROMAP_PREDEF_HPP_HK041119
#include <boost/assert.hpp>
#include <boost/wave/wave_config.hpp>
#include <boost/wave/token_ids.hpp>
///////////////////////////////////////////////////////////////////////////////
//
// This file contains the definition of several token sequence analyse
// and transformation utility functions needed during macro handling.
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace util {
namespace predefined_macros {
// list of static predefined macros
struct static_macros {
char const *name;
boost::wave::token_id token_id;
char const *value;
};
// C++ mode
inline static_macros const &
static_data_cpp(std::size_t i)
{
static static_macros data[] = {
{ "__STDC__", T_INTLIT, "1" },
{ "__cplusplus", T_INTLIT, "199711L" },
{ 0, T_EOF, 0 }
};
BOOST_ASSERT(i < sizeof(data)/sizeof(data[0]));
return data[i];
}
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
// C99 mode
inline static_macros const &
static_data_c99(std::size_t i)
{
static static_macros data[] = {
{ "__STDC__", T_INTLIT, "1" },
{ "__STDC_VERSION__", T_INTLIT, "199901L" },
{ "__STDC_HOSTED__", T_INTLIT, "0" },
{ "__WAVE_HAS_VARIADICS__", T_INTLIT, "1" },
{ 0, T_EOF, 0 }
};
BOOST_ASSERT(i < sizeof(data)/sizeof(data[0]));
return data[i];
}
#endif
// list of dynamic predefined macros
typedef char const * (* get_dynamic_value)(bool);
// __DATE__
inline
char const *get_date(bool reset)
{
static std::string datestr;
static const char *const monthnames[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
if (reset) {
datestr.erase();
}
else {
// for some systems sprintf, time_t etc. is in namespace std
using namespace std;
time_t tt = time(0);
struct tm *tb = 0;
if (tt != (time_t)-1) {
char buffer[sizeof("\"Oct 11 1347\"")+1];
tb = localtime (&tt);
sprintf (buffer, "\"%s %2d %4d\"",
monthnames[tb->tm_mon], tb->tm_mday, tb->tm_year + 1900);
datestr = buffer;
}
else {
datestr = "\"??? ?? ????\"";
}
}
return datestr.c_str();
}
// __TIME__
inline
char const *get_time(bool reset)
{
static std::string timestr;
if (reset) {
timestr.erase();
}
else {
// for some systems sprintf, time_t etc. is in namespace std
using namespace std;
time_t tt = time(0);
struct tm *tb = 0;
if (tt != (time_t)-1) {
char buffer[sizeof("\"12:34:56\"")+1];
tb = localtime (&tt);
sprintf (buffer, "\"%02d:%02d:%02d\"", tb->tm_hour,
tb->tm_min, tb->tm_sec);
timestr = buffer;
}
else {
timestr = "\"??:??:??\"";
}
}
return timestr.c_str();
}
// __SPIRIT_PP__/__WAVE__
inline
char const *get_version(bool /*reset*/)
{
static std::string versionstr;
char buffer[sizeof("0x0000")+1];
using namespace std; // for some systems sprintf is in namespace std
sprintf(buffer, "0x%02d%1d%1d", BOOST_WAVE_VERSION_MAJOR,
BOOST_WAVE_VERSION_MINOR, BOOST_WAVE_VERSION_SUBMINOR);
versionstr = buffer;
return versionstr.c_str();
}
// __SPIRIT_PP_VERSION__/__WAVE_VERSION__
boost::wave::util::time_conversion_helper const
compilation_time(__DATE__ " " __TIME__);
inline
char const *get_fullversion(bool /*reset*/)
{
static std::string versionstr;
char buffer[sizeof("0x00000000")+1];
// for some systems sprintf, time_t etc. is in namespace std
using namespace std;
// calculate the number of days since Dec 13 2001
// (the day the Wave project was started)
tm first_day;
using namespace std; // for some systems memset is in namespace std
memset (&first_day, 0, sizeof(tm));
first_day.tm_mon = 11; // Dec
first_day.tm_mday = 13; // 13
first_day.tm_year = 101; // 2001
long seconds = long(difftime(compilation_time.get_time(),
mktime(&first_day)));
sprintf(buffer, "0x%02d%1d%1d%04ld", BOOST_WAVE_VERSION_MAJOR,
BOOST_WAVE_VERSION_MINOR, BOOST_WAVE_VERSION_SUBMINOR,
seconds/(3600*24));
versionstr = buffer;
return versionstr.c_str();
}
// __SPIRIT_PP_VERSION_STR__/__WAVE_VERSION_STR__
inline
char const *get_versionstr(bool /*reset*/)
{
static std::string versionstr;
char buffer[sizeof("\"00.00.00.0000\"")+1];
// for some systems sprintf, time_t etc. is in namespace std
using namespace std;
// calculate the number of days since Dec 13 2001
// (the day the Wave project was started)
tm first_day;
using namespace std; // for some systems memset is in namespace std
memset (&first_day, 0, sizeof(tm));
first_day.tm_mon = 11; // Dec
first_day.tm_mday = 13; // 13
first_day.tm_year = 101; // 2001
long seconds = long(difftime(compilation_time.get_time(),
mktime(&first_day)));
sprintf(buffer, "\"%d.%d.%d.%ld\"", BOOST_WAVE_VERSION_MAJOR,
BOOST_WAVE_VERSION_MINOR, BOOST_WAVE_VERSION_SUBMINOR,
seconds/(3600*24));
versionstr = buffer;
return versionstr.c_str();
}
struct dynamic_macros {
char const *name;
boost::wave::token_id token_id;
get_dynamic_value generator;
};
inline dynamic_macros const &
dynamic_data(std::size_t i)
{
static dynamic_macros data[] = {
{ "__DATE__", T_STRINGLIT, get_date },
{ "__TIME__", T_STRINGLIT, get_time },
{ "__SPIRIT_PP__", T_INTLIT, get_version },
{ "__SPIRIT_PP_VERSION__", T_INTLIT, get_fullversion },
{ "__SPIRIT_PP_VERSION_STR__", T_STRINGLIT, get_versionstr },
{ "__WAVE__", T_INTLIT, get_version },
{ "__WAVE_VERSION__", T_INTLIT, get_fullversion },
{ "__WAVE_VERSION_STR__", T_STRINGLIT, get_versionstr },
{ 0, T_EOF, 0 }
};
BOOST_ASSERT(i < sizeof(data)/sizeof(data[0]));
return data[i];
}
} // namespace predefined_macros
///////////////////////////////////////////////////////////////////////////////
} // namespace util
} // namespace wave
} // namespace boost
#endif // !defined(CPP_MACROMAP_PREDEF_HPP_HK041119)

View File

@@ -1,497 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Token sequence analysis and transformation helper functions
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(CPP_MACROMAP_UTIL_HPP_HK041119)
#define CPP_MACROMAP_UTIL_HPP_HK041119
#include <boost/assert.hpp>
#include <boost/wave/wave_config.hpp>
#include <boost/wave/token_ids.hpp>
///////////////////////////////////////////////////////////////////////////////
//
// This file contains the definition of several token sequence analyse
// and transformation utility functions needed during macro handling.
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace util {
///////////////////////////////////////////////////////////////////////////////
namespace on_exit {
///////////////////////////////////////////////////////////////////////////
//
// On destruction pop the first element of the list given as the argument
//
///////////////////////////////////////////////////////////////////////////
template <typename ContainerT>
class pop_front {
public:
pop_front(ContainerT &list_) : list(list_) {}
~pop_front() { list.pop_front(); }
private:
ContainerT &list;
};
///////////////////////////////////////////////////////////////////////////
//
// Append a given list to the list given as argument
// On destruction pop the first element of the list given as argument
//
///////////////////////////////////////////////////////////////////////////
template <typename ContainerT>
class splice_pop_front {
public:
splice_pop_front(ContainerT &list_, ContainerT &queue)
: list(list_)
{
list.splice(list.end(), queue);
}
~splice_pop_front() { list.pop_front(); }
private:
ContainerT &list;
};
///////////////////////////////////////////////////////////////////////////
//
// On destruction reset a referenced value to its initial state
//
///////////////////////////////////////////////////////////////////////////
template <typename TypeT>
class reset {
public:
reset(TypeT &target_value_, TypeT new_value)
: target_value(target_value_), old_value(target_value_)
{
target_value_ = new_value;
}
~reset() { target_value = old_value; }
private:
TypeT &target_value;
TypeT old_value;
};
///////////////////////////////////////////////////////////////////////////
//
// On destruction assign the given iterator back
//
///////////////////////////////////////////////////////////////////////////
template <typename IteratorT, typename UnputIteratorT>
class assign {
public:
assign(IteratorT &it_, UnputIteratorT const &uit_)
: it(it_), uit(uit_) {}
~assign() { it = uit.base(); }
private:
IteratorT &it;
UnputIteratorT const &uit;
};
template <typename IteratorT>
class assign<IteratorT, IteratorT> {
public:
assign(IteratorT &it_, IteratorT const &uit_)
: it(it_), uit(uit_) {}
~assign() { it = uit; }
private:
IteratorT &it;
IteratorT const &uit;
};
///////////////////////////////////////////////////////////////////////////////
} // namespace on_exit
///////////////////////////////////////////////////////////////////////////////
namespace impl {
///////////////////////////////////////////////////////////////////////////////
//
// Test, whether a given identifier resolves to a predefined name
//
///////////////////////////////////////////////////////////////////////////////
template <typename StringT>
inline bool
is_special_macroname (StringT const &name)
{
if (name.size() < 7)
return false;
if ("defined" == name)
return true;
if ('_' == name[0] && '_' == name[1]) {
StringT str = name.substr(2);
if (str == "cplusplus" || str == "STDC__" ||
str == "TIME__" || str == "DATE__" ||
str == "LINE__" || str == "FILE__" ||
str == "INCLUDE_LEVEL__")
{
return true;
}
}
return false;
}
///////////////////////////////////////////////////////////////////////////////
//
// Test, whether two tokens are to be considered equal (different sequences
// of whitespace are considered to be equal)
//
///////////////////////////////////////////////////////////////////////////////
template <typename TokenT>
inline bool
token_equals(TokenT const &left, TokenT const &right)
{
using namespace boost::wave;
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
if (T_PARAMETERBASE == token_id(left) ||
T_EXTPARAMETERBASE == token_id(left))
#else
if (T_PARAMETERBASE == token_id(left))
#endif
{
// if the existing token is of type T_PARAMETERBASE, then the right token
// must be of type T_IDENTIFIER or a keyword
return (T_IDENTIFIER == token_id(right) ||
IS_CATEGORY(right, KeywordTokenType)) &&
left.get_value() == right.get_value();
}
// if the left token has whitespace, the value is irrelevant
return token_id(left) == token_id(right) && (
IS_CATEGORY(left, WhiteSpaceTokenType) ||
left.get_value() == right.get_value()
);
}
///////////////////////////////////////////////////////////////////////////////
//
// Tests, whether two macro definitions are equal
//
///////////////////////////////////////////////////////////////////////////////
template <typename ContainerT>
inline bool
definition_equals(ContainerT const &definition,
ContainerT const &new_definition)
{
typedef typename ContainerT::const_iterator const_iterator_type;
const_iterator_type first1 = definition.begin();
const_iterator_type last1 = definition.end();
const_iterator_type first2 = new_definition.begin();
const_iterator_type last2 = new_definition.end();
while (first1 != last1 && token_equals(*first1, *first2)) {
// skip whitespace, if both sequences have a whitespace next
token_id id1 = next_token<const_iterator_type>::peek(first1, last1, false);
token_id id2 = next_token<const_iterator_type>::peek(first2, last2, false);
if (IS_CATEGORY(id1, WhiteSpaceTokenType) &&
IS_CATEGORY(id2, WhiteSpaceTokenType))
{
// all consecutive whitespace tokens count as one whitespace
// adjust first1 and first2 accordingly
skip_whitespace(first1, last1);
skip_whitespace(first2, last2);
}
else if (!IS_CATEGORY(id1, WhiteSpaceTokenType) &&
!IS_CATEGORY(id2, WhiteSpaceTokenType))
{
++first1;
++first2;
}
else {
// the sequences differ
break;
}
}
return (first1 == last1 && first2 == last2) ? true : false;
}
///////////////////////////////////////////////////////////////////////////////
//
// Tests, whether two given sets of macro parameters are equal
//
///////////////////////////////////////////////////////////////////////////////
template <typename ContainerT>
inline bool
parameters_equal(ContainerT const &parameters, ContainerT const &new_parameters)
{
if (parameters.size() != new_parameters.size())
return false; // different parameter count
typedef typename ContainerT::const_iterator const_iterator_type;
const_iterator_type first1 = parameters.begin();
const_iterator_type last1 = parameters.end();
const_iterator_type first2 = new_parameters.begin();
while (first1 != last1) {
// parameters are different, if the corresponding tokens are different
using namespace boost::wave;
if (token_id(*first1) != token_id(*first2) ||
(*first1).get_value() != (*first2).get_value())
{
break;
}
++first1;
++first2;
}
return (first1 == last1) ? true : false;
}
///////////////////////////////////////////////////////////////////////////////
//
// Strip leading and trailing whitespace from the given token sequence
//
///////////////////////////////////////////////////////////////////////////////
template <typename ContainerT>
inline void
trim_replacement_list (ContainerT &replacement_list)
{
using namespace boost::wave;
// strip leading whitespace
if (replacement_list.size() > 0) {
typename ContainerT::iterator end = replacement_list.end();
typename ContainerT::iterator it = replacement_list.begin();
while (it != end && IS_CATEGORY(*it, WhiteSpaceTokenType)) {
if (T_PLACEHOLDER != token_id(*it)) {
typename ContainerT::iterator next = it;
++next;
replacement_list.erase(it);
it = next;
}
else {
++it;
}
}
}
// strip trailing whitespace
if (replacement_list.size() > 0) {
typename ContainerT::reverse_iterator rend = replacement_list.rend();
typename ContainerT::reverse_iterator rit = replacement_list.rbegin();
while (rit != rend && IS_CATEGORY(*rit, WhiteSpaceTokenType))
++rit;
typename ContainerT::iterator end = replacement_list.end();
typename ContainerT::iterator it = rit.base();
while (it != end && IS_CATEGORY(*it, WhiteSpaceTokenType)) {
if (T_PLACEHOLDER != token_id(*it)) {
typename ContainerT::iterator next = it;
++next;
replacement_list.erase(it);
it = next;
}
else {
++it;
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
//
// Remove all placeholder tokens from the given token sequence
//
///////////////////////////////////////////////////////////////////////////////
template <typename ContainerT>
inline void
remove_placeholders (ContainerT &replacement_list)
{
using namespace boost::wave;
// strip leading whitespace
if (replacement_list.size() > 0) {
typename ContainerT::iterator end = replacement_list.end();
typename ContainerT::iterator it = replacement_list.begin();
while (it != end) {
if (T_PLACEHOLDER == token_id(*it)) {
typename ContainerT::iterator next = it;
++next;
replacement_list.erase(it);
it = next;
}
else {
++it;
}
}
// remove all 'new' leading and trailing whitespace
trim_replacement_list(replacement_list);
}
}
///////////////////////////////////////////////////////////////////////////////
//
// Remove all whitespace tokens on the left side of the given token sequence
//
///////////////////////////////////////////////////////////////////////////////
template <typename ContainerT>
inline void
trim_argument_left (ContainerT &argument)
{
using namespace boost::wave;
// strip leading whitespace (should be only one token)
if (argument.size() > 0 &&
IS_CATEGORY(argument.front(), WhiteSpaceTokenType))
{
argument.pop_front();
}
}
///////////////////////////////////////////////////////////////////////////////
//
// Remove all whitespace tokens on the right side of the given token sequence
//
///////////////////////////////////////////////////////////////////////////////
template <typename ContainerT>
inline void
trim_argument_right (ContainerT &argument)
{
using namespace boost::wave;
// strip trailing whitespace (should be only one token)
if (argument.size() > 0 &&
IS_CATEGORY(argument.back(), WhiteSpaceTokenType))
{
argument.pop_back();
}
}
///////////////////////////////////////////////////////////////////////////////
//
// Remove all whitespace tokens on the keft and right sides of the given token
// sequence
//
///////////////////////////////////////////////////////////////////////////////
template <typename ContainerT>
inline void
trim_argument (ContainerT &argument)
{
trim_argument_left(argument);
trim_argument_right(argument);
}
///////////////////////////////////////////////////////////////////////////////
//
// Tests, whether the given token sequence consists out of whitespace only
//
///////////////////////////////////////////////////////////////////////////////
template <typename ContainerT>
inline bool
is_whitespace_only (ContainerT const &argument)
{
using namespace cpplexer;
typename ContainerT::const_iterator end = argument.end();
for (typename ContainerT::const_iterator it = argument.begin();
it != end; ++it)
{
if (!IS_CATEGORY(*it, WhiteSpaceTokenType))
return false;
}
return true;
}
///////////////////////////////////////////////////////////////////////////////
//
// Skip forward to a given token
//
///////////////////////////////////////////////////////////////////////////////
template <typename IteratorT>
inline bool
skip_to_token(IteratorT &it, IteratorT const &end, token_id id)
{
using namespace boost::wave;
if (token_id(*it) == id)
return true;
if (++it == end)
return false;
while (IS_CATEGORY(*it, WhiteSpaceTokenType) ||
T_NEWLINE == token_id(*it))
{
if (++it == end)
return false;
}
return token_id(*it) == id;
}
///////////////////////////////////////////////////////////////////////////////
//
// Get the full name of a given macro name (concatenate the string
// representations of the single tokens).
//
///////////////////////////////////////////////////////////////////////////////
template <typename IteratorT>
inline std::string
get_full_name(IteratorT const &begin, IteratorT const &end)
{
std::string full_name;
for (IteratorT err_it = begin; err_it != end; ++err_it)
full_name += (*err_it).get_value().c_str();
return full_name;
}
///////////////////////////////////////////////////////////////////////////////
//
// The following predicate is used in conjunction with the remove_copy_if
// algorithm to allow the detection of an eventually copied operator ##.
// No removal is performed in any case.
//
///////////////////////////////////////////////////////////////////////////////
class find_concat_operator {
public:
find_concat_operator(bool &found_) : found_concat(found_) {}
template <typename TokenT>
bool operator()(TokenT const &tok)
{
using namespace boost::wave;
if (T_POUND_POUND == BASE_TOKEN(token_id(tok)))
found_concat = true;
return false;
}
private:
bool &found_concat;
};
///////////////////////////////////////////////////////////////////////////////
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
} // namespace util
} // namespace wave
} // namespace boost
#endif // !defined(CPP_MACROMAP_UTIL_HPP_HK041119)

View File

@@ -1,158 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Whitespace eater
http://spirit.sourceforge.net/
Copyright (c) 2003 Paul Mensonides
Copyright (c) 2001-2005 Hartmut Kaiser.
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(EAT_WHITESPACE_HPP_4CE9AD17_F82D_4AB2_A117_555DF0DCC801_INCLUDED)
#define EAT_WHITESPACE_HPP_4CE9AD17_F82D_4AB2_A117_555DF0DCC801_INCLUDED
#include <boost/wave/wave_config.hpp>
#include <boost/wave/token_ids.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace util {
template <typename TokenT>
class eat_whitespace {
public:
eat_whitespace();
bool may_skip (TokenT &token, bool &skipped_newline);
private:
typedef bool state_t(TokenT &token, bool &skipped_newline);
state_t eat_whitespace::* state;
state_t general, newline, newline_2nd, whitespace;
};
template <typename TokenT>
inline
eat_whitespace<TokenT>::eat_whitespace()
: state(&eat_whitespace::newline)
{
}
template <typename TokenT>
inline bool
eat_whitespace<TokenT>::may_skip(TokenT &token, bool &skipped_newline)
{
return (this->*state)(token, skipped_newline);
}
template <typename TokenT>
inline bool
eat_whitespace<TokenT>::general(TokenT &token, bool &skipped_newline)
{
using boost::wave::token_id;
token_id id = token_id(token);
if (T_NEWLINE == id || T_CPPCOMMENT == id) {
state = &eat_whitespace::newline;
}
else if (T_SPACE == id || T_SPACE2 == id || T_CCOMMENT == id) {
state = &eat_whitespace::whitespace;
if (T_CCOMMENT == id) {
if (TokenT::string_type::npos !=
token.get_value().find_first_of("\n"))
{
skipped_newline = true;
}
}
if (token.get_value().size() > 1)
token.set_value(" "); // replace with a single space
}
else {
state = &eat_whitespace::general;
}
return false;
}
template <typename TokenT>
inline bool
eat_whitespace<TokenT>::newline(TokenT &token, bool &skipped_newline)
{
using namespace boost::wave;
token_id id = token_id(token);
if (T_NEWLINE == id || T_CPPCOMMENT == id) {
skipped_newline = true;
state = &eat_whitespace::newline_2nd;
return true;
}
else if (T_SPACE != id && T_SPACE2 != id && T_CCOMMENT != id) {
return general(token, skipped_newline);
}
if (T_CCOMMENT == id) {
if (TokenT::string_type::npos !=
token.get_value().find_first_of("\n"))
{
skipped_newline = true;
}
}
return true;
}
template <typename TokenT>
inline bool
eat_whitespace<TokenT>::newline_2nd(TokenT &token, bool &skipped_newline)
{
using namespace boost::wave;
token_id id = token_id(token);
if (T_SPACE == id || T_SPACE2 == id)
return true;
if (T_CCOMMENT == id) {
if (TokenT::string_type::npos !=
token.get_value().find_first_of("\n"))
{
skipped_newline = true;
}
return true;
}
if (T_NEWLINE != id && T_CPPCOMMENT != id)
return general(token, skipped_newline);
skipped_newline = true;
return true;
}
template <typename TokenT>
inline bool
eat_whitespace<TokenT>::whitespace(TokenT &token, bool &skipped_newline)
{
using namespace boost::wave;
token_id id = token_id(token);
if (T_SPACE != id && T_SPACE2 != id && T_CCOMMENT != id)
return general(token, skipped_newline);
if (T_CCOMMENT == id) {
if (TokenT::string_type::npos !=
token.get_value().find_first_of("\n"))
{
skipped_newline = true;
}
}
return true;
}
///////////////////////////////////////////////////////////////////////////////
} // namespace util
} // namespace wave
} // namespace boost
#endif // !defined(EAT_WHITESPACE_HPP_4CE9AD17_F82D_4AB2_A117_555DF0DCC801_INCLUDED)

View File

@@ -1,170 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Definition of the position_iterator and file_position templates
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(FILE_POSITION_H_52BDEDF7_DAD3_4F24_802F_E66BB8098F68_INCLUDED)
#define FILE_POSITION_H_52BDEDF7_DAD3_4F24_802F_E66BB8098F68_INCLUDED
#include <string>
#include <ostream>
#include <boost/spirit/version.hpp>
#include <boost/spirit/iterator/position_iterator.hpp>
#include <boost/wave/wave_config.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace util {
///////////////////////////////////////////////////////////////////////////////
//
// file_position
//
// A structure to hold positional information. This includes the filename,
// line number and column number of a current token position.
//
///////////////////////////////////////////////////////////////////////////////
template <typename StringT>
struct file_position {
public:
typedef StringT string_type;
file_position()
: file(), line(1), column(1)
{}
explicit file_position(string_type const& file_, int line_ = 1,
int column_ = 1)
: file(file_), line(line_), column(column_)
{}
// accessors
string_type const &get_file() const { return file; }
int get_line() const { return line; }
int get_column() const { return column; }
void set_file(string_type const &file_) { file = file_; }
void set_line(int line_) { line = line_; }
void set_column(int column_) { column = column_; }
private:
string_type file;
int line;
int column;
};
template <typename StringT>
bool operator== (file_position<StringT> const &lhs,
file_position<StringT> const &rhs)
{
return lhs.get_column() == rhs.get_column() &&
lhs.get_line() == rhs.get_line() && lhs.get_file() == rhs.get_file();
}
template <typename StringT>
inline std::ostream &
operator<< (std::ostream &o, file_position<StringT> const &pos)
{
o << pos.get_file() << "(" << pos.get_line() << ")";
return o;
}
typedef file_position<BOOST_WAVE_STRINGTYPE> file_position_type;
///////////////////////////////////////////////////////////////////////////////
//
// position_iterator
//
// The position_iterator used by Wave is now based on the corresponding Spirit
// type. This type is used with our own file_position though. The needed
// specialization of the boost::spirit::position_policy class is provided
// below.
//
///////////////////////////////////////////////////////////////////////////////
template <typename IteratorT, typename PositionT>
struct position_iterator
: boost::spirit::position_iterator<IteratorT, PositionT>
{
typedef boost::spirit::position_iterator<IteratorT, PositionT> base_t;
position_iterator()
{
}
position_iterator(IteratorT const &begin, IteratorT const &end,
PositionT const &pos)
: base_t(begin, end, pos)
{
}
};
///////////////////////////////////////////////////////////////////////////////
} // namespace util
} // namespace wave
///////////////////////////////////////////////////////////////////////////////
#if SPIRIT_VERSION >= 0x1700
namespace spirit {
///////////////////////////////////////////////////////////////////////////////
//
// The boost::spirit::position_policy has to be specialized for our
// file_position class
//
///////////////////////////////////////////////////////////////////////////////
template <>
class position_policy<boost::wave::util::file_position_type> {
public:
position_policy()
: m_CharsPerTab(4)
{}
void next_line(boost::wave::util::file_position_type &pos)
{
pos.set_line(pos.get_line() + 1);
pos.set_column(1);
}
void set_tab_chars(unsigned int chars)
{
m_CharsPerTab = chars;
}
void next_char(boost::wave::util::file_position_type &pos)
{
pos.set_column(pos.get_column() + 1);
}
void tabulation(boost::wave::util::file_position_type &pos)
{
pos.set_column(pos.get_column() + m_CharsPerTab -
(pos.get_column() - 1) % m_CharsPerTab);
}
private:
unsigned int m_CharsPerTab;
};
///////////////////////////////////////////////////////////////////////////////
} // namespace spirit
#endif // SPIRIT_VERSION >= 0x1700
} // namespace boost
#endif // !defined(FILE_POSITION_H_52BDEDF7_DAD3_4F24_802F_E66BB8098F68_INCLUDED)

File diff suppressed because it is too large Load Diff

View File

@@ -1,133 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED)
#define FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED
#include <boost/spirit/iterator/multi_pass.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace util {
///////////////////////////////////////////////////////////////////////////////
//
// class functor_input
//
// Implementation of the InputPolicy used by multi_pass
// functor_input gets tokens from a functor
// Note: the functor must have a typedef for result_type
// It also must have a static variable of type result_type defined
// to represent eof that is called eof.
//
// This functor input policy template is essentially the same as the
// predefined multi_pass functor_input policy. The difference is,
// that the first token is not read at initialization time, but only
// just before returning the first token.
//
///////////////////////////////////////////////////////////////////////////////
struct functor_input {
template <typename FunctorT>
class inner {
typedef typename FunctorT::result_type result_type;
struct Data {
Data(FunctorT const &ftor_)
: ftor(ftor_), was_initialized(false)
{}
FunctorT ftor;
result_type curtok;
bool was_initialized;
};
public:
typedef result_type value_type;
typedef std::ptrdiff_t difference_type;
typedef result_type *pointer;
typedef result_type &reference;
protected:
inner()
: data(0)
{}
inner(FunctorT const &x)
: data(new Data(x))
{}
inner(inner const &x)
: data(x.data)
{}
void destroy()
{
delete data;
data = 0;
}
bool same_input(inner const &x) const
{
return data == x.data;
}
void swap(inner &x)
{
boost::spirit::impl::mp_swap(data, x.data);
}
void ensure_initialized() const
{
if (data && !data->was_initialized) {
data->curtok = (data->ftor)(); // get the first token
data->was_initialized = true;
}
}
public:
reference get_input() const
{
ensure_initialized();
return data->curtok;
}
void advance_input()
{
BOOST_SPIRIT_ASSERT(0 != data);
data->curtok = (data->ftor)();
data->was_initialized = true;
}
bool input_at_eof() const
{
ensure_initialized();
return !data || data->curtok == data->ftor.eof;
}
FunctorT& get_functor() const
{
BOOST_SPIRIT_ASSERT(0 != data);
return data->ftor;
}
private:
mutable Data *data;
};
};
///////////////////////////////////////////////////////////////////////////////
} // namespace util
} // namespace wave
} // namespace boost
#endif // !defined(FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED)

View File

@@ -1,330 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Detect the need to insert a whitespace token into the output stream
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(INSERT_WHITESPACE_DETECTION_HPP_765EF77B_0513_4967_BDD6_6A38148C4C96_INCLUDED)
#define INSERT_WHITESPACE_DETECTION_HPP_765EF77B_0513_4967_BDD6_6A38148C4C96_INCLUDED
#include <boost/wave/wave_config.hpp>
#include <boost/wave/token_ids.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace util {
namespace impl {
// T_IDENTIFIER
template <typename StringT>
inline bool
would_form_universal_char (StringT const &value)
{
if ('u' != value[0] && 'U' != value[0])
return false;
if ('u' == value[0] && value.size() < 5)
return false;
if ('U' == value[0] && value.size() < 9)
return false;
typename StringT::size_type pos =
value.find_first_not_of("0123456789abcdefABCDEF", 1);
if (StringT::npos == pos ||
('u' == value[0] && pos > 5) ||
('U' == value[0] && pos > 9))
{
return true; // would form an universal char
}
return false;
}
template <typename StringT>
inline bool
handle_identifier(boost::wave::token_id prev,
boost::wave::token_id before, StringT const &value)
{
using namespace boost::wave;
switch (static_cast<unsigned int>(prev)) {
case T_IDENTIFIER:
case T_NONREPLACABLE_IDENTIFIER:
case T_INTLIT:
case T_FLOATLIT:
case T_COMPL_ALT:
case T_OR_ALT:
case T_AND_ALT:
case T_NOT_ALT:
case T_XOR_ALT:
case T_ANDASSIGN_ALT:
case T_ORASSIGN_ALT:
case T_XORASSIGN_ALT:
case T_NOTEQUAL_ALT:
case T_FIXEDPOINTLIT:
return true;
// avoid constructing universal characters (\u1234)
case TOKEN_FROM_ID('\\', UnknownTokenType):
return would_form_universal_char(value);
}
return false;
}
// T_INTLIT
inline bool
handle_intlit(boost::wave::token_id prev, boost::wave::token_id before)
{
using namespace boost::wave;
switch(prev) {
case T_IDENTIFIER:
case T_NONREPLACABLE_IDENTIFIER:
case T_INTLIT:
case T_FLOATLIT:
case T_FIXEDPOINTLIT:
return true;
}
return false;
}
// T_FLOATLIT
inline bool
handle_floatlit(boost::wave::token_id prev,
boost::wave::token_id before)
{
using namespace boost::wave;
switch(prev) {
case T_IDENTIFIER:
case T_NONREPLACABLE_IDENTIFIER:
case T_INTLIT:
case T_FLOATLIT:
case T_FIXEDPOINTLIT:
return true;
}
return false;
}
// <% T_LEFTBRACE
inline bool
handle_alt_leftbrace(boost::wave::token_id prev,
boost::wave::token_id before)
{
using namespace boost::wave;
switch(prev) {
case T_LESS: // <<%
case T_SHIFTLEFT: // <<<%
return true;
}
return false;
}
// <: T_LEFTBRACKET
inline bool
handle_alt_leftbracket(boost::wave::token_id prev,
boost::wave::token_id before)
{
using namespace boost::wave;
switch(prev) {
case T_LESS: // <<:
case T_SHIFTLEFT: // <<<:
return true;
}
return false;
}
// T_FIXEDPOINTLIT
inline bool
handle_fixedpointlit(boost::wave::token_id prev,
boost::wave::token_id before)
{
using namespace boost::wave;
switch(prev) {
case T_IDENTIFIER:
case T_NONREPLACABLE_IDENTIFIER:
case T_INTLIT:
case T_FLOATLIT:
case T_FIXEDPOINTLIT:
return true;
}
return false;
}
// T_DOT
inline bool
handle_dot(boost::wave::token_id prev, boost::wave::token_id before)
{
using namespace boost::wave;
switch(prev) {
case T_DOT:
if (T_DOT == before)
return true; // ...
break;
}
return false;
}
// T_QUESTION_MARK
inline bool
handle_questionmark(boost::wave::token_id prev,
boost::wave::token_id before)
{
using namespace boost::wave;
switch(static_cast<unsigned int>(prev)) {
case TOKEN_FROM_ID('\\', UnknownTokenType): // \?
case T_QUESTION_MARK: // ??
return true;
}
return false;
}
// T_NEWLINE
inline bool
handle_newline(boost::wave::token_id prev,
boost::wave::token_id before)
{
using namespace boost::wave;
switch(static_cast<unsigned int>(prev)) {
case TOKEN_FROM_ID('\\', UnknownTokenType): // \ \n
case T_DIVIDE:
if (T_QUESTION_MARK == before)
return true; // ?/\n // may be \\n
break;
}
return false;
}
} // namespace impl
class insert_whitespace_detection
{
public:
insert_whitespace_detection()
: prev(boost::wave::T_EOF), beforeprev(boost::wave::T_EOF)
{}
template <typename StringT>
bool must_insert(boost::wave::token_id current, StringT const &value)
{
using namespace boost::wave;
switch (current) {
case T_NONREPLACABLE_IDENTIFIER:
case T_IDENTIFIER:
return impl::handle_identifier(prev, beforeprev, value);
case T_INTLIT:
return impl::handle_intlit(prev, beforeprev);
case T_FLOATLIT:
return impl::handle_floatlit(prev, beforeprev);
case T_STRINGLIT:
if (TOKEN_FROM_ID('L', UnknownTokenType) == prev) // 'L'
return true;
break;
case T_LEFTBRACE_ALT:
return impl::handle_alt_leftbrace(prev, beforeprev);
case T_LEFTBRACKET_ALT:
return impl::handle_alt_leftbracket(prev, beforeprev);
case T_FIXEDPOINTLIT:
return impl::handle_fixedpointlit(prev, beforeprev);
case T_DOT:
return impl::handle_dot(prev, beforeprev);
case T_QUESTION_MARK:
return impl::handle_questionmark(prev, beforeprev);
case T_NEWLINE:
return impl::handle_newline(prev, beforeprev);
case T_LEFTPAREN:
case T_RIGHTPAREN:
case T_LEFTBRACKET:
case T_RIGHTBRACKET:
case T_SEMICOLON:
case T_COMMA:
case T_COLON:
switch (prev) {
case T_LEFTPAREN:
case T_RIGHTPAREN:
case T_LEFTBRACKET:
case T_RIGHTBRACKET:
case T_LEFTBRACE:
case T_RIGHTBRACE:
return false; // no insertion between parens/brackets/braces
default:
break;
}
break;
case T_LEFTBRACE:
case T_RIGHTBRACE:
switch (prev) {
case T_LEFTPAREN:
case T_RIGHTPAREN:
case T_LEFTBRACKET:
case T_RIGHTBRACKET:
case T_LEFTBRACE:
case T_RIGHTBRACE:
case T_SEMICOLON:
case T_COMMA:
case T_COLON:
return false; // no insertion between parens/brackets/braces
case T_QUESTION_MARK:
if (T_QUESTION_MARK == beforeprev)
return true;
break;
default:
break;
}
break;
case T_MINUS:
case T_MINUSMINUS:
case T_LESS:
case T_EQUAL:
case T_ASSIGN:
case T_GREATER:
case T_DIVIDE:
case T_CHARLIT:
case T_NOT:
case T_NOTEQUAL:
case T_DIVIDEASSIGN:
case T_MINUSASSIGN:
if (T_QUESTION_MARK == prev && T_QUESTION_MARK == beforeprev)
return true; // ??{op}
break;
case T_COMPL_ALT:
case T_OR_ALT:
case T_AND_ALT:
case T_NOT_ALT:
case T_XOR_ALT:
case T_ANDASSIGN_ALT:
case T_ORASSIGN_ALT:
case T_XORASSIGN_ALT:
case T_NOTEQUAL_ALT:
if (T_IDENTIFIER == prev || T_NONREPLACABLE_IDENTIFIER == prev ||
IS_CATEGORY(prev, KeywordTokenType))
return true;
break;
}
// else, handle operators separately
if (IS_CATEGORY(current, OperatorTokenType) &&
IS_CATEGORY(prev, OperatorTokenType))
{
return true; // operators must be delimited always
}
return false;
}
void shift_tokens (boost::wave::token_id next_id)
{
beforeprev = prev;
prev = next_id;
}
private:
boost::wave::token_id prev; // the previous analyzed token
boost::wave::token_id beforeprev; // the token before the previous
};
///////////////////////////////////////////////////////////////////////////////
} // namespace util
} // namespace wave
} // namespace boost
#endif // !defined(INSERT_WHITESPACE_DETECTION_HPP_765EF77B_0513_4967_BDD6_6A38148C4C96_INCLUDED)

View File

@@ -1,135 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(INTERPRET_PRAGMA_HPP_B1F2315E_C5CE_4ED1_A343_0EF548B7942A_INCLUDED)
#define INTERPRET_PRAGMA_HPP_B1F2315E_C5CE_4ED1_A343_0EF548B7942A_INCLUDED
#include <string>
#include <list>
#include <boost/spirit/core.hpp>
#if SPIRIT_VERSION >= 0x1700
#include <boost/spirit/actor/assign_actor.hpp>
#include <boost/spirit/actor/push_back_actor.hpp>
#endif // SPIRIT_VERSION >= 0x1700
#include <boost/wave/wave_config.hpp>
#include <boost/wave/util/pattern_parser.hpp>
#include <boost/wave/util/macro_helpers.hpp>
#include <boost/wave/token_ids.hpp>
#include <boost/wave/cpp_exceptions.hpp>
#include <boost/wave/cpp_iteration_context.hpp>
#include <boost/wave/language_support.hpp>
#if !defined(spirit_append_actor)
#if SPIRIT_VERSION >= 0x1700
#define spirit_append_actor(actor) boost::spirit::push_back_a(actor)
#define spirit_assign_actor(actor) boost::spirit::assign_a(actor)
#else
#define spirit_append_actor(actor) boost::spirit::append(actor)
#define spirit_assign_actor(actor) boost::spirit::assign(actor)
#endif // SPIRIT_VERSION >= 0x1700
#endif // !defined(spirit_append_actor)
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace util {
///////////////////////////////////////////////////////////////////////////////
//
// The function interpret_pragma interprets the given token sequence as the
// body of a #pragma directive (or parameter to the _Pragma operator) and
// executes the actions associated with recognized Wave specific options.
//
///////////////////////////////////////////////////////////////////////////////
template <typename ContextT, typename IteratorT, typename ContainerT>
inline bool
interpret_pragma(ContextT &ctx, typename ContextT::token_type const &act_token,
IteratorT it, IteratorT const &end, ContainerT &pending)
{
typedef typename ContextT::token_type token_type;
typedef typename token_type::string_type string_type;
using namespace cpplexer;
if (T_IDENTIFIER == token_id(*it) && "wave" == (*it).get_value()) {
// this is a wave specific option, it should have the form:
// #pragma wave option(value)
// where '(value)' is required only for some pragma directives
// all of the given #pragma operators are forwarded to the supplied
// context_policy
using namespace boost::spirit;
token_type option;
ContainerT values;
if (!parse (++it, end,
( ch_p(T_IDENTIFIER)
[spirit_assign_actor(option)]
| pattern_p(KeywordTokenType, TokenTypeMask)
[spirit_assign_actor(option)]
)
>> !( ch_p(T_LEFTPAREN)
>> lexeme_d[
*(anychar_p[spirit_append_actor(values)] - ch_p(T_RIGHTPAREN))
]
>> ch_p(T_RIGHTPAREN)
),
pattern_p(WhiteSpaceTokenType, TokenTypeMask)).hit)
{
return false;
}
// remove the falsely matched closing parenthesis
if (values.size() > 0) {
if (T_RIGHTPAREN == values.back()) {
typename ContainerT::reverse_iterator rit = values.rbegin();
values.erase((++rit).base());
}
else {
BOOST_WAVE_THROW(preprocess_exception, ill_formed_pragma_option,
"missing matching ')'", act_token.get_position());
}
}
// decode the option (call the context_policy hook)
if (!ctx.interpret_pragma(pending, option, values, act_token))
{
// unknown #pragma option
string_type option_str (option.get_value());
if (values.size() > 0) {
option_str += "(";
option_str += impl::as_string(values);
option_str += ")";
}
BOOST_WAVE_THROW(preprocess_exception, ill_formed_pragma_option,
option_str, act_token.get_position());
}
return true;
}
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
else if (T_IDENTIFIER == token_id(*it) && "once" == (*it).get_value()) {
// #pragma once
return ctx.add_pragma_once_header(ctx.get_current_filename());
}
#endif
return false;
}
///////////////////////////////////////////////////////////////////////////////
} // namespace util
} // namespace wave
} // namespace boost
#endif // !defined(INTERPRET_PRAGMA_HPP_B1F2315E_C5CE_4ED1_A343_0EF548B7942A_INCLUDED)

View File

@@ -1,71 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(ITERATION_CONTEXT_HPP_9556CD16_F11E_4ADC_AC8B_FB9A174BE664_INCLUDED)
#define ITERATION_CONTEXT_HPP_9556CD16_F11E_4ADC_AC8B_FB9A174BE664_INCLUDED
#include <cstdlib>
#include <stack>
#include <boost/wave/wave_config.hpp>
#include <boost/wave/cpp_exceptions.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace util {
///////////////////////////////////////////////////////////////////////////////
template <typename IterationContextT>
class iteration_context_stack
{
typedef std::stack<IterationContextT> base_t;
public:
typedef typename base_t::size_type size_type;
iteration_context_stack()
: max_include_nesting_depth(BOOST_WAVE_MAX_INCLUDE_LEVEL_DEPTH)
{}
void set_max_include_nesting_depth(size_type new_depth)
{ max_include_nesting_depth = new_depth; }
size_type get_max_include_nesting_depth() const
{ return max_include_nesting_depth; }
typename base_t::size_type size() const { return iter_ctx.size(); }
typename base_t::value_type &top() { return iter_ctx.top(); }
void pop() { iter_ctx.pop(); }
template <typename PositionT>
void push(PositionT const &pos, typename base_t::value_type const &val)
{
if (iter_ctx.size() == max_include_nesting_depth) {
char buffer[22]; // 21 bytes holds all NUL-terminated unsigned 64-bit numbers
using namespace std; // for some systems ltoa is in namespace std
sprintf(buffer, "%d", max_include_nesting_depth);
BOOST_WAVE_THROW(preprocess_exception, include_nesting_too_deep, buffer,
pos);
}
iter_ctx.push(val);
}
private:
size_type max_include_nesting_depth;
base_t iter_ctx;
};
///////////////////////////////////////////////////////////////////////////////
} // namespace util
} // namespace wave
} // namespace boost
#endif // !defined(ITERATION_CONTEXT_HPP_9556CD16_F11E_4ADC_AC8B_FB9A174BE664_INCLUDED)

View File

@@ -1,126 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(MACRO_DEFINITION_HPP_D68A639E_2DA5_4E9C_8ACD_CFE6B903831E_INCLUDED)
#define MACRO_DEFINITION_HPP_D68A639E_2DA5_4E9C_8ACD_CFE6B903831E_INCLUDED
#include <vector>
#include <list>
#include <boost/wave/wave_config.hpp>
#include <boost/wave/token_ids.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace util {
///////////////////////////////////////////////////////////////////////////////
//
// macro_definition
//
// This class containes all infos for a defined macro.
//
///////////////////////////////////////////////////////////////////////////////
template <typename TokenT, typename ContainerT>
struct macro_definition {
typedef std::vector<TokenT> parameter_container_t;
typedef ContainerT definition_container_t;
typedef typename parameter_container_t::const_iterator
const_parameter_iterator_t;
typedef typename definition_container_t::const_iterator
const_definition_iterator_t;
macro_definition(TokenT const &token_, bool has_parameters,
bool is_predefined_, long uid_)
: macroname(token_), uid(uid_), is_functionlike(has_parameters),
replaced_parameters(false), is_available_for_replacement(true),
is_predefined(is_predefined_)
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
, has_ellipsis(false)
#endif
{
}
// generated copy constructor
// generated destructor
// generated assignment operator
// Replace all occurrences of the parameters throughout the macrodefinition
// with special parameter tokens to simplify later macro replacement.
// Additionally mark all occurrences of the macro name itself throughout
// the macro definition
void replace_parameters()
{
using namespace boost::wave;
if (!replaced_parameters) {
typename definition_container_t::iterator end = macrodefinition.end();
typename definition_container_t::iterator it = macrodefinition.begin();
for (/**/; it != end; ++it) {
if (T_IDENTIFIER == token_id(*it) ||
IS_CATEGORY(token_id(*it), KeywordTokenType))
{
// may be a parameter to replace
const_parameter_iterator_t cend = macroparameters.end();
const_parameter_iterator_t cit = macroparameters.begin();
for (typename parameter_container_t::size_type i = 0;
cit != cend; ++cit, ++i)
{
if ((*it).get_value() == (*cit).get_value()) {
(*it).set_token_id(token_id(T_PARAMETERBASE+i));
break;
}
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
else if (T_ELLIPSIS == token_id(*cit) &&
"__VA_ARGS__" == (*it).get_value())
{
// __VA_ARGS__ requires special handling
(*it).set_token_id(token_id(T_EXTPARAMETERBASE+i));
break;
}
#endif
}
}
}
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
// we need to know, if the last of the formal arguments is an ellipsis
if (macroparameters.size() > 0 &&
T_ELLIPSIS == token_id(macroparameters.back()))
{
has_ellipsis = true;
}
#endif
replaced_parameters = true; // do it only once
}
}
TokenT macroname; // macro name
parameter_container_t macroparameters; // formal parameters
definition_container_t macrodefinition; // macro definition token sequence
long uid; // unique id of this macro
bool is_functionlike;
bool replaced_parameters;
bool is_available_for_replacement;
bool is_predefined;
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
bool has_ellipsis;
#endif
};
///////////////////////////////////////////////////////////////////////////////
} // namespace util
} // namespace wave
} // namespace boost
#endif // !defined(MACRO_DEFINITION_HPP_D68A639E_2DA5_4E9C_8ACD_CFE6B903831E_INCLUDED)

View File

@@ -1,241 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(MACRO_HELPERS_HPP_931BBC99_EBFA_4692_8FBE_B555998C2C39_INCLUDED)
#define MACRO_HELPERS_HPP_931BBC99_EBFA_4692_8FBE_B555998C2C39_INCLUDED
#include <boost/wave/wave_config.hpp>
#include <boost/wave/token_ids.hpp>
#include <boost/wave/cpplexer/validate_universal_char.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace util {
namespace impl {
// escape a string literal (insert '\\' before every '\"', '?' and '\\')
template <typename StringT>
inline StringT
escape_lit(StringT const &value)
{
StringT result;
typename StringT::size_type pos = 0;
typename StringT::size_type pos1 = value.find_first_of ("\"\\?", 0);
if (StringT::npos != pos1) {
do {
result += value.substr(pos, pos1-pos)
+ StringT("\\")
+ StringT(1, value[pos1]);
pos1 = value.find_first_of ("\"\\?", pos = pos1+1);
} while (StringT::npos != pos1);
result += value.substr(pos);
}
else {
result = value;
}
return result;
}
// un-escape a string literal (remove '\\' just before '\\', '\"' or '?')
template <typename StringT>
inline StringT
unescape_lit(StringT const &value)
{
StringT result;
typename StringT::size_type pos = 0;
typename StringT::size_type pos1 = value.find_first_of ("\\", 0);
if (StringT::npos != pos1) {
do {
if ('\\' == value[pos1+1] || '\"' == value[pos1+1] ||
'?' == value[pos1+1])
{
result += value.substr(pos, pos1-pos);
}
pos1 = value.find_first_of ("\\", pos = pos1+1);
} while (pos1 != StringT::npos);
result += value.substr(pos);
}
else {
// the string doesn't contain any escaped character sequences
result = value;
}
return result;
}
// return the string representation of a token sequence
template <typename ContainerT, typename PositionT>
inline typename ContainerT::value_type::string_type
as_stringlit (ContainerT const &token_sequence, PositionT const &pos)
{
using namespace boost::wave;
typedef typename ContainerT::value_type::string_type string_type;
string_type result("\"");
bool was_whitespace = false;
typename ContainerT::const_iterator end = token_sequence.end();
for (typename ContainerT::const_iterator it = token_sequence.begin();
it != end; ++it)
{
token_id id = token_id(*it);
if (IS_CATEGORY(*it, WhiteSpaceTokenType) || T_NEWLINE == id) {
if (!was_whitespace) {
// C++ standard 16.3.2.2 [cpp.stringize]
// Each occurrence of white space between the arguments
// preprocessing tokens becomes a single space character in the
// character string literal.
result += " ";
was_whitespace = true;
}
}
else if (T_STRINGLIT == id || T_CHARLIT == id) {
// string literals and character literals have to be escaped
result += impl::escape_lit((*it).get_value());
was_whitespace = false;
}
else
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
if (T_PLACEMARKER != id)
#endif
{
// now append this token to the string
result += (*it).get_value();
was_whitespace = false;
}
}
result += "\"";
// validate the resulting literal to contain no invalid universal character
// value (throws if invalid chars found)
boost::wave::cpplexer::impl::validate_literal(result, pos.get_line(),
pos.get_column(), pos.get_file());
return result;
}
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
// return the string representation of a token sequence
template <typename ContainerT, typename PositionT>
inline typename ContainerT::value_type::string_type
as_stringlit (std::vector<ContainerT> const &arguments,
typename std::vector<ContainerT>::size_type i, PositionT const &pos)
{
using namespace boost::wave;
typedef typename ContainerT::value_type::string_type string_type;
BOOST_SPIRIT_ASSERT(0 <= i && i < arguments.size());
string_type result("\"");
bool was_whitespace = false;
for (/**/; i < arguments.size(); ++i) {
// stringize all remaining arguments
typename ContainerT::const_iterator end = arguments[i].end();
for (typename ContainerT::const_iterator it = arguments[i].begin();
it != end; ++it)
{
token_id id = token_id(*it);
if (IS_CATEGORY(*it, WhiteSpaceTokenType) || T_NEWLINE == id) {
if (!was_whitespace) {
// C++ standard 16.3.2.2 [cpp.stringize]
// Each occurrence of white space between the arguments
// preprocessing tokens becomes a single space character in the
// character string literal.
result += " ";
was_whitespace = true;
}
}
else if (T_STRINGLIT == id || T_CHARLIT == id) {
// string literals and character literals have to be escaped
result += impl::escape_lit((*it).get_value());
was_whitespace = false;
}
else if (T_PLACEMARKER != id) {
// now append this token to the string
result += (*it).get_value();
was_whitespace = false;
}
}
// append comma, if not last argument
if (i < arguments.size()-1) {
result += ",";
was_whitespace = false;
}
}
result += "\"";
// validate the resulting literal to contain no invalid universal character
// value (throws if invalid chars found)
boost::wave::cpplexer::impl::validate_literal(result, pos.get_line(),
pos.get_column(), pos.get_file());
return result;
}
#endif // BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
// return the string representation of a token sequence
template <typename StringT, typename IteratorT>
inline StringT
as_string(IteratorT it, IteratorT end)
{
StringT result;
for (/**/; it != end; ++it)
{
result += (*it).get_value();
}
return result;
}
// return the string representation of a token sequence
template <typename ContainerT>
inline typename ContainerT::value_type::string_type
as_string (ContainerT const &token_sequence)
{
typedef typename ContainerT::value_type::string_type string_type;
return as_string<string_type>(token_sequence.begin(), token_sequence.end());
}
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
///////////////////////////////////////////////////////////////////////////
//
// Copies all arguments beginning with the given index to the output
// sequence. The arguments are separated by commas.
//
template <typename ContainerT, typename PositionT>
void replace_ellipsis (std::vector<ContainerT> const &arguments,
typename ContainerT::size_type index,
ContainerT &expanded, PositionT const &pos)
{
using namespace cpplexer;
typedef typename ContainerT::value_type token_type;
token_type comma(T_COMMA, ",", pos);
for (/**/; index < arguments.size(); ++index) {
ContainerT const &arg = arguments[index];
std::copy(arg.begin(), arg.end(),
std::inserter(expanded, expanded.end()));
if (index < arguments.size()-1)
expanded.push_back(comma);
}
}
#endif
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
} // namespace util
} // namespace wave
} // namespace boost
#endif // !defined(MACRO_HELPERS_HPP_931BBC99_EBFA_4692_8FBE_B555998C2C39_INCLUDED)

View File

@@ -1,55 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Global application configuration
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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_PATTERN_PARSER_HPP)
#define BOOST_SPIRIT_PATTERN_PARSER_HPP
#include <boost/spirit/core/primitives/primitives.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace util {
///////////////////////////////////////////////////////////////////////////
//
// pattern_and class
//
///////////////////////////////////////////////////////////////////////////
template <typename CharT = char>
struct pattern_and : public boost::spirit::char_parser<pattern_and<CharT> >
{
pattern_and(CharT pattern_, unsigned long pattern_mask_ = 0UL)
: pattern(pattern_),
pattern_mask((0UL != pattern_mask_) ? pattern_mask_ : pattern_)
{}
template <typename T>
bool test(T pattern_) const
{ return (pattern_ & pattern_mask) == pattern; }
CharT pattern;
unsigned long pattern_mask;
};
template <typename CharT>
inline pattern_and<CharT>
pattern_p(CharT pattern, unsigned long pattern_mask = 0UL)
{ return pattern_and<CharT>(pattern, pattern_mask); }
///////////////////////////////////////////////////////////////////////////////
} // namespace util
} // namespace wave
} // namespace boost
#endif // defined(BOOST_SPIRIT_PATTERN_PARSER_HPP)

View File

@@ -1,40 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(SYMBOL_TABLE_HPP_32B0F7C6_3DD6_4113_95A5_E16516C6F45A_INCLUDED)
#define SYMBOL_TABLE_HPP_32B0F7C6_3DD6_4113_95A5_E16516C6F45A_INCLUDED
#include <map>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace util {
///////////////////////////////////////////////////////////////////////////////
//
// The symbol_table class is used for the storage of defined macros.
//
///////////////////////////////////////////////////////////////////////////////
template <typename StringT, typename MacroDefT>
struct symbol_table
: public std::map<StringT, boost::shared_ptr<MacroDefT> >
{
symbol_table(long uid_)
{}
};
///////////////////////////////////////////////////////////////////////////////
} // namespace util
} // namespace wave
} // namespace boost
#endif // !defined(SYMBOL_TABLE_HPP_32B0F7C6_3DD6_4113_95A5_E16516C6F45A_INCLUDED)

View File

@@ -1,145 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(TIME_CONVERSION_HELPER_HPP_DA97E389_1797_43BA_82AE_B071064B3EF4_INCLUDED)
#define TIME_CONVERSION_HELPER_HPP_DA97E389_1797_43BA_82AE_B071064B3EF4_INCLUDED
#include <ctime>
#include <boost/spirit/core.hpp>
#include <boost/spirit/symbols.hpp>
#if SPIRIT_VERSION >= 0x1700
#include <boost/spirit/actor/assign_actor.hpp>
#include <boost/spirit/actor/push_back_actor.hpp>
#endif // SPIRIT_VERSION >= 0x1700
#if !defined(spirit_append_actor)
#if SPIRIT_VERSION >= 0x1700
#define spirit_append_actor(actor) boost::spirit::push_back_a(actor)
#define spirit_assign_actor(actor) boost::spirit::assign_a(actor)
#else
#define spirit_append_actor(actor) boost::spirit::append(actor)
#define spirit_assign_actor(actor) boost::spirit::assign(actor)
#endif // SPIRIT_VERSION >= 0x1700
#endif // !defined(spirit_append_actor)
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace util {
namespace time_conversion {
using namespace std; // some systems have std::tm etc. in namespace std
///////////////////////////////////////////////////////////////////////////////
// define, whether the rule's should generate some debug output
#define TRACE_CPP_TIME_CONVERSION \
(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_TIME_CONVERSION) \
/**/
///////////////////////////////////////////////////////////////////////////////
// Grammar for parsing a date/time string generated by the C++ compiler from
// __DATE__ and __TIME__
class time_conversion_grammar :
public boost::spirit::grammar<time_conversion_grammar>
{
public:
time_conversion_grammar() : fYearIsCorrected(false)
{
memset (&time_stamp, 0, sizeof(tm));
BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME(*this, "time_conversion_grammar",
TRACE_CPP_TIME_CONVERSION);
}
template <typename ScannerT>
struct definition {
definition(time_conversion_grammar const &self)
{
using boost::spirit::int_p;
using boost::spirit::add;
char const *m[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
for (int i = 0; i < 12; ++i)
add (month, m[i], i);
time_rule // expected format is 'Dec 29 2001 11:23:59'
= month[spirit_assign_actor(self.time_stamp.tm_mon)]
>> int_p[spirit_assign_actor(self.time_stamp.tm_mday)]
>> int_p[spirit_assign_actor(self.time_stamp.tm_year)]
>> int_p[spirit_assign_actor(self.time_stamp.tm_hour)]
>> int_p[spirit_assign_actor(self.time_stamp.tm_min)]
>> int_p[spirit_assign_actor(self.time_stamp.tm_sec)]
;
BOOST_SPIRIT_DEBUG_TRACE_RULE(time_rule, TRACE_CPP_TIME_CONVERSION);
}
boost::spirit::rule<ScannerT> time_rule;
boost::spirit::symbols<> month;
boost::spirit::rule<ScannerT> const&
start() const { return time_rule; }
};
void correct_year()
{
if (!fYearIsCorrected) {
time_stamp.tm_year -= 1900;
fYearIsCorrected = true;
}
}
mutable tm time_stamp;
bool fYearIsCorrected;
};
///////////////////////////////////////////////////////////////////////////////
// calculate the time of the compilation as a std::time_t to ensure correctness
// of the saved dfa table
class time_conversion_helper
{
public:
time_conversion_helper(char const *act_time) : compile_time(0)
{
using namespace boost::spirit;
time_conversion_grammar g;
if (parse (act_time, g, space_p | ch_p(':')).full) {
g.correct_year();
compile_time = mktime(&g.time_stamp);
}
BOOST_ASSERT(0 != compile_time);
}
time_t get_time() const { return compile_time; }
private:
time_t compile_time;
};
///////////////////////////////////////////////////////////////////////////////
#undef TRACE_CPP_TIME_CONVERSION
} // namespace time_conversion
// import time_conversion into the boost::wave::util namespace
using namespace time_conversion;
///////////////////////////////////////////////////////////////////////////////
} // namespace util
} // namespace wave
} // namespace boost
#endif // !defined(TIME_CONVERSION_HELPER_HPP_DA97E389_1797_43BA_82AE_B071064B3EF4_INCLUDED)

View File

@@ -1,151 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(TRANSFORM_ITERATOR_HPP_D492C659_88C7_4258_8C42_192F9AE80EC0_INCLUDED)
#define TRANSFORM_ITERATOR_HPP_D492C659_88C7_4258_8C42_192F9AE80EC0_INCLUDED
#include <boost/iterator_adaptors.hpp>
#if BOOST_ITERATOR_ADAPTORS_VERSION >= 0x0200
#include <boost/iterator/transform_iterator.hpp>
#endif // BOOST_ITERATOR_ADAPTORS_VERSION >= 0x0200
#include <boost/assert.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace impl {
#if BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
///////////////////////////////////////////////////////////////////////////////
//
// Transform Iterator Adaptor
//
// Upon deference, apply some unary function object and return the
// result by reference.
//
// This class is adapted from the Boost.Iterator library, where a similar
// class exists, which returns the next item by value
template <class AdaptableUnaryFunctionT>
struct ref_transform_iterator_policies
: public boost::default_iterator_policies
{
ref_transform_iterator_policies()
{}
ref_transform_iterator_policies(const AdaptableUnaryFunctionT &f)
: m_f(f) {}
template <class IteratorAdaptorT>
typename IteratorAdaptorT::reference
dereference(const IteratorAdaptorT &iter) const
{ return m_f(*iter.base()); }
AdaptableUnaryFunctionT m_f;
};
template <class AdaptableUnaryFunctionT, class IteratorT>
class ref_transform_iterator_generator
{
typedef typename AdaptableUnaryFunctionT::result_type value_type;
public:
typedef boost::iterator_adaptor<
IteratorT,
ref_transform_iterator_policies<AdaptableUnaryFunctionT>,
value_type, value_type const &, value_type const *,
std::input_iterator_tag>
type;
};
template <class AdaptableUnaryFunctionT, class IteratorT>
inline
typename ref_transform_iterator_generator<
AdaptableUnaryFunctionT, IteratorT>::type
make_ref_transform_iterator(
IteratorT base,
const AdaptableUnaryFunctionT &f = AdaptableUnaryFunctionT())
{
typedef typename ref_transform_iterator_generator<
AdaptableUnaryFunctionT, IteratorT>::type
result_t;
return result_t(base, f);
}
// Retrieve the token value given a parse node
// This is used in conjunction with the ref_transform_iterator above, to
// get the token values while iterating directly over the parse tree.
template <typename TokenT, typename ParseTreeNodeT>
struct get_token_value {
typedef TokenT result_type;
TokenT const &operator()(ParseTreeNodeT const &node) const
{
BOOST_ASSERT(1 == std::distance(node.value.begin(),
node.value.end()));
return *node.value.begin();
}
};
#else
template <class AdaptableUnaryFunctionT, class IteratorT>
class ref_transform_iterator_generator
{
typedef typename AdaptableUnaryFunctionT::result_type return_type;
typedef typename AdaptableUnaryFunctionT::argument_type argument_type;
public:
typedef boost::transform_iterator<
return_type (*)(argument_type), IteratorT, return_type>
type;
};
template <class AdaptableUnaryFunctionT, class IteratorT>
inline
typename ref_transform_iterator_generator<
AdaptableUnaryFunctionT, IteratorT>::type
make_ref_transform_iterator(
IteratorT base, AdaptableUnaryFunctionT const &f)
{
typedef typename ref_transform_iterator_generator<
AdaptableUnaryFunctionT, IteratorT>::type
iterator_type;
return iterator_type(base, f.transform);
}
// Retrieve the token value given a parse node
// This is used in conjunction with the ref_transform_iterator above, to
// get the token values while iterating directly over the parse tree.
template <typename TokenT, typename ParseTreeNodeT>
struct get_token_value {
typedef TokenT const &result_type;
typedef ParseTreeNodeT const &argument_type;
static result_type
transform (argument_type node)
{
BOOST_ASSERT(1 == std::distance(node.value.begin(),
node.value.end()));
return *node.value.begin();
}
};
#endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
///////////////////////////////////////////////////////////////////////////////
} // namespace impl
} // namespace wave
} // namespace boost
#endif // !defined(TRANSFORM_ITERATOR_HPP_D492C659_88C7_4258_8C42_192F9AE80EC0_INCLUDED)

View File

@@ -1,455 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Definition of the unput queue iterator
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(UNPUT_QUEUE_ITERATOR_HPP_76DA23D0_4893_4AD5_ABCC_6CED7CFB89BC_INCLUDED)
#define UNPUT_QUEUE_ITERATOR_HPP_76DA23D0_4893_4AD5_ABCC_6CED7CFB89BC_INCLUDED
#include <list>
#include <boost/assert.hpp>
#include <boost/iterator_adaptors.hpp>
#include <boost/wave/wave_config.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace util {
#if !defined(BOOST_ITERATOR_ADAPTORS_VERSION) || \
BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
template <typename TokenT, typename ContainerT>
class unput_queue_policies : public boost::default_iterator_policies
{
public:
unput_queue_policies(ContainerT &unput_queue_)
: unput_queue(unput_queue_)
{}
unput_queue_policies &operator= (unput_queue_policies const &rhs)
{
unput_queue = rhs.unput_queue;
return *this;
}
template <typename BaseT>
void initialize(BaseT &)
{}
template <typename IteratorAdaptorT>
typename IteratorAdaptorT::reference
dereference(const IteratorAdaptorT &x) const
{
if (x.policies().unput_queue.size() > 0)
return x.policies().unput_queue.front();
return *x.base();
}
template <typename IteratorAdaptorT>
void
increment(IteratorAdaptorT &x)
{
if (x.policies().unput_queue.size() > 0) {
// there exist pending tokens in the unput queue
x.policies().unput_queue.pop_front();
}
else {
// the unput_queue is empty, so advance the base iterator
++x.base();
}
}
template <typename IteratorAdaptorT1, typename IteratorAdaptorT2>
bool
equal(const IteratorAdaptorT1 &x, const IteratorAdaptorT2 &y) const
{
// two iterators are equal, if both begin() iterators of the queue objects
// are equal and the base iterators are equal as well
return
(x.policies().unput_queue.begin() == y.policies().unput_queue.begin() ||
(0 == x.policies().queuesize() && 0 == y.policies().queuesize())) &&
x.base() == y.base();
}
typename ContainerT::size_type queuesize() const
{ return unput_queue.size(); }
ContainerT &get_unput_queue() { return unput_queue; }
ContainerT const &get_unput_queue() const { return unput_queue; }
private:
ContainerT &unput_queue;
};
///////////////////////////////////////////////////////////////////////////////
//
// unput_queue_iterator
//
// The unput_queue_iterator templates encapsulates an unput_queue together
// with the direct input to be read after the unput queue is emptied
//
// This version is for the old iterator_adaptors (Boost V1.30.x)
//
///////////////////////////////////////////////////////////////////////////////
template <typename IteratorT, typename TokenT, typename ContainerT>
class unput_queue_iterator
: public boost::iterator_adaptor<
IteratorT, unput_queue_policies<TokenT, ContainerT>, TokenT,
TokenT const &, TokenT const *>
{
typedef
boost::iterator_adaptor<
IteratorT, unput_queue_policies<TokenT, ContainerT>, TokenT,
TokenT const &, TokenT const *
>
base_type;
typedef unput_queue_policies<TokenT, ContainerT> policies_type;
public:
typedef ContainerT container_type;
typedef IteratorT iterator_type;
unput_queue_iterator(IteratorT const &it, ContainerT &queue)
: base_type(it, policies_type(queue))
{}
ContainerT &get_unput_queue()
{ return policies().get_unput_queue(); }
ContainerT const &get_unput_queue() const
{ return policies().get_unput_queue(); }
IteratorT &get_base_iterator()
{ return base(); }
IteratorT const &get_base_iterator() const
{ return base(); }
};
#else // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
///////////////////////////////////////////////////////////////////////////////
//
// unput_queue_iterator
//
// The unput_queue_iterator templates encapsulates an unput_queue together
// with the direct input to be read after the unput queue is emptied
//
// This version is for the new iterator_adaptors (was released with
// Boost V1.31.0)
//
///////////////////////////////////////////////////////////////////////////////
template <typename IteratorT, typename TokenT, typename ContainerT>
class unput_queue_iterator
: public boost::iterator_adaptor<
unput_queue_iterator<IteratorT, TokenT, ContainerT>,
IteratorT, TokenT const, std::forward_iterator_tag>
{
typedef boost::iterator_adaptor<
unput_queue_iterator<IteratorT, TokenT, ContainerT>,
IteratorT, TokenT const, std::forward_iterator_tag>
base_type;
public:
typedef ContainerT container_type;
typedef IteratorT iterator_type;
unput_queue_iterator(IteratorT const &it, ContainerT &queue)
: base_type(it), unput_queue(queue)
{}
ContainerT &get_unput_queue()
{ return unput_queue; }
ContainerT const &get_unput_queue() const
{ return unput_queue; }
IteratorT &get_base_iterator()
{ return base_type::base_reference(); }
IteratorT const &get_base_iterator() const
{ return base_type::base_reference(); }
unput_queue_iterator &operator= (unput_queue_iterator const &rhs)
{
if (this != &rhs) {
unput_queue = rhs.unput_queue;
base_type::operator=(rhs);
}
return *this;
}
typename base_type::reference dereference() const
{
if (!unput_queue.empty())
return unput_queue.front();
return *base_type::base_reference();
}
void increment()
{
if (!unput_queue.empty()) {
// there exist pending tokens in the unput queue
unput_queue.pop_front();
}
else {
// the unput_queue is empty, so advance the base iterator
++base_type::base_reference();
}
}
template <
typename OtherDerivedT, typename OtherIteratorT,
typename V, typename C, typename R, typename D
>
bool equal(
boost::iterator_adaptor<OtherDerivedT, OtherIteratorT, V, C, R, D>
const &x) const
{
// two iterators are equal, if both begin() iterators of the queue
// objects are equal and the base iterators are equal as well
OtherDerivedT const &rhs = static_cast<OtherDerivedT const &>(x);
return
(unput_queue.empty() && rhs.unput_queue.empty() ||
(&unput_queue == &rhs.unput_queue &&
unput_queue.begin() == rhs.unput_queue.begin()
)
) &&
get_base_iterator() == rhs.get_base_iterator();
}
private:
ContainerT &unput_queue;
};
#endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
namespace impl {
///////////////////////////////////////////////////////////////////////////
template <typename IteratorT, typename TokenT, typename ContainerT>
struct gen_unput_queue_iterator
{
typedef ContainerT container_type;
typedef IteratorT iterator_type;
typedef unput_queue_iterator<IteratorT, TokenT, ContainerT>
return_type;
static container_type last;
static return_type
generate(iterator_type const &it)
{
return return_type(it, last);
}
static return_type
generate(ContainerT &queue, iterator_type const &it)
{
return return_type(it, queue);
}
};
template <typename IteratorT, typename TokenT, typename ContainerT>
typename gen_unput_queue_iterator<IteratorT, TokenT, ContainerT>::
container_type
gen_unput_queue_iterator<IteratorT, TokenT, ContainerT>::last =
typename gen_unput_queue_iterator<IteratorT, TokenT, ContainerT>::
container_type();
///////////////////////////////////////////////////////////////////////////
template <typename IteratorT, typename TokenT, typename ContainerT>
struct gen_unput_queue_iterator<
unput_queue_iterator<IteratorT, TokenT, ContainerT>,
TokenT, ContainerT>
{
typedef ContainerT container_type;
typedef unput_queue_iterator<IteratorT, TokenT, ContainerT>
iterator_type;
typedef unput_queue_iterator<IteratorT, TokenT, ContainerT>
return_type;
static container_type last;
static return_type
generate(iterator_type &it)
{
return return_t(it.base(), last);
}
static return_type
generate(ContainerT &queue, iterator_type &it)
{
return return_t(it.base(), queue);
}
};
///////////////////////////////////////////////////////////////////////////
template <typename IteratorT>
struct assign_iterator {
static void
do_ (IteratorT &dest, IteratorT const &src)
{
dest = src;
}
};
#if !defined(BOOST_ITERATOR_ADAPTORS_VERSION) || \
BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
template <typename IteratorT, typename TokenT, typename ContainerT>
struct assign_iterator<
unput_queue_iterator<IteratorT, TokenT, ContainerT> >
{
typedef unput_queue_iterator<IteratorT, TokenT, ContainerT>
iterator_type;
static void
do_ (iterator_type &dest, iterator_type const &src)
{
dest.base() = src.base();
dest.policies() = src.policies();
}
};
#endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
///////////////////////////////////////////////////////////////////////////
//
// Look for the first non-whitespace token and return this token id.
// Note though, that the embedded unput_queues are not touched in any way!
//
template <typename IteratorT>
struct next_token {
static boost::wave::token_id
peek(IteratorT it, IteratorT end, bool skip_whitespace = true)
{
using namespace boost::wave;
if (skip_whitespace) {
for (++it; it != end; ++it) {
if (!IS_CATEGORY(*it, WhiteSpaceTokenType) &&
T_NEWLINE != token_id(*it))
{
break; // stop at the first non-whitespace token
}
}
}
else {
++it; // we have at least to look ahead
}
if (it != end)
return token_id(*it);
return T_EOI;
}
};
template <typename IteratorT, typename TokenT, typename ContainerT>
struct next_token<
unput_queue_iterator<IteratorT, TokenT, ContainerT> > {
typedef unput_queue_iterator<IteratorT, TokenT, ContainerT> iterator_type;
static boost::wave::token_id
peek(iterator_type it, iterator_type end, bool skip_whitespace = true)
{
using namespace boost::wave;
typename iterator_type::container_type &queue = it.get_unput_queue();
// first try to find it in the unput_queue
if (0 != queue.size()) {
typename iterator_type::container_type::iterator cit = queue.begin();
typename iterator_type::container_type::iterator cend = queue.end();
if (skip_whitespace) {
for (++cit; cit != cend; ++cit) {
if (!IS_CATEGORY(*cit, WhiteSpaceTokenType) &&
T_NEWLINE != token_id(*cit))
{
break; // stop at the first non-whitespace token
}
}
}
else {
++cit; // we have at least to look ahead
}
if (cit != cend)
return token_id(*cit);
}
// second try to move on into the base iterator stream
typename iterator_type::iterator_type base_it = it.get_base_iterator();
typename iterator_type::iterator_type base_end = end.get_base_iterator();
if (0 == queue.size())
++base_it; // advance, if the unput queue is empty
if (skip_whitespace) {
for (/**/; base_it != base_end; ++base_it) {
if (!IS_CATEGORY(*base_it, WhiteSpaceTokenType) &&
T_NEWLINE != token_id(*base_it))
{
break; // stop at the first non-whitespace token
}
}
}
if (base_it == base_end)
return T_EOI;
return token_id(*base_it);
}
};
// Skip all whitespace characters and queue the skipped characters into the
// given container
template <typename IteratorT>
inline boost::wave::token_id
skip_whitespace(IteratorT &first, IteratorT const &last)
{
using namespace cpplexer;
token_id id = next_token<IteratorT>::peek(first, last, false);
if (IS_CATEGORY(id, WhiteSpaceTokenType)) {
do {
++first;
id = next_token<IteratorT>::peek(first, last, false);
} while (IS_CATEGORY(id, WhiteSpaceTokenType));
}
++first;
return id;
}
template <typename IteratorT, typename ContainerT>
inline boost::wave::token_id
skip_whitespace(IteratorT &first, IteratorT const &last, ContainerT &queue)
{
using namespace cpplexer;
queue.push_back (*first); // queue up the current token
token_id id = next_token<IteratorT>::peek(first, last, false);
if (IS_CATEGORY(id, WhiteSpaceTokenType)) {
do {
queue.push_back(*++first); // queue up the next whitespace
id = next_token<IteratorT>::peek(first, last, false);
} while (IS_CATEGORY(id, WhiteSpaceTokenType));
}
++first;
return id;
}
///////////////////////////////////////////////////////////////////////////////
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
} // namespace util
} // namespace wave
} // namespace boost
#endif // !defined(UNPUT_QUEUE_ITERATOR_HPP_76DA23D0_4893_4AD5_ABCC_6CED7CFB89BC_INCLUDED)

View File

@@ -1,271 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
Global application configuration
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(WAVE_CONFIG_HPP_F143F90A_A63F_4B27_AC41_9CA4F14F538D_INCLUDED)
#define WAVE_CONFIG_HPP_F143F90A_A63F_4B27_AC41_9CA4F14F538D_INCLUDED
#include <boost/config.hpp>
#include <boost/version.hpp>
#include <boost/spirit/version.hpp>
#include <boost/wave/wave_version.hpp>
///////////////////////////////////////////////////////////////////////////////
// Define the maximal include nesting depth allowed. If this value isn't
// defined it defaults to 1024
//
// To define a new initial include nesting depth uncomment the following and
// supply a new integer value.
//
#if !defined(BOOST_WAVE_MAX_INCLUDE_LEVEL_DEPTH)
#define BOOST_WAVE_MAX_INCLUDE_LEVEL_DEPTH 1024
#endif
///////////////////////////////////////////////////////////////////////////////
// Decide, whether to support variadics and placemarkers
//
// To implement support variadics and placemarkers uncomment the following
//
#if !defined(BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS)
#define BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS 1
#endif
///////////////////////////////////////////////////////////////////////////////
// Decide, whether to implement a #warning directive as an extension to the
// C++ Standard (same as #error, but emits a warning, not an error)
//
// To implement #warning directives, uncomment the following
//
#if !defined(BOOST_WAVE_SUPPORT_WARNING_DIRECTIVE)
#define BOOST_WAVE_SUPPORT_WARNING_DIRECTIVE 1
#endif
///////////////////////////////////////////////////////////////////////////////
// Decide, whether to implement #pragma once
//
// To implement #pragma once, uncomment the following
//
#if !defined(BOOST_WAVE_SUPPORT_PRAGMA_ONCE)
#define BOOST_WAVE_SUPPORT_PRAGMA_ONCE 1
#endif
///////////////////////////////////////////////////////////////////////////////
// Decide, whether to implement #include_next
// Please note, that this is an extension to the C++ Standard.
//
// To implement #include_next, uncomment the following
//
#if !defined(BOOST_WAVE_SUPPORT_INCLUDE_NEXT)
#define BOOST_WAVE_SUPPORT_INCLUDE_NEXT 1
#endif
///////////////////////////////////////////////////////////////////////////////
// Undefine the following, to enable some MS specific language extensions:
// __int8, __int16, __int32, __int64, __based, __declspec, __cdecl,
// __fastcall, __stdcall, __try, __except, __finally, __leave, __inline,
// __asm
#if !defined(BOOST_WAVE_SUPPORT_MS_EXTENSIONS)
#define BOOST_WAVE_SUPPORT_MS_EXTENSIONS 1
#endif
///////////////////////////////////////////////////////////////////////////////
// Allow the message body of the #error and #warning directives to be
// preprocessed before the diagnostic is issued.
//
// Uncommenting the following will preprocess the message bodies of #error and
// #warning messages before the error (warning) is issued
//
#if !defined(BOOST_WAVE_PREPROCESS_ERROR_MESSAGE_BODY)
#define BOOST_WAVE_PREPROCESS_ERROR_MESSAGE_BODY 1
#endif
///////////////////////////////////////////////////////////////////////////////
// Allow the #pragma directives to be returned to the caller (optionally after
// preprocessing the body)
//
// Uncommenting the following will skip #pragma directives, so that the caller
// will not see them.
//
#if !defined(BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES)
#define BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES 1
#endif
///////////////////////////////////////////////////////////////////////////////
// Allow the body of a #pragma directive to be preprocessed before the
// directive is returned to the caller.
//
// Uncommenting the following will preprocess the bodies of #pragma directives
//
#if !defined(BOOST_WAVE_PREPROCESS_PRAGMA_BODY)
#define BOOST_WAVE_PREPROCESS_PRAGMA_BODY 1
#endif
///////////////////////////////////////////////////////////////////////////////
// Allow to define macros with the command line syntax (-DMACRO(x)=definition)
//
// Uncommenting the following will enable the possibility to define macros
// based on the command line syntax
//
#if !defined(BOOST_WAVE_ENABLE_COMMANDLINE_MACROS)
#define BOOST_WAVE_ENABLE_COMMANDLINE_MACROS 1
#endif
///////////////////////////////////////////////////////////////////////////////
// Define the string type to be used to store the token values and the file
// names inside a file_position template class
//
#if !defined(BOOST_WAVE_STRINGTYPE)
// use the following, if you have a fast std::allocator<char>
#define BOOST_WAVE_STRINGTYPE boost::wave::util::flex_string< \
char, std::char_traits<char>, std::allocator<char>, \
boost::wave::util::CowString</*char, */\
boost::wave::util::AllocatorStringStorage<char> \
> \
> \
/**/
/* #define BOOST_WAVE_STRINGTYPE boost::wave::util::flex_string< \
char, std::char_traits<char>, boost::fast_pool_allocator<char>, \
boost::wave::util::CowString<char, \
boost::wave::util::AllocatorStringStorage<char, \
boost::fast_pool_allocator<char> \
> \
> \
> \
*/ /**/
// This include is needed for the flex_string class used in the
// BOOST_WAVE_STRINGTYPE above.
#include <boost/wave/util/flex_string.hpp>
// This include is needed for the boost::fast_allocator class used in the
// BOOST_WAVE_STRINGTYPE above.
// Configure Boost.Pool thread support (for now: no thread support at all)
//#define BOOST_NO_MT
//#include <boost/pool/pool_alloc.hpp>
// Use the following, if you want to incorporate Maxim Yegorushkin's
// const_string library (http://sourceforge.net/projects/conststring/), which
// may be even faster, than using the flex_string class from above
//#define BOOST_WAVE_STRINGTYPE boost::const_string<char>
//
//#include <boost/const_string/const_string.hpp>
//#include <boost/const_string/io.hpp>
//#include <boost/const_string/concatenation.hpp>
#endif
///////////////////////////////////////////////////////////////////////////////
// Uncomment the following, if you need debug output, the
// BOOST_SPIRIT_DEBUG_FLAGS constants below help to fine control the amount of
// the generated debug output
//#define BOOST_SPIRIT_DEBUG
///////////////////////////////////////////////////////////////////////////////
// debug flags for the Wave library, possible flags:
#define BOOST_SPIRIT_DEBUG_FLAGS_CPP_GRAMMAR 0x0001
#define BOOST_SPIRIT_DEBUG_FLAGS_TIME_CONVERSION 0x0002
#define BOOST_SPIRIT_DEBUG_FLAGS_CPP_EXPR_GRAMMAR 0x0004
#define BOOST_SPIRIT_DEBUG_FLAGS_INTLIT_GRAMMAR 0x0008
#define BOOST_SPIRIT_DEBUG_FLAGS_CHLIT_GRAMMAR 0x0010
#define BOOST_SPIRIT_DEBUG_FLAGS_DEFINED_GRAMMAR 0x0020
#define BOOST_SPIRIT_DEBUG_FLAGS_PREDEF_MACROS_GRAMMAR 0x0040
#if !defined(BOOST_SPIRIT_DEBUG_FLAGS_CPP)
#define BOOST_SPIRIT_DEBUG_FLAGS_CPP 0 // default is no debugging
#endif
///////////////////////////////////////////////////////////////////////////////
//
// For all recognized preprocessor statements the output parse trees
// formatted as xml are printed. The formatted parse trees are streamed to the
// std::ostream defined by the WAVE_DUMP_PARSE_TREE_OUT constant.
//
// Uncomment the following, if you want to see these parse trees.
//
#if !defined(BOOST_WAVE_DUMP_PARSE_TREE)
#define BOOST_WAVE_DUMP_PARSE_TREE 0
#endif
#if BOOST_WAVE_DUMP_PARSE_TREE != 0 && !defined(BOOST_WAVE_DUMP_PARSE_TREE_OUT)
#define BOOST_WAVE_DUMP_PARSE_TREE_OUT std::cerr
#endif
///////////////////////////////////////////////////////////////////////////////
//
// For all #if and #elif directives the preprocessed expressions are printed.
// These expressions are streamed to the std::ostream defined by the
// BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS_OUT constant.
//
// Uncomment the following, if you want to see the preprocessed expressions
//
#if !defined(BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS)
#define BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS 0
#endif
#if BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS != 0 && \
!defined(BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS_OUT)
#define BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS_OUT std::cerr
#endif
///////////////////////////////////////////////////////////////////////////////
// Decide, whether to use the separate compilation model for the instantiation
// of the C++ lexer objects.
//
// If this is defined, you should explicitly instantiate the C++ lexer
// template with the correct parameters in a separate compilation unit of
// your program (see the file instantiate_re2c_lexer.cpp).
//
// To use the lexer inclusion model, uncomment the following
//
#if !defined(BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION)
#define BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION 1
#endif
///////////////////////////////////////////////////////////////////////////////
// Decide, whether to use the separate compilation model for the instantiation
// of the grammar objects.
//
// If this is defined, you should explicitly instantiate the grammar
// templates with the correct parameters in a separate compilation unit of
// your program (see the files instantiate_cpp_grammar.cpp et.al.).
//
// To use the grammar inclusion model, uncomment the following
//
#if !defined(BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION)
#define BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION 1
#endif
///////////////////////////////////////////////////////////////////////////////
// configure Boost.Pool thread support (for now: no thread support at all)
#if !defined(BOOST_NO_MT)
#define BOOST_NO_MT
#endif // !defined(BOOST_NO_MT)
///////////////////////////////////////////////////////////////////////////////
// Auto library naming
#if BOOST_VERSION >= 103100
// auto link features work beginning from Boost V1.31.0
#if !defined(BOOST_WAVE_SOURCE) && !defined(BOOST_ALL_NO_LIB) && \
!defined(BOOST_WAVE_NO_LIB)
#define BOOST_LIB_NAME boost_wave
// tell the auto-link code to select a dll when required:
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_WAVE_DYN_LINK)
#define BOOST_DYN_LINK
#endif
#include <boost/config/auto_link.hpp>
#endif // auto-linking disabled
#endif // BOOST_VERSION
#endif // !defined(WAVE_CONFIG_HPP_F143F90A_A63F_4B27_AC41_9CA4F14F538D_INCLUDED)

View File

@@ -1,26 +0,0 @@
/*=============================================================================
Wave: A Standard compliant C++ preprocessor library
This is the current version of the Wave library
http://spirit.sourceforge.net/
Copyright (c) 2001-2005 Hartmut Kaiser. 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(WAVE_VERSION_H_9D79ABDB_AC54_4C0A_89B1_F70A2DCFE21E_INCLUDED)
#define WAVE_VERSION_H_9D79ABDB_AC54_4C0A_89B1_F70A2DCFE21E_INCLUDED
// BOOST_WAVE_VERSION & 0x0000FF is the sub-minor version
// BOOST_WAVE_VERSION & 0x00FF00 is the minor version
// BOOST_WAVE_VERSION & 0xFF0000 is the major version
#define BOOST_WAVE_VERSION 0x010113
// The following defines contain the same information as above
#define BOOST_WAVE_VERSION_MAJOR 1
#define BOOST_WAVE_VERSION_MINOR 1
#define BOOST_WAVE_VERSION_SUBMINOR 13
#endif // !defined(WAVE_VERSION_H_9D79ABDB_AC54_4C0A_89B1_F70A2DCFE21E_INCLUDED)