是否有一个C预处理器根据定义/未定义的值消除#ifdef块?
原始问题
我想要的不是标准的C预处理器,而是可以从某处接受的变体 – 可能是命令行通过-DNAME1和-UNAME2选项 – 定义了哪些宏的规范,然后消除了死码。
通过一些例子可能更容易理解我所追求的内容:
#ifdef NAME1 #define ALBUQUERQUE "ambidextrous" #else #define PHANTASMAGORIA "ghostly" #endif
如果命令是使用’-DNAME1’运行的,则输出将为:
#define ALBUQUERQUE "ambidextrous"
如果命令是使用’-UNAME1’运行的,则输出将为:
#define PHANTASMAGORIA "ghostly"
如果命令是在没有选项的情况下运行的,则输出将与输入相同。
这是一个简单的例子 – 我希望代码也可以处理更复杂的情况。
用现实世界但仍然简单的例子来说明:
#ifdef USE_VOID #ifdef PLATFORM1 #define VOID void #else #undef VOID typedef void VOID; #endif /* PLATFORM1 */ typedef void * VOIDPTR; #else typedef mint VOID; typedef char * VOIDPTR; #endif /* USE_VOID */
我想用-DUSE_VOID -UPLATFORM1
运行命令并获取输出:
#undef VOID typedef void VOID; typedef void * VOIDPTR;
另一个例子:
#ifndef DOUBLEPAD #if (defined NT) || (defined OLDUNIX) #define DOUBLEPAD 8 #else #define DOUBLEPAD 0 #endif /* NT */ #endif /* !DOUBLEPAD */
理想情况下,我想使用-UOLDUNIX
运行并获取输出:
#ifndef DOUBLEPAD #if (defined NT) #define DOUBLEPAD 8 #else #define DOUBLEPAD 0 #endif /* NT */ #endif /* !DOUBLEPAD */
这可能是我的运气!
动机:大而古老的代码库,有很多条件代码。 许多条件不再适用 – 例如,OLDUNIX平台不再生成且不再受支持,因此不需要在代码中引用它。 其他条件总是如此。 例如,通过条件编译添加function,以便单个版本的代码可用于function不可用的旧版本软件和可用的新版本(或多或少)。 最终,不再支持没有该function的旧版本 – 所有内容都使用该function – 因此应删除该function是否存在的条件,并且应删除“何时缺少function”代码。 我想有一个自动完成工作的工具,因为它比手动操作更快更可靠(当代码库包含21,500个源文件时,这是非常关键的)。
(该工具的一个非常聪明的版本可能会读取#include
文件以确定控制宏 – 在命令行上由-D或-U指定的那些宏 – 是否在这些文件中定义。我不确定这是否真的有用除了作为备份诊断之外,无论它做什么,伪预处理器都不能扩展宏或逐字包含文件。输出必须与输入代码类似,但通常比输入代码更简单。)
状态报告(一年后)
使用一年后,我对所选答案推荐的’ sunifdef ‘感到非常满意。 它还没有犯错,我不指望它。 我唯一的狡辩是风格。 给出如下输入:
#if (defined(A) && defined(B)) || defined(C) || (defined(D) && defined(E))
并使用’-UC’运行(C从未定义),输出为:
#if defined(A) && defined(B) || defined(D) && defined(E)
这在技术上是正确的,因为’&&’比’||’更紧密,但它是一个混乱的公开邀请。 我更倾向于在’&&’条件集中包括括号,如原始:
#if (defined(A) && defined(B)) || (defined(D) && defined(E))
然而,鉴于我必须使用的一些代码的模糊性,因为这是最大的挑选是一个强烈的赞美; 它对我来说是很有价值的工具。
街区的新小孩
检查了URL以包含在上面的信息中,我看到(正如预测的那样)有一个名为Coan的新程序,它是’sunifdef’的inheritance者。 它可以在SourceForge上获得,并且自2010年1月以来一直在使用。我将在今年晚些时候,或者明年,或者某个时候,或者从未进行更多报告。
我对C一无所知,但听起来你正在寻找像unifdef
这样的unifdef
。 请注意,它自2000年以来一直没有更新,但有一个名为“unifdef之子”(sunifdef)的继任者。
几年前我使用unifdef来解决你描述的那种问题,并且它运行良好。 即使它自2000年以来还没有更新过,预处理器ifdef的语法从那时起就没有实质性的改变,所以我希望它仍然会做你想要的。 我想可能存在一些编译问题,尽管这些软件包最近出现了。
我从未使用过sunifdef,所以我不能直接评论它。
你也可以尝试这个工具http://coan2.sourceforge.net/
这样的东西将删除ifdef块:
coan source -UYOUR_FLAG –filter c,h – 保存YourSourceTree
大约在2004年,我写了一个工具,完全符合您的要求。 我从来没有开始分发该工具,但代码可以在这里找到:
http://casey.dnsalias.org/exifdef-0.2.zip (这是一个dsl链接)
它大约是1.7k行并且使用bison和flex来实现足够的C语法来解析预处理器语句,注释和字符串。
如果您需要类似于预处理器的东西,灵活的解决方案是Wave (来自boost)。 它是一个用于构建类似C预处理器的工具的库(包括诸如C ++ 03和C ++ 0x预处理器之类的东西)。 因为它是一个库,你可以挂钩它的输入和输出代码。