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