|
Server : Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8e-fips-rhel5 DAV/2 PHP/5.2.17 System : Linux localhost 2.6.18-419.el5 #1 SMP Fri Feb 24 22:47:42 UTC 2017 x86_64 User : nobody ( 99) PHP Version : 5.2.17 Disable Function : NONE Directory : /usr/include/boost/wave/ |
Upload File : |
/*=============================================================================
Boost.Wave: A Standard compliant C++ preprocessor library
Definition of the preprocessor context
http://www.boost.org/
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_paths.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;
// the context object should not be copied around
context(context const& rhs);
context& operator= (context const& rhs);
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(fname);
includes.init_initial_path();
}
// iterator interface
iterator_type begin()
{
includes.set_current_directory(filename.c_str());
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> ¶meters, 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(
token_type(T_IDENTIFIER, name, macros.get_main_pos()),
even_predefined);
}
bool remove_macro_definition(token_type const &token,
bool even_predefined = false)
{ return macros.remove_macro(token, 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 paths (helper functions)
bool find_include_file (std::string &s, std::string &d, bool is_system,
char const *current_file) const
{ return includes.find_include_file(s, d, 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 ¶meters, DefinitionT const &definition,
bool is_predefined)
{
trace.defined_macro(name, is_functionlike, parameters, definition,
is_predefined);
}
void undefined_macro(token_type const &token)
{
trace.undefined_macro(token);
}
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_paths 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)