是否有一个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预处理器之类的东西)。 因为它是一个库,你可以挂钩它的输入和输出代码。