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