C++ 使用预处理器部分处理文件

C++ 使用预处理器部分处理文件,c++,c,c-preprocessor,C++,C,C Preprocessor,我们继承了一个非常卷积的项目(500kloc),其中包含大量的预处理器条件逻辑,其中大部分不再相关,我想对其进行清理 我是否可以使用预处理器摂仅扩展部分条件逻辑,而将所有其他预处理器宏、定义和包含单独保留在输出中 在这里,我所说的“预处理器”,实际上是指“任何工具”,或者是标准的C预处理器,或者我可以安装的东西,或者甚至是一个经过黑客攻击的Perl或Python脚本 例如,假设我们有一组代码: #include <foo> #define baz #define bar(a) do

我们继承了一个非常卷积的项目(500kloc),其中包含大量的预处理器条件逻辑,其中大部分不再相关,我想对其进行清理

我是否可以使用预处理器摂仅扩展部分条件逻辑,而将所有其他预处理器宏、定义和包含单独保留在输出中

在这里,我所说的“预处理器”,实际上是指“任何工具”,或者是标准的C预处理器,或者我可以安装的东西,或者甚至是一个经过黑客攻击的Perl或Python脚本


例如,假设我们有一组代码:

#include <foo>
#define baz
#define bar(a) do{(a)+1} \
               while(0)
#ifdef X
  #if Y > 20
    #if Z > 5
      so_far_so_good = true;
    #endif
    #ifdef baz
    something();
    #endif
  #else
    otherthing();
  #endif
#else
  #if Z > 10
    wow().this.is.bad;
  #endif
#endif
将产生:

#include <foo>
#define baz
#define bar(a) do{(a)+1} \
               while(0)
#ifdef X
    #if Z > 5
      so_far_so_good = true;
    #endif
    #ifdef baz
    something();
    #endif
#else
  #if Z > 10
    wow().this.is.bad;
  #endif
#endif
你能给我:

#include <foo>
#define bar(a) do{(a)+1} \
               while(0)
#ifdef X
      so_far_so_good = true;
    something();
#else
#endif
现在我可以过滤掉很多东西,然后将我希望预处理器扩展的东西放入
simple.h
。注释被忽略,而
#行
指令被忽略

这几乎就做到了,因为include没有被拉入,
#define
块没有被定义,因此没有扩展到主体中。但当然,它不允许我指定要保留在输出中的条件逻辑集。那太糟糕了。其中一些重要的是保持有条件

#if
嵌套,而
#else
#endif
标记在词汇上不匹配,将问题置于正则表达式管道之外。我需要一个完整的解析器,它实际上与cpp本身完全相同,但对扩展的内容有更细粒度的控制


因此,在深入研究预处理器来实现这一点之前,我想问问是否有人曾经解决过这个问题。我不可能是唯一一个继承了一个满是枯枝的预处理器意大利面窝的人

有一个名为“”的工具,它可以做你想做的事。

你一定要看看

从boost.wave前言中:

因此,Wave项目的主要目标是:

  • 完全符合C++标准(ISO/IEC 1488∶1998)和C99标准(CHITIT/ISO/IEC 9899:1999)
  • 在游戏的解析部分使用Spirit[4](当然是:-)
  • STL和/或Boost库的最大利用率(紧凑性和可维护性)
  • 实现附加功能的直接可扩展性 构建一个灵活的库,用于不同的C++词汇和预处理需要

确认,结合原始问题中的
escape\u tr
shell脚本,可以执行我希望在此源代码库上执行的所有操作。谢谢你,保罗。但是应该存在类似于
cppreadlight
的东西。它概括了
unifdef
cpp
。我不确定为什么需要
escape\u tr
,但可能我遗漏了一些东西。
unifdef
只处理ifdef。我还想省略一些多余的定义。假设这不是我在原始问题中提出的问题的一部分。我不认为这是真的-如果你做“unifdef-DY=22”,它也会处理所有的“#if Y…”。
cpptreadlight -DY=22 -DZ=8 -DX --only=Y,baz,Z
#include <foo>
#define bar(a) do{(a)+1} \
               while(0)
#ifdef X
      so_far_so_good = true;
    something();
#else
#endif
function escape_tr() { 
   gsub "#(define|include)" '@@@\1' < $1 | 
     (echo '#include "simple.h"' && gsub '\\$' "%%%") | 
       cpp -C -P -DY=301 -DZ > $1.new 
}