2010-11-10 60 views
5

我們繼承了一個非常複雜的項目(500kloc),其中大部分已不再相關,並且我想清理它,其中lot預處理器條件邏輯。使用預處理器部分處理文件

我可以使用預處理器¹僅擴展條件邏輯的的一些,並將所有其他預處理器宏,定義和單獨包括在輸出中嗎?在這裏,「預處理器」,我的意思是「任何工具」,無論是標準的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 

的工具,我想(和可能需要的,如果不存在的話寫)將是一個版本CPP的接受不僅是特定調用的定義列表,而且是擴展期間要尊重的定義列表。任何不在第二個列表中的預處理器符號完全保留。一個例子是爲了:

cpptreadlight -DY=22 --only=Y 

會產生:

#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 

和:

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 

注意,即使X定義,它被拋在後面,因爲它沒有出現在--only列表中。還請注意,在列表中,baz的值爲,因此在源中定義它之後進行擴展。


我嘗試了黑客的解決方案:逃避使用如下管道無趣的東西(我自己GSUB工具被使用,但它確實你所期望的):

function escape_tr() { 
    gsub "#(define|include)" '@@@\1' < $1 | 
    (echo '#include "simple.h"' && gsub '\\$' "%%%") | 
     cpp -C -P -DY=301 -DZ > $1.new 
} 

現在我可以過濾掉很多東西,然後把我希望預處理器擴展的東西放在simple.h中。留下評論,#line指令被遺漏。

這個差不多沒有訣竅,因爲那裏面沒有拉入,#define塊沒有定義,所以沒有擴展到正文中。但是,它當然不會讓我指定我想要保留在輸出中的一組條件邏輯。那很糟。其中一些重要的是保持有條件。

#if巢穴,和#else#endif令牌不從詞彙上匹配,使問題超出正則表達式管道。我需要一個全面的解析器,與cpp本身幾乎完全相同,但是對擴展的內容進行了更精細的控制。

因此,在挖掘預處理器來實現它之前,我想我會問是否有人解決過這個問題。我不可能是唯一一個繼承了一個充滿死枝的預處理意大利麪條巢。

回答

8

有一種名爲「unifdef」的工具,可以做你想做的。

+0

很快。謝謝! – clord 2010-11-10 19:02:38

+0

確認這與原始問題中的'escape_tr' shell腳本相結合可以執行我想在此源代碼基礎上完成的所有操作。謝謝保羅。 雖然像'cpptreadlight'應該存在。它概括了'unifdef'和'cpp'。 – clord 2010-11-10 19:47:06

+0

我不知道爲什麼你需要'escape_tr',但可能我錯過了一些東西。 – 2010-11-10 20:38:38

0

你一定要採取從boost.wave前言看看​​

所以對於波項目的主要目標是:

  • 完全符合與C++標準(ISO/IEC 14882:1998)1和C99標準(INCITS/ISO/IEC 9899:1999)
  • Spirit的使用[4] f或遊戲的解析部分(當然:-)
  • STL的最大使用和/或升壓庫(緊湊性和可維護性)
  • 爲附加功能 構建爲不同的C柔性庫執行直接的擴++詞法和預處理需求