Wave 驱动程序

这里实现了一个驱动程序,用于Wave库,它利用了该库的几乎所有功能。它可以用作任何其他 C++ 编译器之上的预处理器可执行文件。它输出从给定输入文件生成的预处理标记的文本表示。此驱动程序具有以下命令行语法

Usage: wave [options] [@config-file(s)] file:
 
  Options allowed on the command line only:
    -h [--help]:            print out program usage (this message)
    -v [--version]:         print the version number
    -c [--copyright]:       print out the copyright statement
    --config-file filepath: specify a config file (alternatively: @filepath)
 
  Options allowed additionally in a config file:
    -o [--output] path:          specify a file [path] to use for output instead of 
                                 stdout or disable output [-]
    -E [ --autooutput ]:         output goes into a file named <input_basename>.i
    -I [--include] path:         specify an additional include directory
    -S [--sysinclude] syspath:   specify an additional system include directory
    -F [--forceinclude] file:    force inclusion of the given file
    -D [--define] macro[=[value]]:    specify a macro to define
    -P [--predefine] macro[=[value]]: specify a macro to predefine
    -U [--undefine] macro:       specify a macro to undefine
    -u [--undefineall]:          undefine all macrodefinitions
    -n [--nesting] depth:        specify a new maximal include nesting depth
	
  Extended options (allowed everywhere)
    -t [--traceto] arg:          output trace info to a file [arg] or to stderr [-]
    --timer:                     output overall elapsed computing time
    --long_long:                 enable long long support if C++ mode
    --variadics:                 enable variadics and placemarkers in C++ mode
    --c99:                       enable C99 mode (implies variadics and placemarkers)
    --c++11:                     enable C++11 mode (implies --variadics and --long_long)
    --c++20:                     enable C++20 mode (adds __VA_OPT__ to variadics)
                                                   (implies --variadics and --long_long)
    -l [ --listincludes ] arg:   list included file to a file [arg] or to stdout [-]
    -m [ --macronames ] arg:     list names of all defined macros to a file [arg] or 
                                 to stdout [-]
    -c [ --macrocounts ] arg     list macro invocation counts to a file [arg] or to
                                 stdout [-]
    -p [ --preserve ] arg (=0):  preserve whitespace
                                 0: no whitespace is preserved (default),
                                 1: begin of line whitespace is preserved,
                                 2: comments and begin of line whitespace is preserved,
                                 3: all whitespace is preserved
    -L [ --line ] arg (=1):      control the generation of #line directives
                                 0: no #line directives are generated
                                 1: #line directives will be emitted (default)
    -x [ --extended ]:           enable the #pragma wave system() directive
    -G [ --noguard ]:            disable include guard detection
    -g [ --listguards ]:         list names of files flagged as 'include once' to a
                                 file [arg] or to stdout [-]
    -s [ --state ] arg:          load and save state information from/to the given
                                 file [arg] or 'wave.state' [-] (interactive mode
                                 only)

可能的选项简单明了,不言自明。以下更详细地描述了其中一些选项。请注意,扩展选项(--c99 和 --variadics)仅在驱动程序使用以下常量编译时可用WAVE_SUPPORT_VARIADICS_PLACEMARKERS定义。

-o [--output] path

指定用于生成的预处理输出流的文件名。如果未给出此选项,则使用标准输出 (stdout)。如果给定的文件名等于'-'(不带引号),则最初不会生成任何输出。这对于仅进行语法检查或结合使用 #pragma wave option(output: ...) 指令(将生成的输出限制为仅特定部分)特别有用(有关描述,请参阅 支持的杂注指令 一节)。

-E [--autooutput]

生成的输出将最终进入一个文件,该文件以输入文件的基本名称命名,并带有文件扩展名 '.i',例如,对于输入文件 'inputfile.cpp',输出将写入 'inputfile.i'。如果使用 --output 选项指定了输出文件名,则此选项将无效。

-I [--include] option

将目录 dir 添加到要搜索头文件的目录列表的头部。这可用于覆盖系统头文件,替换为您自己的版本,因为这些目录是在系统头文件目录之前搜索的。但是,您不应使用此选项添加包含供应商提供的系统头文件的目录(请为此使用 '-S')。如果您使用多个 '-I' 选项,则目录会从左到右扫描,标准系统目录位于最后。

如果标准系统包含目录或使用 '-S' 指定的目录也使用 '-I' 指定,则 '-I' 选项将被忽略。该目录仍将被搜索,但作为系统目录,位于系统包含链中的正常位置。

-I- [--include-] option

Wave库为包含文件维护两个单独的搜索路径。一个用于用户包含文件的搜索路径,一个用于系统包含文件的搜索路径,其中在系统包含路径之前搜索用户包含路径。

在最终给定的 '-I-' 选项之前使用 '-I' 选项指定的任何目录仅针对 '#include "file"'(用户包含文件)的情况进行搜索,它们不会针对 '#include <file>' 指令(系统包含文件)进行搜索。如果在给定 '-I-' 选项后使用 '-I' 选项指定了其他目录,则会针对所有 '#include' 指令搜索这些目录(通常所有 '-I' 目录都以这种方式使用)。

此外,'-I-' 选项禁止将当前目录(当前输入文件来自的目录)用作 '#include "file"' 指令的第一个搜索目录。使用 '-I.',您可以指定搜索编译器调用时所在的目录。这与预处理器默认执行的操作不完全相同,但通常令人满意。

-S [--sysinclude] option

将给定的目录添加到要搜索系统头文件的目录列表的头部。如果您使用多个 '-S' 选项,则目录会从左到右扫描。此选项在 wave.cfg 配置文件中最有用,用于指定在哪里搜索系统包含文件。

-F [--forceinclude] option

将给定的文件作为常规输入处理,并在开始处理常规输入文件之前包含所有结果输出。如果给出了多个此类选项,则文件将按其在命令行上出现的顺序进行预包含。

-D [--define] macro[=definition]
-P [--predefine] macro[=definition]

此选项允许从命令行定义 ('-D') 或预定义 ('-P') 宏。与 '-D' 或 '-P' 选项结合使用的字符串应符合通常的语法 MACRO(x)=definition,详见 此处

'-D' 和 '-P' 选项之间的唯一区别是,后者预定义了一个宏,使其无法通过#undef来自预处理程序内部的指令取消定义。

-U [--undefine] macro

这允许取消定义Wave库的一些自动预定义的宏(请参阅 预定义宏)。唯一的例外是 __LINE__, __FILE__, __DATE__, __TIME__, __STDC____cplusplus 预定义宏,它们是不可取消定义的。如果对同一个名称同时指定了 -U 和 -D,则该名称不会被预定义。

-n [--nesting] depth

指定新的最大包含嵌套深度。如果预处理达到此包含文件嵌套深度,它会在发出错误消息后中止预处理。默认的包含文件嵌套深度为 1024。

-t [--traceto] path

启用内置于Wave库中的跟踪功能。path 指定用于生成的跟踪日志输出的文件名。如果给定的文件名等于'-'(不带引号),则跟踪日志会被放入标准错误流 (stderr) 中。

跟踪仅针对通过以下指令显式启用的输入部分执行#pragma wave trace(enable)_Pragma("wave trace(enable)")指令。有关更多详细信息,请参阅 此处

--timer

启用对给定输入文件所需的总计算耗时的跟踪。编译完成后,耗时将打印到 stdout。

--variadics

在常规 C++ 模式下启用对变长参数(具有可变参数列表的宏)、占位符(空宏参数)和运算符 _Pragma 的支持。此选项预定义了一个特殊的预定义宏__WAVE_HAS_VARIADICS__.

--c99

启用 C99 模式。此模式启用某些 C99 特有的功能,例如变长参数(具有可变参数列表的宏)、占位符(空宏参数)和运算符 _Pragma 的支持支持,并禁用某些 C++ 特有的标记类型,例如'::', '->*'and'->.'。此模式的几个预定义宏不同,有关预定义宏的更多信息,您可以查看 此处

--c++11

启用 C++11 模式。此模式启用 C++11 特有的关键字和功能,例如变长参数(具有可变参数列表的宏)、占位符(空宏参数)和运算符 _Pragma 的支持支持。此模式的几个预定义宏不同,有关预定义宏的更多信息,您可以查看 此处

-l [--listincludes] path

启用所有已打开的包含文件的名称输出。path 指定用于生成的包含日志输出的文件名。如果给定的文件名等于'-'(不带引号),则包含日志会被放入标准输出流 (stdout) 中。

-m [--macronames] path

启用所有已定义宏的输出。这包括宏名称、其参数名称(如果宏是函数式宏)及其定义。path 指定用于生成的宏列表输出的文件名。如果给定的文件名等于'-'(不带引号),则宏列表会被放入标准输出流 (stdout) 中。

-c [--macrocounts] path

启用所有宏调用计数的输出。path 指定用于生成的列表输出的文件名。如果给定的文件名等于'-'(不带引号),则宏列表会被放入标准输出流 (stdout) 中。

-p [--preserve] arg

保留不位于宏定义内部的输入流中的空白字符。该参数定义要保留的空白数量。值 '0'(零)跳过所有空白,值 '1' 仅保留行首空白,值 '2' 保留所有注释和所有行首空白,值 '3' 将保留输出中的所有空白。

即使指定了参数不为 '0'(零)的此选项,位于宏定义内部的注释仍会被跳过。如果命令行上未指定此选项,则仅保留基本空白(相当于参数值为 '0')。

-L [--line]

控制Wave工具是否生成 #line 指令。如果参数为 '1',则将发出这些指令;如果参数值为 '0',则不会生成 #line 指令。如果未指定此选项,Wave将始终生成 #line 指令。

-x [--extended]

启用 #pragma wave system() 指令。此指令现在默认禁用,因为它可能导致潜在的安全威胁。Wave如果未指定此命令行参数且遇到 #pragma wave system() 指令,驱动程序将发出提醒。

-G [--noguard]

此选项禁用 Wave 库在处理包含文件期间通常执行的自动包含保护检测。有关自动包含保护检测的更多信息,请参阅 上下文对象 类参考。

-g [--listguards] arg

此选项将所有包含 #pragma once 或包含包含保护的所有已发现的包含文件列入给定文件。如果给定的文件名等于'-'(不带引号),则保护日志会被放入标准输出流 (stdout) 中。有关自动包含保护检测的更多信息,请参阅 上下文对象 类参考。

-s [--state]

此选项尝试指示Wave工具从作为参数给出的文件中加载序列化信息,并在会话结束时将内部状态信息保存回同一个文件。使用此选项时,Wave会加载并保存所有已定义的宏(甚至是预定义的宏)以及有关用 #pragma once 标记和/或标识为具有包含保护的已处理头文件的信息。

注意:此选项仅在交互模式下有效。

@ [--config-file] option

一些可能的命令行选项可以在特殊的配置文件中指定。这非常有用,作为不同全局配置的简写。配置文件可能包含其他选项(即 -I, -S, -F, -U, -D 和 -P 选项),每行一个选项。空行和以 '#' 字符开头的行将被忽略(被视为注释行)。请注意,'#' 字符仅在其是行中第一个非空白字符时才被视为注释的开始。以下是一个小示例,说明了支持的配置文件语法

    # 
    # enable variadics et.al. in C++ mode
    #
    --variadics
    #
    # enable timer support
    #
    --timer
    #
    # emulate gcc V3.3.2
    #
    -D__GNUC__=3
    -D__GNUC_MINOR__=3
    -D__GNUC_PATCHLEVEL__=2
    -D__GNUG__
    # 
    # add Boost to the system include search paths
    #
    -S/usr/local/boost

在命令行上指定配置文件有一种简写:只需在相应文件名之前立即使用 '@' 字符即可。

配置文件中找到的选项被解释为仿佛它们被放置在命令行上的配置文件选项位置一样。

Wave驱动程序在启动时会从输入文件所在的目录开始,在文件系统层次结构中的每个目录中查找名为 'wave.cfg' 的配置文件。找到的第一个文件将停止搜索。如果存在文件,则将其视为常规配置文件,并将在其中指定的选项解释为仿佛它们是作为命令行上的第一个选项给出的。此功能对于为Wave预处理器驱动程序定义全局环境非常有用。