8

我有大量的 c++ 源文件,我想通过扩展我指定的单个函数宏来转换它们,并保持所有其他预处理指令不变。宏的参数通常会涉及括号和大括号以及括号保护的逗号,因此使用 sed 和 kin 执行此操作似乎并不直接。

更新:我们的代码大量使用宏来生成样板(例如 swig 的帮助代码)。当我们更好地弄清楚如何做某些事情时,各种宏不再做任何非常有趣的事情(例如,只是声明一些函数),许多人抱怨它们使代码更难阅读。我想扩展不那么有趣的宏,这些宏扩展到简单的 C++ 代码。

4

3 回答 3

2

我通过在 python 中使用正则表达式来完成这类事情。您可以编写一个相当短的脚本来处理大量文件并在每个文件上运行一些正则表达式。正则表达式可能是最耗时的部分。

于 2013-01-08T18:42:24.080 回答
1

我也有类似的需求:摆脱(扩展)那些用于处理古老的 C89 之前的编译器的无用的原型隐藏宏,同时保留其他所有内容。

示例来自<stdio.h>

int     _EXFUN(vfprintf, (FILE *__restrict, const char *__restrict, __VALIST)
               _ATTRIBUTE ((__format__ (__printf__, 2, 0))));
int     _EXFUN(vprintf, (const char *, __VALIST)
               _ATTRIBUTE ((__format__ (__printf__, 1, 0))));
int     _EXFUN(vsprintf, (char *__restrict, const char *__restrict, __VALIST)
               _ATTRIBUTE ((__format__ (__printf__, 2, 0))));
int     _EXFUN(fgetc, (FILE *));
char *  _EXFUN(fgets, (char *__restrict, int, FILE *__restrict));
int     _EXFUN(fputc, (int, FILE *));

在这里,我需要将宏扩展_EXFUN(name,proto)name proto. 请注意,某些宏调用跨越多行。

解决方案是使用宏处理器,m4因为它与 #include 指令和其他宏处理无关(与cppor不同gcc -E):

$ m4 '-D_EXFUN=$1$2' stdio.h
int     vfprintf(FILE *__restrict, const char *__restrict, __VALIST)
               _ATTRIBUTE ((__format__ (__printf__, 2, 0)));
int     vprintf(const char *, __VALIST)
               _ATTRIBUTE ((__format__ (__printf__, 1, 0)));
int     vsprintf(char *__restrict, const char *__restrict, __VALIST)
               _ATTRIBUTE ((__format__ (__printf__, 2, 0)));
int     fgetc(FILE *);
char *  fgets(char *__restrict, int, FILE *__restrict);
int     fputc(int, FILE *);
于 2018-06-22T14:37:32.200 回答
0
  • 创建undef.h文件
  • 用 's 填充#undef你不想扩展的所有宏
  • 包括extern int LandMarkSoYouCanFindThis;作为最后一行
  • 对于每个文件
    • #include "undef.h"在文件中最后一个包含之后注入。
    • 通过运行文件cpp
    • 使用LandMark切断包含的所有内容
    • 合并回原始文件。

您可以通过从#undefing 刚刚选择的宏和#undefing 所有宏之间的差异生成补丁来自动化最后一步。

于 2013-08-09T15:12:13.407 回答