我想在我正在从事的一个项目中删除一个宏,由于c / cpp源中出现了800多个事件,因此需要脚本来执行。请注意,尽管此宏出现在cpp文件中,但声明和类型均为纯c。
所讨论的宏如下所示:
#define ARRAY(data_type, size, array_name) data_type array_name[size]
在源代码中使用时,看起来像这样:
#define BAR_LEN 2
struct Foo_t
{
uint16_t example;
ARRAY(uint8_t, BAR_LEN, Bar); //<-- This line
uint8_t target;
};
现在,我可以列出所有源文件
find . -regextype egrep -regex '.*/.*\.(h|c|cpp)' -print0
并可能将它们通过管道传递到xargs中,以便与其他实用程序(如awk或sed)一起使用。问题是,我不确定该朝哪个方向走。使用上面的示例,我的目标是转换:
struct Foo_t
{
uint16_t example;
ARRAY(uint8_t, BAR_LEN, Bar); //<-- This line
uint8_t target;
};
收件人
struct Foo_t
{
uint16_t example;
uint8_t Bar[BAR_LEN]; //<-- This line
uint8_t target;
};
但是,有很多使用该宏的声明,它们为每个调用传递不同的参数。同样,宏用法在间隔方面具有格式差异。我现在有些困惑,任何方向将不胜感激。谢谢!
更新:
出于测试目的,我创建了一个Test.txt文件来针对命令进行测试,其中仅包含以下4行:
ARRAY( uint8_t, 16, Bar1);
ARRAY(uint8_t,4,Bar2);
ARRAY(uint8_t, 18,Bar3);
ARRAY(uint8_t,2, Bar4);
实际用法可在下面的链接中找到:
答案 0 :(得分:1)
最有可能的是,最好在预处理器模式下使用gcc扩展宏,但如果仅(并且确实)要扩展此宏,则只要提供了宏调用,以下oneliner可能已经做到了在一行中,类型本身就是示例中的简单标识符。
ERROR TypeError: $(...).datepicker is not a function
这将输出您的测试数据:
perl -pi -e 's/\bARRAY\(\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*\)/$1 $3\[$2\]/g' *.c
另一种方法是运行uint8_t Bar1[16];
uint8_t Bar2[4];
uint8_t Bar3[18];
uint8_t Bar4[2];
,但这也会扩展所有gcc -E
。