preprocessing_hooks.hpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. /*=============================================================================
  2. Boost.Wave: A Standard compliant C++ preprocessor library
  3. http://www.boost.org/
  4. Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
  5. Software License, Version 1.0. (See accompanying file
  6. LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. =============================================================================*/
  8. #if !defined(BOOST_DEFAULT_PREPROCESSING_HOOKS_HPP_INCLUDED)
  9. #define BOOST_DEFAULT_PREPROCESSING_HOOKS_HPP_INCLUDED
  10. #include <boost/wave/wave_config.hpp>
  11. #include <boost/wave/util/cpp_include_paths.hpp>
  12. #include <boost/wave/cpp_exceptions.hpp>
  13. #include <vector>
  14. // this must occur after all of the includes and before any code appears
  15. #ifdef BOOST_HAS_ABI_HEADERS
  16. #include BOOST_ABI_PREFIX
  17. #endif
  18. ///////////////////////////////////////////////////////////////////////////////
  19. namespace boost {
  20. namespace wave {
  21. namespace context_policies {
  22. ///////////////////////////////////////////////////////////////////////////////
  23. //
  24. // The default_preprocessing_hooks class is a placeholder for all
  25. // preprocessing hooks called from inside the preprocessing engine
  26. //
  27. ///////////////////////////////////////////////////////////////////////////////
  28. struct default_preprocessing_hooks
  29. {
  30. ///////////////////////////////////////////////////////////////////////////
  31. //
  32. // The function 'expanding_function_like_macro' is called, whenever a
  33. // function-like macro is to be expanded.
  34. //
  35. // The parameter 'macrodef' marks the position, where the macro to expand
  36. // is defined.
  37. //
  38. // The parameter 'formal_args' holds the formal arguments used during the
  39. // definition of the macro.
  40. //
  41. // The parameter 'definition' holds the macro definition for the macro to
  42. // trace.
  43. //
  44. // The parameter 'macro_call' marks the position, where this macro invoked.
  45. //
  46. // The parameter 'arguments' holds the macro arguments used during the
  47. // invocation of the macro
  48. //
  49. // The parameters 'seqstart' and 'seqend' point into the input token
  50. // stream allowing to access the whole token sequence comprising the macro
  51. // invocation (starting with the opening parenthesis and ending after the
  52. // closing one).
  53. //
  54. // The return value defines whether the corresponding macro will be
  55. // expanded (return false) or will be copied to the output (return true).
  56. // Note: the whole argument list is copied unchanged to the output as well
  57. // without any further processing.
  58. //
  59. ///////////////////////////////////////////////////////////////////////////
  60. template <typename ContextT, typename TokenT, typename ContainerT, typename IteratorT>
  61. bool
  62. expanding_function_like_macro(ContextT const& ctx,
  63. TokenT const& macrodef, std::vector<TokenT> const& formal_args,
  64. ContainerT const& definition,
  65. TokenT const& macrocall, std::vector<ContainerT> const& arguments,
  66. IteratorT const& seqstart, IteratorT const& seqend)
  67. { return false; } // default is to normally expand the macro
  68. ///////////////////////////////////////////////////////////////////////////
  69. //
  70. // The function 'expanding_object_like_macro' is called, whenever a
  71. // object-like macro is to be expanded .
  72. //
  73. // The parameter 'ctx' is a reference to the context object used for
  74. // instantiating the preprocessing iterators by the user.
  75. //
  76. // The parameter 'macro' marks the position, where the macro to expand
  77. // is defined.
  78. //
  79. // The definition 'definition' holds the macro definition for the macro to
  80. // trace.
  81. //
  82. // The parameter 'macrocall' marks the position, where this macro invoked.
  83. //
  84. // The return value defines whether the corresponding macro will be
  85. // expanded (return false) or will be copied to the output (return true).
  86. //
  87. ///////////////////////////////////////////////////////////////////////////
  88. template <typename ContextT, typename TokenT, typename ContainerT>
  89. bool
  90. expanding_object_like_macro(ContextT const& ctx, TokenT const& macro,
  91. ContainerT const& definition, TokenT const& macrocall)
  92. { return false; } // default is to normally expand the macro
  93. ///////////////////////////////////////////////////////////////////////////
  94. //
  95. // The function 'expanded_macro' is called, whenever the expansion of a
  96. // macro is finished but before the rescanning process starts.
  97. //
  98. // The parameter 'ctx' is a reference to the context object used for
  99. // instantiating the preprocessing iterators by the user.
  100. //
  101. // The parameter 'result' contains the token sequence generated as the
  102. // result of the macro expansion.
  103. //
  104. ///////////////////////////////////////////////////////////////////////////
  105. template <typename ContextT, typename ContainerT>
  106. void expanded_macro(ContextT const& ctx, ContainerT const& result)
  107. {}
  108. ///////////////////////////////////////////////////////////////////////////
  109. //
  110. // The function 'rescanned_macro' is called, whenever the rescanning of a
  111. // macro is finished.
  112. //
  113. // The parameter 'ctx' is a reference to the context object used for
  114. // instantiating the preprocessing iterators by the user.
  115. //
  116. // The parameter 'result' contains the token sequence generated as the
  117. // result of the rescanning.
  118. //
  119. ///////////////////////////////////////////////////////////////////////////
  120. template <typename ContextT, typename ContainerT>
  121. void rescanned_macro(ContextT const& ctx, ContainerT const& result)
  122. {}
  123. ///////////////////////////////////////////////////////////////////////////
  124. //
  125. // The function 'locate_include_file' is called, whenever a #include
  126. // directive was encountered. It is supposed to locate the given file and
  127. // should return the full file name of the located file. This file name
  128. // is expected to uniquely identify the referenced file.
  129. //
  130. // The parameter 'ctx' is a reference to the context object used for
  131. // instantiating the preprocessing iterators by the user.
  132. //
  133. // The parameter 'file_path' contains the (expanded) file name found after
  134. // the #include directive. This parameter holds the string as it is
  135. // specified in the #include directive, i.e. <file> or "file" will result
  136. // in a parameter value 'file'.
  137. //
  138. // The parameter 'is_system' is set to 'true' if this call happens as a
  139. // result of a #include '<file>' directive, it is 'false' otherwise, i.e.
  140. // for #include "file" directives.
  141. //
  142. // The parameter 'current_name' is only used if a #include_next directive
  143. // was encountered (and BOOST_WAVE_SUPPORT_INCLUDE_NEXT was defined to be
  144. // non-zero). In this case it points to unique full name of the current
  145. // include file (if any). Otherwise this parameter is set to NULL.
  146. //
  147. // The parameter 'dir_path' on return is expected to hold the directory
  148. // part of the located file.
  149. //
  150. // The parameter 'native_name' on return is expected to hold the unique
  151. // full file name of the located file.
  152. //
  153. // The return value defines whether the file was located successfully.
  154. //
  155. ///////////////////////////////////////////////////////////////////////////
  156. template <typename ContextT>
  157. bool
  158. locate_include_file(ContextT& ctx, std::string &file_path,
  159. bool is_system, char const *current_name, std::string &dir_path,
  160. std::string &native_name)
  161. {
  162. if (!ctx.find_include_file (file_path, dir_path, is_system, current_name))
  163. return false; // could not locate file
  164. namespace fs = boost::filesystem;
  165. fs::path native_path(wave::util::create_path(file_path));
  166. if (!fs::exists(native_path)) {
  167. BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, bad_include_file,
  168. file_path.c_str(), ctx.get_main_pos());
  169. return false;
  170. }
  171. // return the unique full file system path of the located file
  172. native_name = wave::util::native_file_string(native_path);
  173. return true; // include file has been located successfully
  174. }
  175. ///////////////////////////////////////////////////////////////////////////
  176. //
  177. // The function 'found_include_directive' is called, whenever a #include
  178. // directive was located.
  179. //
  180. // The parameter 'ctx' is a reference to the context object used for
  181. // instantiating the preprocessing iterators by the user.
  182. //
  183. // The parameter 'filename' contains the (expanded) file name found after
  184. // the #include directive. This has the format '<file>', '"file"' or
  185. // 'file'.
  186. // The formats '<file>' or '"file"' are used for #include directives found
  187. // in the preprocessed token stream, the format 'file' is used for files
  188. // specified through the --force_include command line argument.
  189. //
  190. // The parameter 'include_next' is set to true if the found directive was
  191. // a #include_next directive and the BOOST_WAVE_SUPPORT_INCLUDE_NEXT
  192. // preprocessing constant was defined to something != 0.
  193. //
  194. // The return value defines whether the found file will be included
  195. // (return false) or will be skipped (return true).
  196. //
  197. ///////////////////////////////////////////////////////////////////////////
  198. template <typename ContextT>
  199. bool
  200. found_include_directive(ContextT const& ctx, std::string const& filename,
  201. bool include_next)
  202. {
  203. return false; // ok to include this file
  204. }
  205. ///////////////////////////////////////////////////////////////////////////
  206. //
  207. // The function 'opened_include_file' is called, whenever a file referred
  208. // by an #include directive was successfully located and opened.
  209. //
  210. // The parameter 'ctx' is a reference to the context object used for
  211. // instantiating the preprocessing iterators by the user.
  212. //
  213. // The parameter 'filename' contains the file system path of the
  214. // opened file (this is relative to the directory of the currently
  215. // processed file or a absolute path depending on the paths given as the
  216. // include search paths).
  217. //
  218. // The include_depth parameter contains the current include file depth.
  219. //
  220. // The is_system_include parameter denotes whether the given file was
  221. // found as a result of a #include <...> directive.
  222. //
  223. ///////////////////////////////////////////////////////////////////////////
  224. template <typename ContextT>
  225. void
  226. opened_include_file(ContextT const& ctx, std::string const& relname,
  227. std::string const& absname, bool is_system_include)
  228. {}
  229. ///////////////////////////////////////////////////////////////////////////
  230. //
  231. // The function 'returning_from_include_file' is called, whenever an
  232. // included file is about to be closed after it's processing is complete.
  233. //
  234. // The parameter 'ctx' is a reference to the context object used for
  235. // instantiating the preprocessing iterators by the user.
  236. //
  237. ///////////////////////////////////////////////////////////////////////////
  238. template <typename ContextT>
  239. void
  240. returning_from_include_file(ContextT const& ctx)
  241. {}
  242. #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
  243. ///////////////////////////////////////////////////////////////////////////
  244. //
  245. // The function 'detected_include_guard' is called whenever either a
  246. // include file is about to be added to the list of #pragma once headers.
  247. // That means this header file will not be opened and parsed again even
  248. // if it is specified in a later #include directive.
  249. // This function is called as the result of a detected include guard
  250. // scheme.
  251. //
  252. // The implemented heuristics for include guards detects two forms of
  253. // include guards:
  254. //
  255. // #ifndef INCLUDE_GUARD_MACRO
  256. // #define INCLUDE_GUARD_MACRO
  257. // ...
  258. // #endif
  259. //
  260. // or
  261. //
  262. // if !defined(INCLUDE_GUARD_MACRO)
  263. // #define INCLUDE_GUARD_MACRO
  264. // ...
  265. // #endif
  266. //
  267. // note, that the parenthesis are optional (i.e. !defined INCLUDE_GUARD_MACRO
  268. // will work as well). The code allows for any whitespace, newline and single
  269. // '#' tokens before the #if/#ifndef and after the final #endif.
  270. //
  271. // The parameter 'ctx' is a reference to the context object used for
  272. // instantiating the preprocessing iterators by the user.
  273. //
  274. // The parameter 'filename' contains the file system path of the
  275. // opened file (this is relative to the directory of the currently
  276. // processed file or a absolute path depending on the paths given as the
  277. // include search paths).
  278. //
  279. // The parameter contains the name of the detected include guard.
  280. //
  281. ///////////////////////////////////////////////////////////////////////////
  282. template <typename ContextT>
  283. void
  284. detected_include_guard(ContextT const& ctx, std::string const& filename,
  285. std::string const& include_guard)
  286. {}
  287. ///////////////////////////////////////////////////////////////////////////
  288. //
  289. // The function 'detected_pragma_once' is called whenever either a
  290. // include file is about to be added to the list of #pragma once headers.
  291. // That means this header file will not be opened and parsed again even
  292. // if it is specified in a later #include directive.
  293. // This function is called as the result of a detected directive
  294. // #pragma once.
  295. //
  296. // The parameter 'ctx' is a reference to the context object used for
  297. // instantiating the preprocessing iterators by the user.
  298. //
  299. // The parameter pragma_token refers to the token "#pragma" triggering
  300. // this preprocessing hook.
  301. //
  302. // The parameter 'filename' contains the file system path of the
  303. // opened file (this is relative to the directory of the currently
  304. // processed file or a absolute path depending on the paths given as the
  305. // include search paths).
  306. //
  307. ///////////////////////////////////////////////////////////////////////////
  308. template <typename ContextT, typename TokenT>
  309. void
  310. detected_pragma_once(ContextT const& ctx, TokenT const& pragma_token,
  311. std::string const& filename)
  312. {}
  313. #endif
  314. ///////////////////////////////////////////////////////////////////////////
  315. //
  316. // The function 'interpret_pragma' is called, whenever a '#pragma command'
  317. // directive is found which isn't known to the core Wave library, where
  318. // 'command' is the value defined as the BOOST_WAVE_PRAGMA_KEYWORD constant
  319. // which defaults to "wave".
  320. //
  321. // The parameter 'ctx' is a reference to the context object used for
  322. // instantiating the preprocessing iterators by the user.
  323. //
  324. // The parameter 'pending' may be used to push tokens back into the input
  325. // stream, which are to be used as the replacement text for the whole
  326. // #pragma directive.
  327. //
  328. // The parameter 'option' contains the name of the interpreted pragma.
  329. //
  330. // The parameter 'values' holds the values of the parameter provided to
  331. // the pragma operator.
  332. //
  333. // The parameter 'act_token' contains the actual #pragma token, which may
  334. // be used for error output.
  335. //
  336. // If the return value is 'false', the whole #pragma directive is
  337. // interpreted as unknown and a corresponding error message is issued. A
  338. // return value of 'true' signs a successful interpretation of the given
  339. // #pragma.
  340. //
  341. ///////////////////////////////////////////////////////////////////////////
  342. template <typename ContextT, typename ContainerT>
  343. bool
  344. interpret_pragma(ContextT const& ctx, ContainerT &pending,
  345. typename ContextT::token_type const& option, ContainerT const& values,
  346. typename ContextT::token_type const& act_token)
  347. {
  348. return false;
  349. }
  350. ///////////////////////////////////////////////////////////////////////////
  351. //
  352. // The function 'emit_line_directive' is called whenever a #line directive
  353. // has to be emitted into the generated output.
  354. //
  355. // The parameter 'ctx' is a reference to the context object used for
  356. // instantiating the preprocessing iterators by the user.
  357. //
  358. // The parameter 'pending' may be used to push tokens back into the input
  359. // stream, which are to be used instead of the default output generated
  360. // for the #line directive.
  361. //
  362. // The parameter 'act_token' contains the actual #pragma token, which may
  363. // be used for error output. The line number stored in this token can be
  364. // used as the line number emitted as part of the #line directive.
  365. //
  366. // If the return value is 'false', a default #line directive is emitted
  367. // by the library. A return value of 'true' will inhibit any further
  368. // actions, the tokens contained in 'pending' will be copied verbatim
  369. // to the output.
  370. //
  371. ///////////////////////////////////////////////////////////////////////////
  372. template <typename ContextT, typename ContainerT>
  373. bool
  374. emit_line_directive(ContextT const& ctx, ContainerT &pending,
  375. typename ContextT::token_type const& act_token)
  376. {
  377. return false;
  378. }
  379. ///////////////////////////////////////////////////////////////////////////
  380. //
  381. // The function 'defined_macro' is called, whenever a macro was defined
  382. // successfully.
  383. //
  384. // The parameter 'ctx' is a reference to the context object used for
  385. // instantiating the preprocessing iterators by the user.
  386. //
  387. // The parameter 'name' is a reference to the token holding the macro name.
  388. //
  389. // The parameter 'is_functionlike' is set to true, whenever the newly
  390. // defined macro is defined as a function like macro.
  391. //
  392. // The parameter 'parameters' holds the parameter tokens for the macro
  393. // definition. If the macro has no parameters or if it is a object like
  394. // macro, then this container is empty.
  395. //
  396. // The parameter 'definition' contains the token sequence given as the
  397. // replacement sequence (definition part) of the newly defined macro.
  398. //
  399. // The parameter 'is_predefined' is set to true for all macros predefined
  400. // during the initialization phase of the library.
  401. //
  402. ///////////////////////////////////////////////////////////////////////////
  403. template <
  404. typename ContextT, typename TokenT, typename ParametersT,
  405. typename DefinitionT
  406. >
  407. void
  408. defined_macro(ContextT const& ctx, TokenT const& macro_name,
  409. bool is_functionlike, ParametersT const& parameters,
  410. DefinitionT const& definition, bool is_predefined)
  411. {}
  412. ///////////////////////////////////////////////////////////////////////////
  413. //
  414. // The function 'undefined_macro' is called, whenever a macro definition
  415. // was removed successfully.
  416. //
  417. // The parameter 'ctx' is a reference to the context object used for
  418. // instantiating the preprocessing iterators by the user.
  419. //
  420. // The parameter 'name' holds the name of the macro, which definition was
  421. // removed.
  422. //
  423. ///////////////////////////////////////////////////////////////////////////
  424. template <typename ContextT, typename TokenT>
  425. void
  426. undefined_macro(ContextT const& ctx, TokenT const& macro_name)
  427. {}
  428. ///////////////////////////////////////////////////////////////////////////
  429. //
  430. // The function 'found_directive' is called, whenever a preprocessor
  431. // directive was encountered, but before the corresponding action is
  432. // executed.
  433. //
  434. // The parameter 'ctx' is a reference to the context object used for
  435. // instantiating the preprocessing iterators by the user.
  436. //
  437. // The parameter 'directive' is a reference to the token holding the
  438. // preprocessing directive.
  439. //
  440. // The return value defines whether the given expression has to be
  441. // to be executed in a normal way (return 'false'), or if it has to be
  442. // skipped altogether (return 'true'), which means it gets replaced in the
  443. // output by a single newline.
  444. //
  445. ///////////////////////////////////////////////////////////////////////////
  446. template <typename ContextT, typename TokenT>
  447. bool
  448. found_directive(ContextT const& ctx, TokenT const& directive)
  449. { return false; } // by default we never skip any directives
  450. ///////////////////////////////////////////////////////////////////////////
  451. //
  452. // The function 'found_unknown_directive' is called, whenever an unknown
  453. // preprocessor directive was encountered.
  454. //
  455. // The parameter 'ctx' is a reference to the context object used for
  456. // instantiating the preprocessing iterators by the user.
  457. //
  458. // The parameter 'line' holds the tokens of the entire source line
  459. // containing the unknown directive.
  460. //
  461. // The parameter 'pending' may be used to push tokens back into the input
  462. // stream, which are to be used as the replacement text for the whole
  463. // line containing the unknown directive.
  464. //
  465. // The return value defines whether the given expression has been
  466. // properly interpreted by the hook function or not. If this function
  467. // returns 'false', the library will raise an 'ill_formed_directive'
  468. // preprocess_exception. Otherwise the tokens pushed back into 'pending'
  469. // are passed on to the user program.
  470. //
  471. ///////////////////////////////////////////////////////////////////////////
  472. template <typename ContextT, typename ContainerT>
  473. bool
  474. found_unknown_directive(ContextT const& ctx, ContainerT const& line,
  475. ContainerT& pending)
  476. { return false; } // by default we never interpret unknown directives
  477. ///////////////////////////////////////////////////////////////////////////
  478. //
  479. // The function 'evaluated_conditional_expression' is called, whenever a
  480. // conditional preprocessing expression was evaluated (the expression
  481. // given to a #if, #elif, #ifdef or #ifndef directive)
  482. //
  483. // The parameter 'ctx' is a reference to the context object used for
  484. // instantiating the preprocessing iterators by the user.
  485. //
  486. // The parameter 'directive' is a reference to the token holding the
  487. // corresponding preprocessing directive.
  488. //
  489. // The parameter 'expression' holds the non-expanded token sequence
  490. // comprising the evaluated expression.
  491. //
  492. // The parameter expression_value contains the result of the evaluation of
  493. // the expression in the current preprocessing context.
  494. //
  495. // The return value defines whether the given expression has to be
  496. // evaluated again, allowing to decide which of the conditional branches
  497. // should be expanded. You need to return 'true' from this hook function
  498. // to force the expression to be re-evaluated.
  499. //
  500. ///////////////////////////////////////////////////////////////////////////
  501. template <typename ContextT, typename TokenT, typename ContainerT>
  502. bool
  503. evaluated_conditional_expression(ContextT const& ctx,
  504. TokenT const& directive, ContainerT const& expression,
  505. bool expression_value)
  506. { return false; } // ok to continue, do not re-evaluate expression
  507. ///////////////////////////////////////////////////////////////////////////
  508. //
  509. // The function 'skipped_token' is called, whenever a token is about to be
  510. // skipped due to a false preprocessor condition (code fragments to be
  511. // skipped inside the not evaluated conditional #if/#else/#endif branches).
  512. //
  513. // The parameter 'ctx' is a reference to the context object used for
  514. // instantiating the preprocessing iterators by the user.
  515. //
  516. // The parameter 'token' refers to the token to be skipped.
  517. //
  518. ///////////////////////////////////////////////////////////////////////////
  519. template <typename ContextT, typename TokenT>
  520. void
  521. skipped_token(ContextT const& ctx, TokenT const& token)
  522. {}
  523. ///////////////////////////////////////////////////////////////////////////
  524. //
  525. // The function 'generated_token' will be called by the library whenever a
  526. // token is about to be returned from the library.
  527. //
  528. // The parameter 'ctx' is a reference to the context object used for
  529. // instantiating the preprocessing iterators by the user.
  530. //
  531. // The parameter 't' is the token about to be returned from the library.
  532. // This function may alter the token, but in this case it must be
  533. // implemented with a corresponding signature:
  534. //
  535. // TokenT const&
  536. // generated_token(ContextT const& ctx, TokenT& t);
  537. //
  538. // which makes it possible to modify the token in place.
  539. //
  540. // The default behavior is to return the token passed as the parameter
  541. // without modification.
  542. //
  543. ///////////////////////////////////////////////////////////////////////////
  544. template <typename ContextT, typename TokenT>
  545. TokenT const&
  546. generated_token(ContextT const& ctx, TokenT const& t)
  547. { return t; }
  548. ///////////////////////////////////////////////////////////////////////////
  549. //
  550. // The function 'may_skip_whitespace' will be called by the
  551. // library, whenever it must be tested whether a specific token refers to
  552. // whitespace and this whitespace has to be skipped.
  553. //
  554. // The parameter 'ctx' is a reference to the context object used for
  555. // instantiating the preprocessing iterators by the user.
  556. //
  557. // The 'token' parameter holds a reference to the current token. The policy
  558. // is free to change this token if needed.
  559. //
  560. // The 'skipped_newline' parameter holds a reference to a boolean value
  561. // which should be set to true by the policy function whenever a newline
  562. // is going to be skipped.
  563. //
  564. // If the return value is true, the given token is skipped and the
  565. // preprocessing continues to the next token. If the return value is
  566. // false, the given token is returned to the calling application.
  567. //
  568. // ATTENTION!
  569. // Caution has to be used, because by returning true the policy function
  570. // is able to force skipping even significant tokens, not only whitespace.
  571. //
  572. ///////////////////////////////////////////////////////////////////////////
  573. template <typename ContextT, typename TokenT>
  574. bool
  575. may_skip_whitespace(ContextT const& ctx, TokenT& token, bool& skipped_newline)
  576. { return false; }
  577. #if BOOST_WAVE_SUPPORT_WARNING_DIRECTIVE != 0
  578. ///////////////////////////////////////////////////////////////////////////
  579. //
  580. // The function 'found_warning_directive' will be called by the library
  581. // whenever a #warning directive is found.
  582. //
  583. // The parameter 'ctx' is a reference to the context object used for
  584. // instantiating the preprocessing iterators by the user.
  585. //
  586. // The parameter 'message' references the argument token sequence of the
  587. // encountered #warning directive.
  588. //
  589. // If the return value is false, the library throws a preprocessor
  590. // exception of the type 'warning_directive', if the return value is true
  591. // the execution continues as if no #warning directive has been found.
  592. //
  593. ///////////////////////////////////////////////////////////////////////////
  594. template <typename ContextT, typename ContainerT>
  595. bool
  596. found_warning_directive(ContextT const& ctx, ContainerT const& message)
  597. { return false; }
  598. #endif
  599. ///////////////////////////////////////////////////////////////////////////
  600. //
  601. // The function 'found_error_directive' will be called by the library
  602. // whenever a #error directive is found.
  603. //
  604. // The parameter 'ctx' is a reference to the context object used for
  605. // instantiating the preprocessing iterators by the user.
  606. //
  607. // The parameter 'message' references the argument token sequence of the
  608. // encountered #error directive.
  609. //
  610. // If the return value is false, the library throws a preprocessor
  611. // exception of the type 'error_directive', if the return value is true
  612. // the execution continues as if no #error directive has been found.
  613. //
  614. ///////////////////////////////////////////////////////////////////////////
  615. template <typename ContextT, typename ContainerT>
  616. bool
  617. found_error_directive(ContextT const& ctx, ContainerT const& message)
  618. { return false; }
  619. ///////////////////////////////////////////////////////////////////////////
  620. //
  621. // The function 'found_line_directive' will be called by the library
  622. // whenever a #line directive is found.
  623. //
  624. // The parameter 'ctx' is a reference to the context object used for
  625. // instantiating the preprocessing iterators by the user.
  626. //
  627. // The parameter 'arguments' references the argument token sequence of the
  628. // encountered #line directive.
  629. //
  630. // The parameter 'line' contains the recognized line number from the #line
  631. // directive.
  632. //
  633. // The parameter 'filename' references the recognized file name from the
  634. // #line directive (if there was one given).
  635. //
  636. ///////////////////////////////////////////////////////////////////////////
  637. template <typename ContextT, typename ContainerT>
  638. void
  639. found_line_directive(ContextT const& ctx, ContainerT const& arguments,
  640. unsigned int line, std::string const& filename)
  641. {}
  642. ///////////////////////////////////////////////////////////////////////////
  643. //
  644. // The function 'throw_exception' will be called by the library whenever a
  645. // preprocessing exception occurs.
  646. //
  647. // The parameter 'ctx' is a reference to the context object used for
  648. // instantiating the preprocessing iterators by the user.
  649. //
  650. // The parameter 'e' is the exception object containing detailed error
  651. // information.
  652. //
  653. // The default behavior is to call the function boost::throw_exception.
  654. //
  655. ///////////////////////////////////////////////////////////////////////////
  656. template <typename ContextT, typename ExceptionT>
  657. void
  658. throw_exception(ContextT const& ctx, ExceptionT const& e)
  659. {
  660. boost::throw_exception(e);
  661. }
  662. };
  663. ///////////////////////////////////////////////////////////////////////////////
  664. } // namespace context_policies
  665. } // namespace wave
  666. } // namespace boost
  667. // the suffix header occurs after all of the code
  668. #ifdef BOOST_HAS_ABI_HEADERS
  669. #include BOOST_ABI_SUFFIX
  670. #endif
  671. #endif // !defined(BOOST_DEFAULT_PREPROCESSING_HOOKS_HPP_INCLUDED)