我有大量的 c++ 源文件,我想通过扩展我指定的单个函数宏来转换它们,并保持所有其他预处理指令不变。宏的参数通常会涉及括号和大括号以及括号保护的逗号,因此使用 sed 和 kin 执行此操作似乎并不直接。
更新:我们的代码大量使用宏来生成样板(例如 swig 的帮助代码)。当我们更好地弄清楚如何做某些事情时,各种宏不再做任何非常有趣的事情(例如,只是声明一些函数),许多人抱怨它们使代码更难阅读。我想扩展不那么有趣的宏,这些宏扩展到简单的 C++ 代码。
我有大量的 c++ 源文件,我想通过扩展我指定的单个函数宏来转换它们,并保持所有其他预处理指令不变。宏的参数通常会涉及括号和大括号以及括号保护的逗号,因此使用 sed 和 kin 执行此操作似乎并不直接。
更新:我们的代码大量使用宏来生成样板(例如 swig 的帮助代码)。当我们更好地弄清楚如何做某些事情时,各种宏不再做任何非常有趣的事情(例如,只是声明一些函数),许多人抱怨它们使代码更难阅读。我想扩展不那么有趣的宏,这些宏扩展到简单的 C++ 代码。
我通过在 python 中使用正则表达式来完成这类事情。您可以编写一个相当短的脚本来处理大量文件并在每个文件上运行一些正则表达式。正则表达式可能是最耗时的部分。
我也有类似的需求:摆脱(扩展)那些用于处理古老的 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 指令和其他宏处理无关(与cpp
or不同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 *);
undef.h
文件#undef
你不想扩展的所有宏extern int LandMarkSoYouCanFindThis;
作为最后一行#include "undef.h"
在文件中最后一个包含之后注入。cpp
LandMark
切断包含的所有内容您可以通过从#undef
ing 刚刚选择的宏和#undef
ing 所有宏之间的差异生成补丁来自动化最后一步。