1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/wave/cpp_context.hpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,460 @@
1.4 +/*=============================================================================
1.5 + Boost.Wave: A Standard compliant C++ preprocessor library
1.6 + Definition of the preprocessor context
1.7 +
1.8 + http://www.boost.org/
1.9 +
1.10 + Copyright (c) 2001-2007 Hartmut Kaiser. Distributed under the Boost
1.11 + Software License, Version 1.0. (See accompanying file
1.12 + LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
1.13 +=============================================================================*/
1.14 +
1.15 +#if !defined(CPP_CONTEXT_HPP_907485E2_6649_4A87_911B_7F7225F3E5B8_INCLUDED)
1.16 +#define CPP_CONTEXT_HPP_907485E2_6649_4A87_911B_7F7225F3E5B8_INCLUDED
1.17 +
1.18 +#include <string>
1.19 +#include <vector>
1.20 +#include <stack>
1.21 +
1.22 +#include <boost/concept_check.hpp>
1.23 +#include <boost/noncopyable.hpp>
1.24 +#include <boost/filesystem/path.hpp>
1.25 +
1.26 +#include <boost/wave/wave_config.hpp>
1.27 +#if BOOST_WAVE_SERIALIZATION != 0
1.28 +#include <boost/serialization/serialization.hpp>
1.29 +#include <boost/wave/wave_config_constant.hpp>
1.30 +#endif
1.31 +#include <boost/wave/token_ids.hpp>
1.32 +
1.33 +#include <boost/wave/util/unput_queue_iterator.hpp>
1.34 +#include <boost/wave/util/cpp_ifblock.hpp>
1.35 +#include <boost/wave/util/cpp_include_paths.hpp>
1.36 +#include <boost/wave/util/iteration_context.hpp>
1.37 +#include <boost/wave/util/cpp_iterator.hpp>
1.38 +#include <boost/wave/util/cpp_macromap.hpp>
1.39 +
1.40 +#include <boost/wave/preprocessing_hooks.hpp>
1.41 +#include <boost/wave/whitespace_handling.hpp>
1.42 +#include <boost/wave/cpp_iteration_context.hpp>
1.43 +#include <boost/wave/language_support.hpp>
1.44 +
1.45 +// this must occur after all of the includes and before any code appears
1.46 +#ifdef BOOST_HAS_ABI_HEADERS
1.47 +#include BOOST_ABI_PREFIX
1.48 +#endif
1.49 +
1.50 +///////////////////////////////////////////////////////////////////////////////
1.51 +namespace boost {
1.52 +namespace wave {
1.53 +
1.54 +///////////////////////////////////////////////////////////////////////////////
1.55 +//
1.56 +// The C preprocessor context template class
1.57 +//
1.58 +// The boost::wave::context template is the main interface class to
1.59 +// control the behaviour of the preprocessing engine.
1.60 +//
1.61 +// The following template parameters has to be supplied:
1.62 +//
1.63 +// IteratorT The iterator type of the underlying input stream
1.64 +// LexIteratorT The lexer iterator type to use as the token factory
1.65 +// InputPolicyT The input policy type to use for loading the files
1.66 +// to be included. This template parameter is optional and
1.67 +// defaults to the
1.68 +// iteration_context_policies::load_file_to_string
1.69 +// type.
1.70 +// HooksT The hooks policy to use for different notification
1.71 +// callbacks. This template parameter is optional and
1.72 +// defaults to the
1.73 +// context_policies::default_preprocessing_hooks
1.74 +// type.
1.75 +//
1.76 +///////////////////////////////////////////////////////////////////////////////
1.77 +
1.78 +template <
1.79 + typename IteratorT,
1.80 + typename LexIteratorT,
1.81 + typename InputPolicyT = iteration_context_policies::load_file_to_string,
1.82 + typename HooksT = context_policies::eat_whitespace<typename LexIteratorT::token_type>
1.83 +>
1.84 +class context : private boost::noncopyable
1.85 +{
1.86 +public:
1.87 +
1.88 +// concept checks
1.89 +// the given iterator shall be at least a forward iterator type
1.90 + BOOST_CLASS_REQUIRE(IteratorT, boost, ForwardIteratorConcept);
1.91 +
1.92 +// public typedefs
1.93 + typedef typename LexIteratorT::token_type token_type;
1.94 + typedef context<IteratorT, LexIteratorT, InputPolicyT, HooksT>
1.95 + self_type;
1.96 +
1.97 + typedef IteratorT target_iterator_type;
1.98 + typedef LexIteratorT lexer_type;
1.99 + typedef pp_iterator<self_type> iterator_type;
1.100 +
1.101 + typedef InputPolicyT input_policy_type;
1.102 + typedef typename token_type::position_type position_type;
1.103 +
1.104 +
1.105 +// type of a token sequence
1.106 + typedef std::list<token_type, boost::fast_pool_allocator<token_type> >
1.107 + token_sequence_type;
1.108 +// types of the policies
1.109 + typedef HooksT hook_policy_type;
1.110 +
1.111 +private:
1.112 +// stack of shared_ptr's to the pending iteration contexts
1.113 + typedef boost::shared_ptr<base_iteration_context<lexer_type> >
1.114 + iteration_ptr_type;
1.115 + typedef boost::wave::util::iteration_context_stack<iteration_ptr_type>
1.116 + iteration_context_stack_type;
1.117 + typedef typename iteration_context_stack_type::size_type iter_size_type;
1.118 +
1.119 + context *this_() { return this; } // avoid warning in constructor
1.120 +
1.121 +public:
1.122 + context(target_iterator_type const &first_, target_iterator_type const &last_,
1.123 + char const *fname = "<Unknown>", HooksT const &hooks_ = HooksT())
1.124 + : first(first_), last(last_), filename(fname)
1.125 +#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
1.126 + , current_filename(fname)
1.127 +#endif
1.128 + , macros(*this_())
1.129 + , language(language_support(
1.130 + support_cpp
1.131 + | support_option_convert_trigraphs
1.132 + | support_option_emit_line_directives
1.133 +#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
1.134 + | support_option_include_guard_detection
1.135 +#endif
1.136 + ))
1.137 + , hooks(hooks_)
1.138 + {
1.139 + macros.init_predefined_macros(fname);
1.140 + includes.init_initial_path();
1.141 + }
1.142 +
1.143 +// default copy constructor
1.144 +// default assignment operator
1.145 +// default destructor
1.146 +
1.147 +// iterator interface
1.148 + iterator_type begin()
1.149 + {
1.150 + std::string fname(filename);
1.151 + if (filename != "<Unknown>" && filename != "<stdin>") {
1.152 + using namespace boost::filesystem;
1.153 + path fpath(complete(path(filename)));
1.154 + fname = fpath.string();
1.155 + includes.set_current_directory(fname.c_str());
1.156 + }
1.157 + return iterator_type(*this, first, last, position_type(fname.c_str()));
1.158 + }
1.159 + iterator_type begin(
1.160 + target_iterator_type const &first_,
1.161 + target_iterator_type const &last_)
1.162 + {
1.163 + std::string fname(filename);
1.164 + if (filename != "<Unknown>" && filename != "<stdin>") {
1.165 + using namespace boost::filesystem;
1.166 + path fpath(complete(path(filename)));
1.167 + fname = fpath.string();
1.168 + includes.set_current_directory(fname.c_str());
1.169 + }
1.170 + return iterator_type(*this, first_, last_, position_type(fname.c_str()));
1.171 + }
1.172 + iterator_type end() const
1.173 + { return iterator_type(); }
1.174 +
1.175 +// maintain include paths
1.176 + bool add_include_path(char const *path_)
1.177 + { return includes.add_include_path(path_, false);}
1.178 + bool add_sysinclude_path(char const *path_)
1.179 + { return includes.add_include_path(path_, true);}
1.180 + void set_sysinclude_delimiter() { includes.set_sys_include_delimiter(); }
1.181 + typename iteration_context_stack_type::size_type get_iteration_depth() const
1.182 + { return iter_ctxs.size(); }
1.183 +
1.184 +// maintain defined macros
1.185 +#if BOOST_WAVE_ENABLE_COMMANDLINE_MACROS != 0
1.186 + bool add_macro_definition(std::string macrostring,
1.187 + bool is_predefined = false)
1.188 + { return boost::wave::util::add_macro_definition(*this, macrostring,
1.189 + is_predefined, get_language()); }
1.190 +#endif
1.191 + bool add_macro_definition(token_type const &name, bool has_params,
1.192 + std::vector<token_type> ¶meters, token_sequence_type &definition,
1.193 + bool is_predefined = false)
1.194 + { return macros.add_macro(name, has_params, parameters, definition,
1.195 + is_predefined); }
1.196 + template <typename IteratorT2>
1.197 + bool is_defined_macro(IteratorT2 const &begin, IteratorT2 const &end)
1.198 + { return macros.is_defined(begin, end); }
1.199 + bool get_macro_definition(typename token_type::string_type const &name,
1.200 + bool &has_params, bool &is_predefined, position_type &pos,
1.201 + std::vector<token_type> ¶meters, token_sequence_type &definition)
1.202 + {
1.203 + return macros.get_macro(name, has_params, is_predefined, pos,
1.204 + parameters, definition);
1.205 + }
1.206 + bool remove_macro_definition(typename token_type::string_type const &name,
1.207 + bool even_predefined = false)
1.208 + {
1.209 +#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
1.210 + // ensure this gets remove from the list of include guards as well
1.211 + includes.remove_pragma_once_header(std::string(name.c_str()));
1.212 +#endif
1.213 + return macros.remove_macro(
1.214 + token_type(T_IDENTIFIER, name, macros.get_main_pos()),
1.215 + even_predefined);
1.216 + }
1.217 + void reset_macro_definitions()
1.218 + { macros.reset_macromap(); macros.init_predefined_macros(); }
1.219 +
1.220 +// get the Wave version information
1.221 + static std::string get_version()
1.222 + { return boost::wave::util::predefined_macros::get_fullversion(false); }
1.223 + static std::string get_version_string()
1.224 + { return boost::wave::util::predefined_macros::get_versionstr(false); }
1.225 +
1.226 +// access current language options
1.227 + void set_language(boost::wave::language_support language_,
1.228 + bool reset_macros = true)
1.229 + {
1.230 + language = language_;
1.231 + if (reset_macros)
1.232 + reset_macro_definitions();
1.233 + }
1.234 + boost::wave::language_support get_language() const { return language; }
1.235 +
1.236 +// change and ask for maximal possible include nesting depth
1.237 + void set_max_include_nesting_depth(iter_size_type new_depth)
1.238 + { iter_ctxs.set_max_include_nesting_depth(new_depth); }
1.239 + iter_size_type get_max_include_nesting_depth() const
1.240 + { return iter_ctxs.get_max_include_nesting_depth(); }
1.241 +
1.242 +// access the policies
1.243 + hook_policy_type &get_hooks() { return hooks; }
1.244 +
1.245 +// return the directory of the currently preprocessed file
1.246 + boost::filesystem::path get_current_directory() const
1.247 + { return includes.get_current_directory(); }
1.248 +
1.249 +#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
1.250 +protected:
1.251 + friend class boost::wave::pp_iterator<
1.252 + boost::wave::context<IteratorT, lexer_type, InputPolicyT, HooksT> >;
1.253 + friend class boost::wave::impl::pp_iterator_functor<
1.254 + boost::wave::context<IteratorT, lexer_type, InputPolicyT, HooksT> >;
1.255 +#endif
1.256 +
1.257 +// maintain include paths (helper functions)
1.258 + bool find_include_file (std::string &s, std::string &d, bool is_system,
1.259 + char const *current_file) const
1.260 + { return includes.find_include_file(s, d, is_system, current_file); }
1.261 + void set_current_directory(char const *path_)
1.262 + { includes.set_current_directory(path_); }
1.263 +
1.264 +// conditional compilation contexts
1.265 + bool get_if_block_status() const { return ifblocks.get_status(); }
1.266 + bool get_if_block_some_part_status() const
1.267 + { return ifblocks.get_some_part_status(); }
1.268 + bool get_enclosing_if_block_status() const
1.269 + { return ifblocks.get_enclosing_status(); }
1.270 + void enter_if_block(bool new_status)
1.271 + { ifblocks.enter_if_block(new_status); }
1.272 + bool enter_elif_block(bool new_status)
1.273 + { return ifblocks.enter_elif_block(new_status); }
1.274 + bool enter_else_block() { return ifblocks.enter_else_block(); }
1.275 + bool exit_if_block() { return ifblocks.exit_if_block(); }
1.276 + typename boost::wave::util::if_block_stack::size_type get_if_block_depth() const
1.277 + { return ifblocks.get_if_block_depth(); }
1.278 +
1.279 +// stack of iteration contexts
1.280 + iteration_ptr_type pop_iteration_context()
1.281 + { iteration_ptr_type top = iter_ctxs.top(); iter_ctxs.pop(); return top; }
1.282 + void push_iteration_context(position_type const &act_pos, iteration_ptr_type iter_ctx)
1.283 + { iter_ctxs.push(act_pos, iter_ctx); }
1.284 +
1.285 + position_type &get_main_pos() { return macros.get_main_pos(); }
1.286 +
1.287 +///////////////////////////////////////////////////////////////////////////////
1.288 +//
1.289 +// expand_tokensequence():
1.290 +// expands all macros contained in a given token sequence, handles '##'
1.291 +// and '#' pp operators and re-scans the resulting sequence
1.292 +// (essentially pre-processes the token sequence).
1.293 +//
1.294 +// The expand_undefined parameter is true during macro expansion inside
1.295 +// a C++ expression given for a #if or #elif statement.
1.296 +//
1.297 +///////////////////////////////////////////////////////////////////////////////
1.298 + template <typename IteratorT2>
1.299 + token_type expand_tokensequence(IteratorT2 &first_, IteratorT2 const &last_,
1.300 + token_sequence_type &pending, token_sequence_type &expanded,
1.301 + bool expand_undefined = false)
1.302 + {
1.303 + return macros.expand_tokensequence(first_, last_, pending, expanded,
1.304 + expand_undefined);
1.305 + }
1.306 +
1.307 + template <typename IteratorT2>
1.308 + void expand_whole_tokensequence(IteratorT2 &first_, IteratorT2 const &last_,
1.309 + token_sequence_type &expanded, bool expand_undefined = true)
1.310 + {
1.311 + macros.expand_whole_tokensequence(expanded, first_, last_,
1.312 + expand_undefined);
1.313 +
1.314 + // remove any contained placeholder
1.315 + boost::wave::util::impl::remove_placeholders(expanded);
1.316 + }
1.317 +
1.318 +public:
1.319 +#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
1.320 +// support for #pragma once
1.321 +// maintain the real name of the current preprocessed file
1.322 + void set_current_filename(char const *real_name)
1.323 + { current_filename = real_name; }
1.324 + std::string const &get_current_filename() const
1.325 + { return current_filename; }
1.326 +
1.327 +// maintain the list of known headers containing #pragma once
1.328 + bool has_pragma_once(std::string const &filename_)
1.329 + { return includes.has_pragma_once(filename_); }
1.330 + bool add_pragma_once_header(std::string const &filename_,
1.331 + std::string const& guard_name = "__BOOST_WAVE_PRAGMA_ONCE__")
1.332 + { return includes.add_pragma_once_header(filename_, guard_name); }
1.333 +#endif
1.334 +
1.335 +// forwarding functions for the context policy hooks
1.336 + template <typename ContainerT>
1.337 + bool interpret_pragma(ContainerT &pending, token_type const &option,
1.338 + ContainerT const &values, token_type const &act_token)
1.339 + {
1.340 + return hooks.interpret_pragma(*this, pending, option, values, act_token);
1.341 + }
1.342 +
1.343 +#if BOOST_WAVE_SERIALIZATION != 0
1.344 +public:
1.345 + BOOST_STATIC_CONSTANT(unsigned int, version = 0x10);
1.346 + BOOST_STATIC_CONSTANT(unsigned int, version_mask = 0x0f);
1.347 +
1.348 +private:
1.349 + friend class boost::serialization::access;
1.350 + template<class Archive>
1.351 + void save(Archive & ar, const unsigned int version) const
1.352 + {
1.353 + typedef typename token_type::string_type string_type;
1.354 +
1.355 + string_type cfg(BOOST_PP_STRINGIZE(BOOST_WAVE_CONFIG));
1.356 + string_type kwd(BOOST_WAVE_PRAGMA_KEYWORD);
1.357 + string_type strtype(BOOST_PP_STRINGIZE((BOOST_WAVE_STRINGTYPE)));
1.358 + ar & cfg;
1.359 + ar & kwd;
1.360 + ar & strtype;
1.361 +
1.362 + ar & language;
1.363 + ar & macros;
1.364 + ar & includes;
1.365 + }
1.366 + template<class Archive>
1.367 + void load(Archive & ar, const unsigned int loaded_version)
1.368 + {
1.369 + if (version != (loaded_version & ~version_mask)) {
1.370 + BOOST_WAVE_THROW(preprocess_exception, incompatible_config,
1.371 + "cpp_context state version", get_main_pos());
1.372 + }
1.373 +
1.374 + // check compatibility of the stored information
1.375 + typedef typename token_type::string_type string_type;
1.376 + string_type config, pragma_keyword, string_type_str;
1.377 +
1.378 + ar & config; // BOOST_WAVE_CONFIG
1.379 + if (config != BOOST_PP_STRINGIZE(BOOST_WAVE_CONFIG)) {
1.380 + BOOST_WAVE_THROW(preprocess_exception, incompatible_config,
1.381 + "BOOST_WAVE_CONFIG", get_main_pos());
1.382 + }
1.383 +
1.384 + ar & pragma_keyword; // BOOST_WAVE_PRAGMA_KEYWORD
1.385 + if (pragma_keyword != BOOST_WAVE_PRAGMA_KEYWORD) {
1.386 + BOOST_WAVE_THROW(preprocess_exception, incompatible_config,
1.387 + "BOOST_WAVE_PRAGMA_KEYWORD", get_main_pos());
1.388 + }
1.389 +
1.390 + ar & string_type_str; // BOOST_PP_STRINGIZE((BOOST_WAVE_STRINGTYPE))
1.391 + if (string_type_str != BOOST_PP_STRINGIZE((BOOST_WAVE_STRINGTYPE))) {
1.392 + BOOST_WAVE_THROW(preprocess_exception, incompatible_config,
1.393 + "BOOST_WAVE_STRINGTYPE", get_main_pos());
1.394 + }
1.395 +
1.396 + // read in the useful bits
1.397 + ar & language;
1.398 + ar & macros;
1.399 + ar & includes;
1.400 + }
1.401 + BOOST_SERIALIZATION_SPLIT_MEMBER()
1.402 +#endif
1.403 +
1.404 +private:
1.405 +// the main input stream
1.406 + target_iterator_type first; // underlying input stream
1.407 + target_iterator_type last;
1.408 + std::string filename; // associated main filename
1.409 +#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
1.410 + std::string current_filename; // real name of current preprocessed file
1.411 +#endif
1.412 +
1.413 + boost::wave::util::if_block_stack ifblocks; // conditional compilation contexts
1.414 + boost::wave::util::include_paths includes; // lists of include directories to search
1.415 + iteration_context_stack_type iter_ctxs; // iteration contexts
1.416 + boost::wave::util::macromap<self_type> macros; // map of defined macros
1.417 + boost::wave::language_support language; // supported language/extensions
1.418 + hook_policy_type hooks; // hook policy instance
1.419 +};
1.420 +
1.421 +///////////////////////////////////////////////////////////////////////////////
1.422 +} // namespace wave
1.423 +} // namespace boost
1.424 +
1.425 +#if BOOST_WAVE_SERIALIZATION != 0
1.426 +namespace boost { namespace serialization {
1.427 +
1.428 +template<
1.429 + typename Iterator, typename LexIterator,
1.430 + typename InputPolicy, typename Hooks
1.431 +>
1.432 +struct tracking_level<boost::wave::context<Iterator, LexIterator, InputPolicy, Hooks> >
1.433 +{
1.434 + typedef mpl::integral_c_tag tag;
1.435 + typedef mpl::int_<track_never> type;
1.436 + BOOST_STATIC_CONSTANT(
1.437 + int,
1.438 + value = tracking_level::type::value
1.439 + );
1.440 +};
1.441 +
1.442 +template<
1.443 + typename Iterator, typename LexIterator,
1.444 + typename InputPolicy, typename Hooks
1.445 +>
1.446 +struct version<boost::wave::context<Iterator, LexIterator, InputPolicy, Hooks> >
1.447 +{
1.448 + typedef boost::wave::context<Iterator, LexIterator, InputPolicy, Hooks>
1.449 + target_type;
1.450 + typedef mpl::int_<target_type::version> type;
1.451 + typedef mpl::integral_c_tag tag;
1.452 + BOOST_STATIC_CONSTANT(unsigned int, value = version::type::value);
1.453 +};
1.454 +
1.455 +}} // namespace boost::serialization
1.456 +#endif
1.457 +
1.458 +// the suffix header occurs after all of the code
1.459 +#ifdef BOOST_HAS_ABI_HEADERS
1.460 +#include BOOST_ABI_SUFFIX
1.461 +#endif
1.462 +
1.463 +#endif // !defined(CPP_CONTEXT_HPP_907485E2_6649_4A87_911B_7F7225F3E5B8_INCLUDED)