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