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>
expanding_function_like_macroboost::wave::context_policies::default_preprocessing_hooks72     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>
expanding_object_like_macroboost::wave::context_policies::default_preprocessing_hooks112     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
expanding_object_like_macroboost::wave::context_policies::default_preprocessing_hooks119     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>
expanded_macroboost::wave::context_policies::default_preprocessing_hooks139     void expanded_macro(ContainerT const& result)
140     {}
141 #else
142     // new signature
143     template <typename ContextT, typename ContainerT>
expanded_macroboost::wave::context_policies::default_preprocessing_hooks144     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>
rescanned_macroboost::wave::context_policies::default_preprocessing_hooks163     void rescanned_macro(ContainerT const& result)
164     {}
165 #else
166     // new signature
167     template <typename ContextT, typename ContainerT>
rescanned_macroboost::wave::context_policies::default_preprocessing_hooks168     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
locate_include_fileboost::wave::context_policies::default_preprocessing_hooks207     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         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         fs::path native_path(wave::util::create_path(file_path));
217         if (!fs::exists(native_path)) {
218             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         native_name = wave::util::native_file_string(native_path);
225 
226         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
found_include_directiveboost::wave::context_policies::default_preprocessing_hooks255     found_include_directive(std::string const& filename, bool include_next)
256     {}
257 #else
258     // new signature
259     template <typename ContextT>
260     bool
found_include_directiveboost::wave::context_policies::default_preprocessing_hooks261     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
opened_include_fileboost::wave::context_policies::default_preprocessing_hooks290     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
opened_include_fileboost::wave::context_policies::default_preprocessing_hooks297     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
returning_from_include_fileboost::wave::context_policies::default_preprocessing_hooks314     returning_from_include_file()
315     {}
316 #else
317     // new signature
318     template <typename ContextT>
319     void
returning_from_include_fileboost::wave::context_policies::default_preprocessing_hooks320     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
detected_include_guardboost::wave::context_policies::default_preprocessing_hooks366     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
detected_pragma_onceboost::wave::context_policies::default_preprocessing_hooks393     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
interpret_pragmaboost::wave::context_policies::default_preprocessing_hooks428     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
emit_line_directiveboost::wave::context_policies::default_preprocessing_hooks459     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
defined_macroboost::wave::context_policies::default_preprocessing_hooks493     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
defined_macroboost::wave::context_policies::default_preprocessing_hooks504     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
undefined_macroboost::wave::context_policies::default_preprocessing_hooks526     undefined_macro(TokenT const& macro_name)
527     {}
528 #else
529     // new signature
530     template <typename ContextT, typename TokenT>
531     void
undefined_macroboost::wave::context_policies::default_preprocessing_hooks532     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
found_directiveboost::wave::context_policies::default_preprocessing_hooks558     found_directive(TokenT const& directive)
559     {}
560 #else
561     // new signature
562     template <typename ContextT, typename TokenT>
563     bool
found_directiveboost::wave::context_policies::default_preprocessing_hooks564     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
found_unknown_directiveboost::wave::context_policies::default_preprocessing_hooks592     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
evaluated_conditional_expressionboost::wave::context_policies::default_preprocessing_hooks624     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
evaluated_conditional_expressionboost::wave::context_policies::default_preprocessing_hooks631     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
skipped_tokenboost::wave::context_policies::default_preprocessing_hooks653     skipped_token(TokenT const& token)
654     {}
655 #else
656     // new signature
657     template <typename ContextT, typename TokenT>
658     void
skipped_tokenboost::wave::context_policies::default_preprocessing_hooks659     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&
generated_tokenboost::wave::context_policies::default_preprocessing_hooks686     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
may_skip_whitespaceboost::wave::context_policies::default_preprocessing_hooks716     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
found_warning_directiveboost::wave::context_policies::default_preprocessing_hooks738     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
found_error_directiveboost::wave::context_policies::default_preprocessing_hooks760     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
found_line_directiveboost::wave::context_policies::default_preprocessing_hooks783     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
throw_exceptionboost::wave::context_policies::default_preprocessing_hooks803     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)
820