上下文策略

介绍
头文件 'wave/preprocessing_hooks.hpp' 概要
成员函数

引言

上下文策略用于提供回调钩子,当以下情况发生时,它们会从库内部调用到用户代码中:

此策略类型用作 boost::wave::context<> 对象的模板参数,其中默认策略仅提供空钩子函数。

头文件 wave/preprocessing_hooks.hpp 概要

namespace boost {
namespace wave {
namespace context_policies {

struct default_preprocessing_hooks {

// general hook functions template <typename ContextT, typename TokenT>
bool found_directive(ContextT const &ctx,
TokenT const &directive);
template <typename ContextT, typename ContainerT> bool found_unknown_directive(ContextT const& ctx, ContainerT const& line, ContainerT& pending); template <typename ContextT, typename ExceptionT>
void throw_exception(ContextT const &ctx,
ExceptionT const& e);

// test, whether a given token may be skipped
template <typename ContextT>
bool may_skip_whitespace (ContextT const& ctx,
TokenT &token, bool &skipped_newline);
// Conditional compilation template <
typename ContextT, typename TokenT,
typename ContainerT
>
bool evaluated_conditional_expression(
ContextT const &ctx, TokenT const& directive,
ContainerT const& expression, bool expression_value);
template <typename ContextT, typename TokenT>
void skipped_token(ContextT const &ctx,
TokenT const& token);

template <typename ContextT, typename TokenT>
TokenT const& generated_token(ContextT const &ctx,
TokenT const& token);


// macro expansion tracing template < typename ContextT, typename TokenT, typename ContainerT,
typename IteratorT
>
bool expanding_function_like_macro(
ContextT const &ctx, TokenT const &macrodef,
std::vector<TokenT> const &formal_args,
ContainerT const &definition, TokenT const &macrocall,
std::vector<ContainerT> const &arguments,
IteratorT const &seqstart, Iterator const &seqend);

template <typename ContextT, typename TokenT, typename ContainerT>
bool expanding_object_like_macro(
ContextT const &ctx, TokenT const &macro,
ContainerT const &definition, TokenT const &macrocall);

template <typename ContextT, typename ContainerT>
void expanded_macro(ContextT const &ctx,
ContainerT const &result);

template <typename ContextT, typename ContainerT>
void rescanned_macro(ContextT const &ctx,
ContainerT const &result);

// include file tracing functions template <typename ContextT>
bool found_include_directive(ContextT const &ctx,
std::string const &filename, bool include_next);
template <typename ContextT> bool locate_include_file(ContextT& ctx, std::string &file_path, bool is_system, char const *current_name, std::string &dir_path, std::string &native_name);
template <typename ContextT>
void opened_include_file(ContextT const &ctx,
std::string const &relname, std::string const& absname,
bool is_system_include);
template <typename ContextT>
void returning_from_include_file(ContextT const &ctx);
template <typename ContextT>
void detected_include_guard(ContextT const &ctx, std::string const& filename, std::string const& include_guard);
template <typename ContextT, typename TokenT>
void detected_pragma_once(ContextT const &ctx, TokenT const& pragma_token, std::string const& filename);

// interpretation of #pragmas of the form // 'wave option[(value)]' template <typename ContextT, typename ContainerT>
bool interpret_pragma(ContextT const &ctx, ContainerT &pending,
typename ContextT::token_type const &option,
ContainerT const &values,
typename ContextT::token_type const &pragma_token);

// macro definition hooks template <
typename ContextT, typename TokenT, typename ParametersT, typename DefinitionT
>
void defined_macro(ContextT const &ctx, TokenT const &name, bool is_functionlike, ParametersT const &parameters,
DefinitionT const &definition, bool is_predefined);

template <typename ContextT, typename TokenT>
void undefined_macro(ContextT const &ctx,
TokenT const &name);

// #error and #warning directive hooks template <typename ContextT, typename ContainerT>
bool found_warning_directive(ContextT const &ctx,
ContainerT const &message);

template <typename ContextT, typename ContainerT>
bool found_error_directive(ContextT const &ctx,
ContainerT const &message);

// #line directive hooks template <typename ContextT, typename ContainerT>
void found_line_directive(ContextT const &ctx,
ContainerT const &arguments, unsigned int line,
std::string const& filename);
template <typename ContextT, typename ContainerT> bool emit_line_directive(ContextT const& ctx, ContainerT &pending, typename ContextT::token_type const& act_token); };

}}} // namespace boost::wave::context_policies

成员函数

通用钩子函数

found_directive

    template <typename ContextT, typename TokenT>
bool found_directive(ContextT const& ctx, TokenT const &directive);

函数found_directive当预处理器检测到以下任一预处理器指令(#define, #undef, #if, #idef, #ifndef, #elif, #endif, #error, #include, #pragma#warning)时调用。

ctx参数提供对context_type的引用,该参数在用户实例化预处理迭代器时使用。

参数指令指向包含已检测到预处理器指令的 token。

如果返回值是true,则该指令将被完全跳过,即不进行预处理。整个指令被替换为单个换行符。如果返回值是false,则该指令按正常方式处理。

found_unknown_directive

    template <typename ContextT, typename ContainerT>
    bool found_unknown_directive(ContextT const& ctx,
        ContainerT const& line, ContainerT& pending);

函数  found_unknown_directive在遇到未知预处理器指令时调用。

参数  ctx是用户实例化预处理迭代器时使用的上下文对象的引用。

参数  包含包含未知指令的整个源行的 token。

参数  pending可用于将 token 推回输入流,这些 token 将用作包含未知指令的整行的替换文本。

返回值定义了钩子函数是否已正确解释给定表达式。如果此函数返回  false,库将引发一个  ill_formed_directive异常。否则,推回  pending的 token 将传递给用户程序。

throw_exception

    template <typename ContextT, typename ExceptionT>
void throw_exception(ContextT const &ctx,
ExceptionT const& e);

当发生预处理器异常时调用函数 throw_exception

ctx参数提供对context_type用户在实例化预处理迭代器时使用。 

参数 e是包含详细错误信息的异常对象。

may_skip_whitespace

    template <typename ContextT, typename TokenT>
bool may_skip_whitespace(ContextT const& ctx, TokenT &token,
bool& skipped_newline);

函数may_skip_whitespace当 token 即将返回给调用应用程序时,库会调用此函数。

ctx参数提供对context_type用户在实例化预处理迭代器时使用。请注意,此参数已添加用于 Wave V1.2.4 版本。

标记参数持有当前 token 的引用。策略可以根据需要更改此 token。

skipped_newline参数持有布尔值的引用,当要跳过换行符时,策略函数应将其设置为 true。

如果返回值是true,则跳过给定的 token,预处理继续到下一个 token。如果返回值是false,则将给定的 token 返回给调用应用程序。需要谨慎使用,因为通过返回 true,策略函数可以强制跳过非空白的重要 token。

条件编译钩子函数

evaluated_conditional_expression

   template <typename ContextT, typename TokenT, typename ContainerT>
    bool evaluated_conditional_expression(ContextT const& ctx, 
TokenT const& directive, ContainerT const& expression,
bool
expression_value);

函数evaluated_conditional_expression当预处理器遇到 #if, #elif, #ifdef#ifndef 指令时调用。此钩子接收未展开的条件表达式(正如在分析的源文件中给出的那样)以及在当前预处理上下文中评估该表达式的结果。

ctx参数提供对context_type的引用,该参数在用户实例化预处理迭代器时使用。

标记参数持有已评估的指令 token 的引用。 

参数表达式包含由已评估表达式组成的未展开 token 序列。

参数expression_value包含在当前预处理上下文中对表达式的评估结果。

返回值定义了是否需要重新评估给定表达式,从而可以决定展开哪个条件分支。您需要从此钩子函数返回“true”以强制重新评估表达式。

skipped_token

    template <typename ContextT, typename TokenT>
void skipped_token(ContextT const& ctx, TokenT const& token);

函数skipped_token当由于错误的预处理器条件而即将跳过 token 时(未评估的条件 #if/#else/#endif 分支内的要跳过的代码片段)调用。

ctx参数提供对context_type的引用,该参数在用户实例化预处理迭代器时使用。

参数标记指向要跳过的 token。

generated_token

    template <typename ContextT, typename TokenT>
TokenT const& generated_token(ContextT const& ctx, TokenT const& token);

函数generated_token当 token 即将从库返回时调用。

ctx参数提供对context_type的引用,该参数在用户实例化预处理迭代器时使用。

参数标记指向即将从库返回的 token。此函数可以修改 token,但在此情况下,它必须以非 const 引用实现 token 参数,从而允许就地修改 token。

默认行为是将传入的 token 引用不变地返回给调用者。

宏展开跟踪函数

expanding_function_like_macro

   template <typename ContextT, typename TokenT, typename ContainerT>
bool expanding_function_like_macro(
ContextT const& ctx, TokenT const &macrodef,
std::vector<TokenT> const &formal_args,
ContainerT const &definition, TokenT const &macrocall,
std::vector<ContainerT> const &arguments,
IteratorT const &seqstart, Iterator const &seqend);

函数expanding_function_like_macro当要展开函数式宏时调用,即在实际展开开始之前

ctx参数提供对context_type的引用,该参数在用户实例化预处理迭代器时使用。

macroname参数标记宏定义的位置。它包含标识在相应宏定义中使用宏名称的 token。

formal_args参数保存宏定义期间使用的形式参数。

定义参数保存要跟踪的宏的宏定义。这是一个标准的 STL 容器,其中包含在宏定义期间标识为宏替换列表的 token 序列。

macrocall参数标记调用此宏的位置。它包含在预处理输入流中标识宏调用的 token。

参数参数保存宏调用期间使用的宏参数。这是一个标准 STL 容器的向量,其中包含在宏调用位置标识为在宏展开期间使用的参数的 token 序列。

参数seqstartandseqend指向输入 token 流,允许访问构成宏调用的整个 token 序列(从开括号开始,在闭括号后结束)。

如果返回值是true,则不展开宏,即整个宏调用序列(包括参数)将被原样复制到输出,不再进一步处理。如果返回值是false,则按预期展开宏。

expanding_object_like_macro

    template <typename ContextT, typename TokenT, typename ContainerT>
bool expanding_object_like_macro(
ContextT const& ctx, TokenT const &macro,
ContainerT const &definition, TokenT const &macrocall);

函数expanding_object_like_macro当要展开类对象宏时调用,即在实际展开开始之前

ctx参数提供对context_type的引用,该参数在用户实例化预处理迭代器时使用。

macroname参数标记宏定义的位置。它包含标识在相应宏定义中使用宏名称的 token。

定义参数保存要跟踪的宏的宏定义。这是一个标准的 STL 容器,其中包含在宏定义期间标识为宏替换列表的 token 序列。

macrocall参数标记调用此宏的位置。它包含在预处理输入流中标识宏调用的 token。

如果返回值是true,则不展开宏,即宏符号将被原样复制到输出,不再进一步处理。如果返回值是false,则按预期展开宏。

expanded_macro

    template <typename ContextT, typename ContainerT>
void expanded_macro(ContextT const& ctx, ContainerT const &result);

函数expanded_macro在宏展开完成、替换列表完全扫描并且其中标识的宏已替换为其相应的展开结果时调用,但在重新扫描过程开始之前

ctx参数提供对context_type的引用,该参数在用户实例化预处理迭代器时使用。

参数result包含到目前为止的宏展开结果。这是一个标准的 STL 容器,包含生成的 token 序列。

rescanned_macro

    template <typename ContextT, typename ContainerT>
void rescanned_macro(ContextT const& ctx, ContainerT const &result);

函数rescanned_macro宏重新扫描完成时调用,即宏展开完成。

ctx参数提供对context_type的引用,该参数在用户实例化预处理迭代器时使用。

参数result包含整个宏展开的结果。这是一个标准的 STL 容器,包含生成的 token 序列。

包含文件跟踪函数

found_include_directive

    template <typename ContextT>
bool found_include_directive(ContextT const& ctx,
std::string const &filename, bool include_next);

函数found_include_directive当找到 #include 指令时调用。

ctx参数提供对context_type的引用,该参数在用户实例化预处理迭代器时使用。

参数文件名包含 #include 指令后面的(展开后的)文件名。格式为<file>, "file"文件。格式<file>"file"用于在预处理 token 流中找到的 #include 指令,格式文件用于通过 --force_include 命令行参数指定的文件的。

参数include_next如果找到的指令是 #include_next 指令并且BOOST_WAVE_SUPPORT_INCLUDE_NEXT预编译常量被定义为非零值,则设置为 true。

如果返回值是true,则不执行 include 指令,即不加载或处理要包含的文件。整个指令被替换为单个换行符。如果返回值是false,则按正常方式执行指令。

locate_include_file

    template <typename ContextT>
    bool locate_include_file(ContextT& ctx, std::string &file_path, 
        bool is_system, char const *current_name, std::string &dir_path, 
        std::string &native_name)

函数  locate_include_file遇到 #include 指令时调用。它应该定位给定的文件,并返回定位文件的完整文件名。此文件名预计能唯一标识引用的文件。

参数  ctx是用户实例化预处理迭代器时使用的上下文对象的引用。

参数  file_path包含 #include 指令后面的(展开后的)文件名。#include指令。此参数保存 #include 指令中指定的字符串,即<file>"file"将导致参数值为 'file'。

参数  is_system如果此调用是由于 #include <file> 指令而发生的,则设置为  true;否则(即对于 #include "file" 指令),则设置为  false

参数  current_name仅当遇到 #include_next 指令时使用(并且BOOST_WAVE_SUPPORT_INCLUDE_NEXT被定义为非零)。在这种情况下,它指向当前包含文件的唯一完整名称(如果有)。否则,此参数设置为NULL.

参数  dir_path返回时应包含定位文件的目录部分。

参数  native_name返回时应包含定位文件的唯一完整文件名。

返回值定义了文件是否成功定位。

opened_include_file

    template <typename ContextT>
void opened_include_file(ContextT const& ctx,
std::string const &rel_filename, std::string const &abs_filename,
bool is_system_include);

函数opened_include_file在 #include 指令引用的文件成功定位并打开时调用。

ctx参数提供对context_type的引用,该参数在用户实例化预处理迭代器时使用。

参数rel_filename包含已打开文件的(规范化的)可能相对的文件系统路径。此文件名的具体格式取决于预先提供给库的包含搜索路径的格式。

参数abs_filename包含已打开文件的(规范化的)完整文件系统路径。

is_system_include参数表示,给定文件是否是作为#include <...>指令相反。

指令的结果找到的。

    template <typename ContextT>
void returning_from_include_file(ContextT const& ctx);

函数returning_from_include_filereturning_from_include_file

ctx参数提供对context_type的引用,该参数在用户实例化预处理迭代器时使用。

在包含文件处理完成后即将关闭时调用。

    template <typename ContextT>
void detected_include_guard(ContextT const& ctx, std::string const& filename, std::string const& include_guard);

函数detected_include_guarddetected_include_guard

ctx参数提供对context_type的引用,该参数在用户实例化预处理迭代器时使用。

参数文件名当包含文件即将作为检测到的 include guard 方案的结果添加到 #pragma once 头文件列表时调用。这意味着即使在后续的 #include 指令中指定,此头文件也不会再次打开和解析。 

参数包含已打开文件的文件系统路径(相对于当前处理文件的目录或绝对路径,取决于作为包含搜索路径给定的路径)。include_guard

包含检测到的 include guard 的名称。

    template <typename ContextT, typename TokenT>
void detected_pragma_once(ContextT const& ctx, TokenT const& pragma_token, std::string const& filename);

函数detected_pragma_oncedetected_pragma_once

ctx参数提供对context_type的引用,该参数在用户实例化预处理迭代器时使用。

在包含文件即将作为检测到的 #pragma once 指令的结果添加到 #pragma once 头文件列表时调用。这意味着即使在后续的 #include 指令中指定,此头文件也不会再次打开和解析。

参数文件名当包含文件即将作为检测到的 include guard 方案的结果添加到 #pragma once 头文件列表时调用。这意味着即使在后续的 #include 指令中指定,此头文件也不会再次打开和解析。 

参数 pragma_token 指的是触发此预处理钩子的“#pragma” token。

解释 #pragmas

    template <typename ContextT, typename ContextT, typename ContainerT>
bool interpret_pragma(ContextT const &ctx, ContainerT &pending,
typename ContextT::token_type const &option,
ContainerT const &values,
typename ContextT::token_type const &pragma_token);

函数interpret_pragmainterpret_pragma在输入流中找到无法识别的#pragma wave ...或运算符_Pragma("wave ...")

ctx参数提供对context_type的引用,该参数在用户实例化预处理迭代器时使用。

pending时调用。参数可用于将 token 推回输入流,这些 token 将用作整个#pragma wave()

option指令的替换文本。如果此序列留空,则不进行替换,即解释的指令将从生成的 token 流中删除。

参数包含解释的 pragma 的名称。

参数保存提供给 pragma 运算符的值。pragma_token

参数包含实际的 #pragma token,可用于提取某些错误输出的位置信息。

如果返回值是“false”,则整个 #pragma 指令被解释为未知并发出相应的错误消息。返回“true”表示成功解释了给定的 #pragma。

宏定义

    template <
typename ContextT, typename TokenT, typename ParametersT, typename DefinitionT
>
void defined_macro(ContextT const& ctx,
TokenT const &name, bool is_functionlike,
ParametersT const &parameters, DefinitionT const &definition,
bool is_predefined);

函数defined_macrodefined_macro

ctx参数提供对context_type的引用,该参数在用户实例化预处理迭代器时使用。

参数名称宏成功定义时调用。

参数是对持有宏名称的 token 的引用。is_functionlike

参数parameters当新定义的宏被定义为函数式宏时设置为 true。

参数定义保存宏定义的参数 token。如果宏没有参数,或者它是一个类对象宏,则此容器为空。

参数包含作为新定义宏的替换序列(定义部分)给出的 token 序列。is_predefined

在库的初始初始化阶段预定义的宏都设置为 true。

    template <typename ContextT, typename TokenT>
void undefined_macro(ContextT const& ctx, TokenT const &name);

函数undefined_macroundefined_macro

ctx参数提供对context_type的引用,该参数在用户实例化预处理迭代器时使用。

参数名称宏定义成功移除时调用。

保存了宏的 token,其定义已被移除。

    template <typename ContextT, typename ContainerT>
bool found_warning_directive(ContextT const& ctx,
ContainerT const &message);

函数found_warning_directivefound_warning_directive当遇到 #warning 指令时调用。只有当BOOST_WAVE_SUPPORT_WARNING_DIRECTIVE

ctx参数提供对context_type的引用,该参数在用户实例化预处理迭代器时使用。

参数消息编译时常量被定义为非零值(参见 Compile Time Configuration 以获取更多信息)时,此函数才会被调用。

如果返回值是false引用遇到的 #warning 指令的参数 token 序列。true,库将抛出类型为 warning_directive 的预处理器异常(正常执行继续),如果返回值是

则继续执行,就好像没有找到 #warning 指令一样,整个指令被替换为单个换行符。

    template <typename ContextT, typename ContainerT>
bool found_error_directive(ContextT const& ctx,
ContainerT const &message);

函数found_error_directivefound_error_directive

ctx参数提供对context_type的引用,该参数在用户实例化预处理迭代器时使用。

参数消息遇到 #error 指令时调用。

如果返回值是false引用遇到的 #error 指令的参数 token 序列。true,库将抛出类型为 error_directive 的预处理器异常(正常执行继续),如果返回值是

则继续执行,就好像没有找到 #error 指令一样,整个指令被替换为单个换行符。

    template <typename ContextT, typename ContainerT>
void found_line_directive(ContextT const& ctx,
ContainerT const &arguments, unsigned int line,
std::string const& filename);

函数found_line_directivefound_line_directive

ctx参数提供对context_type的引用,该参数在用户实例化预处理迭代器时使用。

参数参数遇到 #line 指令时调用。

参数引用遇到的 #line 指令的参数 token 序列。

参数文件名包含从 #line 指令识别的行号。

引用从 #line 指令识别的文件名(如果提供了)。

    template <typename ContextT, typename ContainerT>
    bool emit_line_directive(ContextT const& ctx, ContainerT &pending, 
        typename ContextT::token_type const& act_token);

函数emit_line_directiveemit_line_directive

参数  ctx是用户实例化预处理迭代器时使用的上下文对象的引用。

参数  pending当需要发出 #line 指令到生成的输出时调用。

参数  可用于将 token 推回输入流,这些 token 将被用作 #line 指令的默认输出的替代。act_token

包含实际的 #pragma token,可用于错误输出。此 token 中存储的行号可用作作为 #line 指令一部分发出的行号。false如果返回值是  true,则库发出默认的 #line 指令。返回  pending将阻止任何进一步的操作, 中包含的 token 将按原样复制到输出。