【问题标题】:Finding and modifying function definitions (C++) via bash-script通过 bash 脚本查找和修改函数定义 (C++)
【发布时间】:2015-08-21 14:28:39
【问题描述】:

目前我正在做一个相当大的项目。为了提高代码的质量,我们决定对每个函数强制执行返回值(错误代码)的处理。 GCC 支持关于函数返回值的警告,但是函数定义必须以以下标志开头。

static __attribute__((warn_unused_result)) ErrorCode test() { /* code goes here */ }

我想实现一个 bashscript 来解析整个源代码并发出警告,以防万一

__attribute__((warn_unused_result))

不见了。 请注意,所有需要这种修改的函数都会返回一个名为 ErrorCode 的类型。 您认为这可以通过 bash 脚本实现吗?

【问题讨论】:

  • 我建议你考虑把它写成一个 clang 插件。我写了一个插件,它分析符号的使用并在大约 350 行代码中警告无用的包含,所以它不是特别困难。

标签: c++ bash parsing


【解决方案1】:

也许您可以将sed 与正则表达式一起使用。以下对我尝试的几个测试文件有用:

sed -r "s/ErrorCode\s+\w+\s*(.*)\s*\{/__attribute__((warn_unused_result)) \0/g" test.cpp

如果您不熟悉正则表达式,则该模式基本上可以转换为:

错误代码、一些空格、一些字母数字(函数名称)、可能一些空格、左括号、任何内容(参数)、右括号、可能一些空格、打开大括号。

如果找到此模式,则以__attribute__((warn_unused_result)) 为前缀。请注意,这仅适用于将大括号始终与参数放在同一行并且函数声明中没有换行符的情况。

【讨论】:

  • 谢谢!我想我可以用这个。但是,它可能会产生许多错误。据我所知,这将自动替换指定的事件。这对我的口味来说有点太硬核了。是否有任何选项可以使命令仅返回可能发生替换的行和文件,以便我仍然可以决定是否执行?
  • 您可以grep -E "ErrorCode\s+\w+\s*(.*)\s*\{" 打印所有匹配正则表达式的行。
【解决方案2】:

我能想到的一个简单方法是通过ctags。您在所有源代码上创建一个标签文件,然后解析标签文件。但是,我不太确定标签文件的格式。如果标签代表一个函数,我在这里使用的变体(Exuberant Ctags 5.8)似乎在第四列中放置了一个“f”。所以在这种情况下,我会使用awk 过滤所有代表函数的标签,然后用grep 丢弃所有没有__attribute__((warn_unused_result)) 的行。

所以,简而言之,首先你要这样做

$ ctags **/*.c

这会在当前目录中创建一个名为“tags”的文件。该命令也可能是ctags-exuberant,具体取决于您的变体。 **/*.c 是一种可能在你的 shell 中工作的 glob 模式 - 如果不能,你必须以另一种方式提供你的源文件(查看 ctagsoptions)。

然后你过滤功能:

$ cat tags | awk -F '\t' '$4 == "f" {print $0}' | grep -v "__attribute__((warn_unused_result))"

【讨论】:

  • 我看了一下这个,看起来很有希望。但是据我所知,该方法并不关心函数的返回值类型。但是,我只想处理返回值 ErrorCode 的函数
  • 啊,对不起,我错过了你的问题。所以,那么你将不得不使用正则表达式。第一次尝试可能如下所示:cat tags | awk -F '\t' '$4 == "f" {print $3}' | grep '.*ErrorCode .*('。请注意,我让awk 只打印列$3,其中包含我的ctags 版本中的函数模式。但是,我不太确定这是否适用于特殊情况,例如,当返回类型与函数名称位于不同的行时。你应该玩一下它并控制结果。
【解决方案3】:

不,一般情况下是不可能的。 C++ 语法是我所知道的所有语言中最复杂的,在一般情况下,C++ 不能通过正则表达式进行解析。如果您将自己限制在非常狭窄的用途范围内,您可能会成功,但我不确定在您的情况下它有多可行。 我也不认为练习是值得的,因为有时忽略函数的结果是可以的。

【讨论】:

  • 它没有那么复杂,它是一种相当严格的语言。
  • 嗯,有些东西可能同时非常严格和非常复杂。就像我之前说的,一般 C++ 代码的正则表达式解析是不可能的。
  • 解析通过 ctags 创建的文件对我有用。还处理命名空间内联函数、模板...
猜你喜欢
  • 2017-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-30
相关资源
最近更新 更多