preprocessing_hooks.hpp 33 KB

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