如何摆脱可怕的无用的宏

时间:2014-04-03 12:52:32

标签: c sed preprocessor

我有一个非常大的C和C ++代码(~200k loc),它大量使用了糟糕的宏:

/* ... */
#define PRIVATE static
#define BEGIN           {
#define END             }
/* ... */
#define WHILE(e)        while (e) {
#define DO /* yep, it's empty */
#define ENDWHILE        }
/* and it goes on and on, for every keyword of the language */

这是事情,我想摆脱那个愚蠢的标题,清理代码,并正确缩进。

起初,我想用一个简单的sed替换所有这些宏,但似乎并不那么简单。

WHILE的情况很成问题(其他语句也是如此)。我无法通过WHILE来替换while,因为缺少开头的大括号。当然,由于DO宏没有做任何事情,它并不总是出现在代码中。因此,将DO替换为{将无法解决问题。

我也不能使用结束语,因为条件通常被分成多行:

WHILE (clsr_calibragedf_tabdisque.tab_disque[indice_disque].tab_date[indice_date] NE
                   clsr_calibragedf_tabdate [indice].date) DO
                indice ++;
            ENDWHILE

我能想到的最佳解决方案是C预处理器,它只能替换特定的宏,而不能扩展#include指令或其他宏。但我找不到那样的东西。

有什么想法吗?

2 个答案:

答案 0 :(得分:7)

呸!怎么样:

  1. 通过一些perl运行您的程序,以独特的方式注释#include指令(例如/*FIXSTUFF #include <blah.h> FIXSTUFF*/)。您可能希望以类似的方式注释掉其他预处理器内容(例如#define)。

  2. 检查每个文件#include的奇怪宏的定义(仅限)。

  3. 现在在每个文件上运行gcc -E,这将预处理宏。

  4. 反向步骤1.

  5. 运行indent以获得良好的衡量标准。

  6. 注意,C预处理执行以下操作(从here中窃取):

    1. Trigraph替换:预处理器用它们代表的字符替换三字符序列。
    2. 线拼接:使用转义换行序列继续的物理源线拼接成逻辑线。
    3. 标记:预处理器将结果分解为预处理标记和空格。它用空格替换注释。
    4. 宏扩展和指令处理:执行预处理指令行,包括文件包含和条件编译。预处理器同时扩展宏,并在1999版C标准中处理_Pragma运算符。
    5. 因此,理论上您将在源代码中丢失三字符(有些人会建议这是一个奖励),并可能改变行拼接(在步骤5中使用indent修复)。您将需要按照步骤(1)保护任何其他预处理器指示。

      祝你好运!

答案 1 :(得分:0)

Eclipse IDE有一些很棒的搜索和替换工具。您可以在那里导入代码,然后使用文件搜索工具。您可以像这样使用它:

  1. 使用Ctrl + H(或上下文菜单中的Search > File...)将其打开以搜索您的某个宏的所有出现

  2. 点击Replace...打开替换窗口,可以选择替换

  3. 点击Preview >查看所有替换内容并将其应用于OK

  4. 使用正则表达式

    对于更复杂的情况,您可以在文件搜索视图中使用正则表达式标记。例如,以下是如何将其应用于WHILE-ENDWHILE-macro:

    1. 搜索正则表达式(请参阅反向查找,了解其工作原理):

      WHILE(((?!ENDWHILE).|\s)+)ENDWHILE

    2. 插入替换while(\1)

    3. 在预览页面中查看结果并应用