annotate DEPENDENCIES/generic/include/boost/wave/cpp_context.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 /*=============================================================================
Chris@16 2 Boost.Wave: A Standard compliant C++ preprocessor library
Chris@16 3 Definition of the preprocessor context
Chris@16 4
Chris@16 5 http://www.boost.org/
Chris@16 6
Chris@16 7 Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
Chris@16 8 Software License, Version 1.0. (See accompanying file
Chris@16 9 LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 10 =============================================================================*/
Chris@16 11
Chris@16 12 #if !defined(CPP_CONTEXT_HPP_907485E2_6649_4A87_911B_7F7225F3E5B8_INCLUDED)
Chris@16 13 #define CPP_CONTEXT_HPP_907485E2_6649_4A87_911B_7F7225F3E5B8_INCLUDED
Chris@16 14
Chris@16 15 #include <string>
Chris@16 16 #include <vector>
Chris@16 17 #include <stack>
Chris@16 18
Chris@16 19 #include <boost/concept_check.hpp>
Chris@16 20 #include <boost/noncopyable.hpp>
Chris@16 21 #include <boost/filesystem/path.hpp>
Chris@16 22 #include <boost/mpl/if.hpp>
Chris@16 23 #include <boost/type_traits/is_same.hpp>
Chris@16 24 #include <boost/pool/pool_alloc.hpp>
Chris@16 25
Chris@16 26 #include <boost/wave/wave_config.hpp>
Chris@16 27 #if BOOST_WAVE_SERIALIZATION != 0
Chris@16 28 #include <boost/serialization/serialization.hpp>
Chris@16 29 #include <boost/wave/wave_config_constant.hpp>
Chris@16 30 #endif
Chris@16 31 #include <boost/wave/token_ids.hpp>
Chris@16 32
Chris@16 33 #include <boost/wave/util/unput_queue_iterator.hpp>
Chris@16 34 #include <boost/wave/util/cpp_ifblock.hpp>
Chris@16 35 #include <boost/wave/util/cpp_include_paths.hpp>
Chris@16 36 #include <boost/wave/util/iteration_context.hpp>
Chris@16 37 #include <boost/wave/util/cpp_iterator.hpp>
Chris@16 38 #include <boost/wave/util/cpp_macromap.hpp>
Chris@16 39
Chris@16 40 #include <boost/wave/preprocessing_hooks.hpp>
Chris@16 41 #include <boost/wave/whitespace_handling.hpp>
Chris@16 42 #include <boost/wave/cpp_iteration_context.hpp>
Chris@16 43 #include <boost/wave/language_support.hpp>
Chris@16 44
Chris@16 45 // this must occur after all of the includes and before any code appears
Chris@16 46 #ifdef BOOST_HAS_ABI_HEADERS
Chris@16 47 #include BOOST_ABI_PREFIX
Chris@16 48 #endif
Chris@16 49
Chris@16 50 ///////////////////////////////////////////////////////////////////////////////
Chris@16 51 namespace boost {
Chris@16 52 namespace wave {
Chris@16 53
Chris@16 54 ///////////////////////////////////////////////////////////////////////////////
Chris@16 55 //
Chris@16 56 // The C/C++ preprocessor context template class
Chris@16 57 //
Chris@16 58 // The boost::wave::context template is the main interface class to
Chris@16 59 // control the behavior of the preprocessing engine.
Chris@16 60 //
Chris@16 61 // The following template parameters has to be supplied:
Chris@16 62 //
Chris@16 63 // IteratorT The iterator type of the underlying input stream
Chris@16 64 // LexIteratorT The lexer iterator type to use as the token factory
Chris@16 65 // InputPolicyT The input policy type to use for loading the files
Chris@16 66 // to be included. This template parameter is optional and
Chris@16 67 // defaults to the
Chris@16 68 // iteration_context_policies::load_file_to_string
Chris@16 69 // type.
Chris@16 70 // HooksT The hooks policy to use for different notification
Chris@16 71 // callbacks. This template parameter is optional and
Chris@16 72 // defaults to the
Chris@16 73 // context_policies::default_preprocessing_hooks
Chris@16 74 // type.
Chris@16 75 // DerivedT The type of the type being derived from the context
Chris@16 76 // type (if any). This template parameter is optional and
Chris@16 77 // defaults to 'this_type', which means that the context
Chris@16 78 // type will be used assuming no derived type exists.
Chris@16 79 //
Chris@16 80 ///////////////////////////////////////////////////////////////////////////////
Chris@16 81
Chris@16 82 struct this_type {};
Chris@16 83
Chris@16 84 template <
Chris@16 85 typename IteratorT,
Chris@16 86 typename LexIteratorT,
Chris@16 87 typename InputPolicyT = iteration_context_policies::load_file_to_string,
Chris@16 88 typename HooksT = context_policies::eat_whitespace<typename LexIteratorT::token_type>,
Chris@16 89 typename DerivedT = this_type
Chris@16 90 >
Chris@16 91 class context : private boost::noncopyable
Chris@16 92 {
Chris@16 93 private:
Chris@16 94 typedef typename mpl::if_<
Chris@16 95 is_same<DerivedT, this_type>, context, DerivedT
Chris@16 96 >::type actual_context_type;
Chris@16 97
Chris@16 98 public:
Chris@16 99
Chris@16 100 // concept checks
Chris@16 101 // the given iterator should be at least a forward iterator type
Chris@16 102 BOOST_CLASS_REQUIRE(IteratorT, boost, ForwardIteratorConcept);
Chris@16 103
Chris@16 104 // public typedefs
Chris@16 105 typedef typename LexIteratorT::token_type token_type;
Chris@16 106 typedef typename token_type::string_type string_type;
Chris@16 107
Chris@16 108 typedef IteratorT target_iterator_type;
Chris@16 109 typedef LexIteratorT lexer_type;
Chris@16 110 typedef pp_iterator<context> iterator_type;
Chris@16 111
Chris@16 112 typedef InputPolicyT input_policy_type;
Chris@16 113 typedef typename token_type::position_type position_type;
Chris@16 114
Chris@16 115 // type of a token sequence
Chris@16 116 typedef std::list<token_type, boost::fast_pool_allocator<token_type> >
Chris@16 117 token_sequence_type;
Chris@16 118 // type of the policies
Chris@16 119 typedef HooksT hook_policy_type;
Chris@16 120
Chris@16 121 private:
Chris@16 122 // stack of shared_ptr's to the pending iteration contexts
Chris@16 123 typedef boost::shared_ptr<base_iteration_context<context, lexer_type> >
Chris@16 124 iteration_ptr_type;
Chris@16 125 typedef boost::wave::util::iteration_context_stack<iteration_ptr_type>
Chris@16 126 iteration_context_stack_type;
Chris@16 127 typedef typename iteration_context_stack_type::size_type iter_size_type;
Chris@16 128
Chris@16 129 context *this_() { return this; } // avoid warning in constructor
Chris@16 130
Chris@16 131 public:
Chris@16 132 context(target_iterator_type const &first_, target_iterator_type const &last_,
Chris@16 133 char const *fname = "<Unknown>", HooksT const &hooks_ = HooksT())
Chris@16 134 : first(first_), last(last_), filename(fname)
Chris@16 135 , has_been_initialized(false)
Chris@16 136 #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
Chris@16 137 , current_filename(fname)
Chris@16 138 #endif
Chris@16 139 , current_relative_filename(fname)
Chris@16 140 , macros(*this_())
Chris@16 141 , language(language_support(
Chris@16 142 support_cpp
Chris@16 143 | support_option_convert_trigraphs
Chris@16 144 | support_option_emit_line_directives
Chris@16 145 #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
Chris@16 146 | support_option_include_guard_detection
Chris@16 147 #endif
Chris@16 148 #if BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES != 0
Chris@16 149 | support_option_emit_pragma_directives
Chris@16 150 #endif
Chris@16 151 | support_option_insert_whitespace
Chris@16 152 ))
Chris@16 153 , hooks(hooks_)
Chris@16 154 {
Chris@16 155 macros.init_predefined_macros(fname);
Chris@16 156 }
Chris@16 157
Chris@16 158 // default copy constructor
Chris@16 159 // default assignment operator
Chris@16 160 // default destructor
Chris@16 161
Chris@16 162 // iterator interface
Chris@16 163 iterator_type begin()
Chris@16 164 {
Chris@16 165 std::string fname(filename);
Chris@16 166 if (filename != "<Unknown>" && filename != "<stdin>") {
Chris@16 167 using namespace boost::filesystem;
Chris@16 168 path fpath(util::complete_path(path(filename)));
Chris@16 169 fname = fpath.string();
Chris@16 170 }
Chris@16 171 return iterator_type(*this, first, last, position_type(fname.c_str()));
Chris@16 172 }
Chris@16 173 iterator_type begin(
Chris@16 174 target_iterator_type const &first_,
Chris@16 175 target_iterator_type const &last_)
Chris@16 176 {
Chris@16 177 std::string fname(filename);
Chris@16 178 if (filename != "<Unknown>" && filename != "<stdin>") {
Chris@16 179 using namespace boost::filesystem;
Chris@16 180 path fpath(util::complete_path(path(filename)));
Chris@16 181 fname = fpath.string();
Chris@16 182 }
Chris@16 183 return iterator_type(*this, first_, last_, position_type(fname.c_str()));
Chris@16 184 }
Chris@16 185 iterator_type end() const
Chris@16 186 { return iterator_type(); }
Chris@16 187
Chris@16 188 // maintain include paths
Chris@16 189 bool add_include_path(char const *path_)
Chris@16 190 { return includes.add_include_path(path_, false);}
Chris@16 191 bool add_sysinclude_path(char const *path_)
Chris@16 192 { return includes.add_include_path(path_, true);}
Chris@16 193 void set_sysinclude_delimiter() { includes.set_sys_include_delimiter(); }
Chris@16 194 typename iteration_context_stack_type::size_type get_iteration_depth() const
Chris@16 195 { return iter_ctxs.size(); }
Chris@16 196
Chris@16 197 // maintain defined macros
Chris@16 198 #if BOOST_WAVE_ENABLE_COMMANDLINE_MACROS != 0
Chris@16 199 template <typename StringT>
Chris@16 200 bool add_macro_definition(StringT macrostring, bool is_predefined = false)
Chris@16 201 {
Chris@16 202 return boost::wave::util::add_macro_definition(*this,
Chris@16 203 util::to_string<std::string>(macrostring), is_predefined,
Chris@16 204 get_language());
Chris@16 205 }
Chris@16 206 #endif
Chris@16 207 // Define and undefine macros, macro introspection
Chris@16 208 template <typename StringT>
Chris@16 209 bool add_macro_definition(StringT const &name, position_type const& pos,
Chris@16 210 bool has_params, std::vector<token_type> &parameters,
Chris@16 211 token_sequence_type &definition, bool is_predefined = false)
Chris@16 212 {
Chris@16 213 return macros.add_macro(
Chris@16 214 token_type(T_IDENTIFIER, util::to_string<string_type>(name), pos),
Chris@16 215 has_params, parameters, definition, is_predefined);
Chris@16 216 }
Chris@16 217 template <typename StringT>
Chris@16 218 bool is_defined_macro(StringT const &str) const
Chris@16 219 {
Chris@16 220 return macros.is_defined(util::to_string<string_type>(str));
Chris@16 221 }
Chris@16 222 template <typename StringT>
Chris@16 223 bool get_macro_definition(StringT const &name,
Chris@16 224 bool &has_params, bool &is_predefined, position_type &pos,
Chris@16 225 std::vector<token_type> &parameters,
Chris@16 226 token_sequence_type &definition) const
Chris@16 227 {
Chris@16 228 return macros.get_macro(util::to_string<string_type>(name),
Chris@16 229 has_params, is_predefined, pos, parameters, definition);
Chris@16 230 }
Chris@16 231 template <typename StringT>
Chris@16 232 bool remove_macro_definition(StringT const& undefname, bool even_predefined = false)
Chris@16 233 {
Chris@16 234 // strip leading and trailing whitespace
Chris@16 235 string_type name = util::to_string<string_type>(undefname);
Chris@16 236 typename string_type::size_type pos = name.find_first_not_of(" \t");
Chris@16 237 if (pos != string_type::npos) {
Chris@16 238 typename string_type::size_type endpos = name.find_last_not_of(" \t");
Chris@16 239 name = name.substr(pos, endpos-pos+1);
Chris@16 240 }
Chris@16 241
Chris@16 242 #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
Chris@16 243 // ensure this gets removed from the list of include guards as well
Chris@16 244 includes.remove_pragma_once_header(
Chris@16 245 util::to_string<std::string>(name));
Chris@16 246 #endif
Chris@16 247 return macros.remove_macro(name, macros.get_main_pos(), even_predefined);
Chris@16 248 }
Chris@16 249 void reset_macro_definitions()
Chris@16 250 { macros.reset_macromap(); macros.init_predefined_macros(); }
Chris@16 251
Chris@16 252 // Iterate over names of defined macros
Chris@16 253 typedef boost::wave::util::macromap<context> macromap_type;
Chris@16 254 typedef typename macromap_type::name_iterator name_iterator;
Chris@16 255 typedef typename macromap_type::const_name_iterator const_name_iterator;
Chris@16 256
Chris@16 257 name_iterator macro_names_begin() { return macros.begin(); }
Chris@16 258 name_iterator macro_names_end() { return macros.end(); }
Chris@16 259 const_name_iterator macro_names_begin() const { return macros.begin(); }
Chris@16 260 const_name_iterator macro_names_end() const { return macros.end(); }
Chris@16 261
Chris@16 262 // This version now is used internally mainly, but since it was a documented
Chris@16 263 // API function we leave it in the public interface.
Chris@16 264 bool add_macro_definition(token_type const &name, bool has_params,
Chris@16 265 std::vector<token_type> &parameters, token_sequence_type &definition,
Chris@16 266 bool is_predefined = false)
Chris@16 267 {
Chris@16 268 return macros.add_macro(name, has_params, parameters, definition,
Chris@16 269 is_predefined);
Chris@16 270 }
Chris@16 271
Chris@16 272 // get the Wave version information
Chris@16 273 static std::string get_version()
Chris@16 274 {
Chris@16 275 boost::wave::util::predefined_macros p;
Chris@16 276 return util::to_string<std::string>(p.get_fullversion());
Chris@16 277 }
Chris@16 278 static std::string get_version_string()
Chris@16 279 {
Chris@16 280 boost::wave::util::predefined_macros p;
Chris@16 281 return util::to_string<std::string>(p.get_versionstr());
Chris@16 282 }
Chris@16 283
Chris@16 284 // access current language options
Chris@16 285 void set_language(boost::wave::language_support language_,
Chris@16 286 bool reset_macros = true)
Chris@16 287 {
Chris@16 288 language = language_;
Chris@16 289 if (reset_macros)
Chris@16 290 reset_macro_definitions();
Chris@16 291 }
Chris@16 292 boost::wave::language_support get_language() const { return language; }
Chris@16 293
Chris@16 294 position_type &get_main_pos() { return macros.get_main_pos(); }
Chris@16 295 position_type const& get_main_pos() const { return macros.get_main_pos(); }
Chris@16 296
Chris@16 297 // change and ask for maximal possible include nesting depth
Chris@16 298 void set_max_include_nesting_depth(iter_size_type new_depth)
Chris@16 299 { iter_ctxs.set_max_include_nesting_depth(new_depth); }
Chris@16 300 iter_size_type get_max_include_nesting_depth() const
Chris@16 301 { return iter_ctxs.get_max_include_nesting_depth(); }
Chris@16 302
Chris@16 303 // access the policies
Chris@16 304 hook_policy_type &get_hooks() { return hooks; }
Chris@16 305 hook_policy_type const &get_hooks() const { return hooks; }
Chris@16 306
Chris@16 307 // return type of actually used context type (might be the derived type)
Chris@16 308 actual_context_type& derived()
Chris@16 309 { return *static_cast<actual_context_type*>(this); }
Chris@16 310 actual_context_type const& derived() const
Chris@16 311 { return *static_cast<actual_context_type const*>(this); }
Chris@16 312
Chris@16 313 // return the directory of the currently preprocessed file
Chris@16 314 boost::filesystem::path get_current_directory() const
Chris@16 315 { return includes.get_current_directory(); }
Chris@16 316
Chris@16 317 #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
Chris@16 318 protected:
Chris@16 319 friend class boost::wave::pp_iterator<context>;
Chris@16 320 friend class boost::wave::impl::pp_iterator_functor<context>;
Chris@16 321 #endif
Chris@16 322
Chris@16 323 // make sure the context has been initialized
Chris@16 324 void init_context()
Chris@16 325 {
Chris@16 326 if (!has_been_initialized) {
Chris@16 327 std::string fname(filename);
Chris@16 328 if (filename != "<Unknown>" && filename != "<stdin>") {
Chris@16 329 using namespace boost::filesystem;
Chris@16 330 path fpath(util::complete_path(path(filename)));
Chris@16 331 fname = fpath.string();
Chris@16 332 includes.set_current_directory(fname.c_str());
Chris@16 333 }
Chris@16 334 has_been_initialized = true; // execute once
Chris@16 335 }
Chris@16 336 }
Chris@16 337
Chris@16 338 template <typename IteratorT2>
Chris@16 339 bool is_defined_macro(IteratorT2 const &begin, IteratorT2 const &end) const
Chris@16 340 { return macros.is_defined(begin, end); }
Chris@16 341
Chris@16 342 // maintain include paths (helper functions)
Chris@16 343 void set_current_directory(char const *path_)
Chris@16 344 { includes.set_current_directory(path_); }
Chris@16 345
Chris@16 346 // conditional compilation contexts
Chris@16 347 bool get_if_block_status() const { return ifblocks.get_status(); }
Chris@16 348 bool get_if_block_some_part_status() const
Chris@16 349 { return ifblocks.get_some_part_status(); }
Chris@16 350 bool get_enclosing_if_block_status() const
Chris@16 351 { return ifblocks.get_enclosing_status(); }
Chris@16 352 void enter_if_block(bool new_status)
Chris@16 353 { ifblocks.enter_if_block(new_status); }
Chris@16 354 bool enter_elif_block(bool new_status)
Chris@16 355 { return ifblocks.enter_elif_block(new_status); }
Chris@16 356 bool enter_else_block() { return ifblocks.enter_else_block(); }
Chris@16 357 bool exit_if_block() { return ifblocks.exit_if_block(); }
Chris@16 358 typename boost::wave::util::if_block_stack::size_type get_if_block_depth() const
Chris@16 359 { return ifblocks.get_if_block_depth(); }
Chris@16 360
Chris@16 361 // stack of iteration contexts
Chris@16 362 iteration_ptr_type pop_iteration_context()
Chris@16 363 { iteration_ptr_type top = iter_ctxs.top(); iter_ctxs.pop(); return top; }
Chris@16 364 void push_iteration_context(position_type const &act_pos, iteration_ptr_type iter_ctx)
Chris@16 365 { iter_ctxs.push(*this, act_pos, iter_ctx); }
Chris@16 366
Chris@16 367 ///////////////////////////////////////////////////////////////////////////////
Chris@16 368 //
Chris@16 369 // expand_tokensequence():
Chris@16 370 // expands all macros contained in a given token sequence, handles '##'
Chris@16 371 // and '#' pp operators and re-scans the resulting sequence
Chris@16 372 // (essentially pre-processes the token sequence).
Chris@16 373 //
Chris@16 374 // The expand_undefined parameter is true during macro expansion inside
Chris@16 375 // a C++ expression given for a #if or #elif statement.
Chris@16 376 //
Chris@16 377 ///////////////////////////////////////////////////////////////////////////////
Chris@16 378 template <typename IteratorT2>
Chris@16 379 token_type expand_tokensequence(IteratorT2 &first_, IteratorT2 const &last_,
Chris@16 380 token_sequence_type &pending, token_sequence_type &expanded,
Chris@16 381 bool& seen_newline, bool expand_undefined = false)
Chris@16 382 {
Chris@16 383 return macros.expand_tokensequence(first_, last_, pending, expanded,
Chris@16 384 seen_newline, expand_undefined);
Chris@16 385 }
Chris@16 386
Chris@16 387 template <typename IteratorT2>
Chris@16 388 void expand_whole_tokensequence(IteratorT2 &first_, IteratorT2 const &last_,
Chris@16 389 token_sequence_type &expanded, bool expand_undefined = true)
Chris@16 390 {
Chris@16 391 macros.expand_whole_tokensequence(expanded, first_, last_,
Chris@16 392 expand_undefined);
Chris@16 393
Chris@16 394 // remove any contained placeholder
Chris@16 395 boost::wave::util::impl::remove_placeholders(expanded);
Chris@16 396 }
Chris@16 397
Chris@16 398 public:
Chris@16 399 #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
Chris@16 400 // support for #pragma once
Chris@16 401 // maintain the real name of the current preprocessed file
Chris@16 402 void set_current_filename(char const *real_name)
Chris@16 403 { current_filename = real_name; }
Chris@16 404 std::string const &get_current_filename() const
Chris@16 405 { return current_filename; }
Chris@16 406
Chris@16 407 // maintain the list of known headers containing #pragma once
Chris@16 408 bool has_pragma_once(std::string const &filename_)
Chris@16 409 { return includes.has_pragma_once(filename_); }
Chris@16 410 bool add_pragma_once_header(std::string const &filename_,
Chris@16 411 std::string const& guard_name)
Chris@16 412 {
Chris@16 413 get_hooks().detected_include_guard(derived(), filename_, guard_name);
Chris@16 414 return includes.add_pragma_once_header(filename_, guard_name);
Chris@16 415 }
Chris@16 416 bool add_pragma_once_header(token_type const &pragma_,
Chris@16 417 std::string const &filename_)
Chris@16 418 {
Chris@16 419 get_hooks().detected_pragma_once(derived(), pragma_, filename_);
Chris@16 420 return includes.add_pragma_once_header(filename_,
Chris@16 421 "__BOOST_WAVE_PRAGMA_ONCE__");
Chris@16 422 }
Chris@16 423 #endif
Chris@16 424
Chris@16 425 void set_current_relative_filename(char const *real_name)
Chris@16 426 { current_relative_filename = real_name; }
Chris@16 427 std::string const &get_current_relative_filename() const
Chris@16 428 { return current_relative_filename; }
Chris@16 429
Chris@16 430 bool find_include_file (std::string &s, std::string &d, bool is_system,
Chris@16 431 char const *current_file) const
Chris@16 432 { return includes.find_include_file(s, d, is_system, current_file); }
Chris@16 433
Chris@16 434 #if BOOST_WAVE_SERIALIZATION != 0
Chris@16 435 public:
Chris@16 436 BOOST_STATIC_CONSTANT(unsigned int, version = 0x10);
Chris@16 437 BOOST_STATIC_CONSTANT(unsigned int, version_mask = 0x0f);
Chris@16 438
Chris@16 439 private:
Chris@16 440 friend class boost::serialization::access;
Chris@16 441 template<class Archive>
Chris@16 442 void save(Archive & ar, const unsigned int version) const
Chris@16 443 {
Chris@16 444 using namespace boost::serialization;
Chris@16 445
Chris@16 446 string_type cfg(BOOST_PP_STRINGIZE(BOOST_WAVE_CONFIG));
Chris@16 447 string_type kwd(BOOST_WAVE_PRAGMA_KEYWORD);
Chris@16 448 string_type strtype(BOOST_PP_STRINGIZE((BOOST_WAVE_STRINGTYPE)));
Chris@16 449 ar & make_nvp("config", cfg);
Chris@16 450 ar & make_nvp("pragma_keyword", kwd);
Chris@16 451 ar & make_nvp("string_type", strtype);
Chris@16 452
Chris@16 453 ar & make_nvp("language_options", language);
Chris@16 454 ar & make_nvp("macro_definitions", macros);
Chris@16 455 ar & make_nvp("include_settings", includes);
Chris@16 456 }
Chris@16 457 template<class Archive>
Chris@16 458 void load(Archive & ar, const unsigned int loaded_version)
Chris@16 459 {
Chris@16 460 using namespace boost::serialization;
Chris@16 461 if (version != (loaded_version & ~version_mask)) {
Chris@16 462 BOOST_WAVE_THROW_CTX((*this), preprocess_exception,
Chris@16 463 incompatible_config, "cpp_context state version",
Chris@16 464 get_main_pos());
Chris@16 465 return;
Chris@16 466 }
Chris@16 467
Chris@16 468 // check compatibility of the stored information
Chris@16 469 string_type config, pragma_keyword, string_type_str;
Chris@16 470
Chris@16 471 // BOOST_PP_STRINGIZE(BOOST_WAVE_CONFIG)
Chris@16 472 ar & make_nvp("config", config);
Chris@16 473 if (config != BOOST_PP_STRINGIZE(BOOST_WAVE_CONFIG)) {
Chris@16 474 BOOST_WAVE_THROW_CTX((*this), preprocess_exception,
Chris@16 475 incompatible_config, "BOOST_WAVE_CONFIG", get_main_pos());
Chris@16 476 return;
Chris@16 477 }
Chris@16 478
Chris@16 479 // BOOST_WAVE_PRAGMA_KEYWORD
Chris@16 480 ar & make_nvp("pragma_keyword", pragma_keyword);
Chris@16 481 if (pragma_keyword != BOOST_WAVE_PRAGMA_KEYWORD) {
Chris@16 482 BOOST_WAVE_THROW_CTX((*this), preprocess_exception,
Chris@16 483 incompatible_config, "BOOST_WAVE_PRAGMA_KEYWORD",
Chris@16 484 get_main_pos());
Chris@16 485 return;
Chris@16 486 }
Chris@16 487
Chris@16 488 // BOOST_PP_STRINGIZE((BOOST_WAVE_STRINGTYPE))
Chris@16 489 ar & make_nvp("string_type", string_type_str);
Chris@16 490 if (string_type_str != BOOST_PP_STRINGIZE((BOOST_WAVE_STRINGTYPE))) {
Chris@16 491 BOOST_WAVE_THROW_CTX((*this), preprocess_exception,
Chris@16 492 incompatible_config, "BOOST_WAVE_STRINGTYPE", get_main_pos());
Chris@16 493 return;
Chris@16 494 }
Chris@16 495
Chris@16 496 try {
Chris@16 497 // read in the useful bits
Chris@16 498 ar & make_nvp("language_options", language);
Chris@16 499 ar & make_nvp("macro_definitions", macros);
Chris@16 500 ar & make_nvp("include_settings", includes);
Chris@16 501 }
Chris@16 502 catch (boost::wave::preprocess_exception const& e) {
Chris@16 503 // catch version mismatch exceptions and call error handler
Chris@16 504 get_hooks().throw_exception(derived(), e);
Chris@16 505 }
Chris@16 506 }
Chris@16 507 BOOST_SERIALIZATION_SPLIT_MEMBER()
Chris@16 508 #endif
Chris@16 509
Chris@16 510 private:
Chris@16 511 // the main input stream
Chris@16 512 target_iterator_type first; // underlying input stream
Chris@16 513 target_iterator_type last;
Chris@16 514 std::string filename; // associated main filename
Chris@16 515 bool has_been_initialized; // set cwd once
Chris@16 516 #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
Chris@16 517 std::string current_filename; // real name of current preprocessed file
Chris@16 518 #endif
Chris@16 519 std::string current_relative_filename; // real relative name of current preprocessed file
Chris@16 520
Chris@16 521 boost::wave::util::if_block_stack ifblocks; // conditional compilation contexts
Chris@16 522 boost::wave::util::include_paths includes; // lists of include directories to search
Chris@16 523 iteration_context_stack_type iter_ctxs; // iteration contexts
Chris@16 524 macromap_type macros; // map of defined macros
Chris@16 525 boost::wave::language_support language; // supported language/extensions
Chris@16 526 hook_policy_type hooks; // hook policy instance
Chris@16 527 };
Chris@16 528
Chris@16 529 ///////////////////////////////////////////////////////////////////////////////
Chris@16 530 } // namespace wave
Chris@16 531 } // namespace boost
Chris@16 532
Chris@16 533 #if BOOST_WAVE_SERIALIZATION != 0
Chris@16 534 namespace boost { namespace serialization {
Chris@16 535
Chris@16 536 template<
Chris@16 537 typename Iterator, typename LexIterator,
Chris@16 538 typename InputPolicy, typename Hooks
Chris@16 539 >
Chris@16 540 struct tracking_level<boost::wave::context<Iterator, LexIterator, InputPolicy, Hooks> >
Chris@16 541 {
Chris@16 542 typedef mpl::integral_c_tag tag;
Chris@16 543 typedef mpl::int_<track_never> type;
Chris@16 544 BOOST_STATIC_CONSTANT(
Chris@16 545 int,
Chris@16 546 value = tracking_level::type::value
Chris@16 547 );
Chris@16 548 };
Chris@16 549
Chris@16 550 template<
Chris@16 551 typename Iterator, typename LexIterator,
Chris@16 552 typename InputPolicy, typename Hooks
Chris@16 553 >
Chris@16 554 struct version<boost::wave::context<Iterator, LexIterator, InputPolicy, Hooks> >
Chris@16 555 {
Chris@16 556 typedef boost::wave::context<Iterator, LexIterator, InputPolicy, Hooks>
Chris@16 557 target_type;
Chris@16 558 typedef mpl::int_<target_type::version> type;
Chris@16 559 typedef mpl::integral_c_tag tag;
Chris@16 560 BOOST_STATIC_CONSTANT(unsigned int, value = version::type::value);
Chris@16 561 };
Chris@16 562
Chris@16 563 }} // namespace boost::serialization
Chris@16 564 #endif
Chris@16 565
Chris@16 566 // the suffix header occurs after all of the code
Chris@16 567 #ifdef BOOST_HAS_ABI_HEADERS
Chris@16 568 #include BOOST_ABI_SUFFIX
Chris@16 569 #endif
Chris@16 570
Chris@16 571 #endif // !defined(CPP_CONTEXT_HPP_907485E2_6649_4A87_911B_7F7225F3E5B8_INCLUDED)