我该如何找到没有牙套的语句

How can I find if and for statements without braces?

本文关键字:语句 何找      更新时间:2023-10-16

我正在寻找一个项目,其中某些iffor语句没有其关联的括号,例如:

if(condition)
  single_line_statement;
for(int i=0;i<10;i++)
  single_line_statement;

我想找到这些语句!

但是,这是通过具有两种不同的括号样式的代码的存在而变得挑战的:

if(condition){
   stuff;
}

if(condition(a) && condition(b))
{
  stuff;
}

以及通过复杂的语句,例如(注意嵌套括号(:

for (auto const &x : y)
{
    for (auto const &m : ted.bob())
    {
        if (m.n(o) != 0)
        {
            p[q] = true;
        }
        r["s"].push_back(rn.t(u));
    }
}

我如何在没有括号的情况下找到iffor语句?

要解决这个问题,我创建了一个方便的花花公子脚本:

#!/bin/bash
find . -name '*.h' -o -name '*.cpp' | #Find all C++ files
  xargs pcregrep -A 1 -nHM 'b(?:if|for)s*((([^()]++|(?1))*))(?!.*{|.*n.*{)'

这会找到所有C 文件,然后使用Perl兼容的正则表达式研究每个文件的内容。此表达式使用递归(?1)iffor语句之后提取(condition),并且.字符匹配不是Newlines的字符,并且n常数以匹配新行。负面的(?!...)用于找到无括号的线。

正则表达式可以在此处在线测试。

输出看起来像这样:

./dir1/file1.cpp:845:        if (!a)
./dir1/file1.cpp-846-            std::cout << "a not found!" << std::endl;
--
./dir2/file2.cpp:20:    if (b == NULL)
./dir2/file2.cpp-21-        throw std::runtime_error("b was NULL");

由于脚本实际上并没有解析C ,因此在某些情况下会出现不良行为。例如,它将错过以下内容:

if (condition) // An example {
  statement;

此答案利用clang-tidy提供完整的检查,费用必须将clang-tidy纳入一个人的构建系统。

我使用 vera++在项目中验证该代码符合特定样式规则。

Vera: https://bitbucket.org/verateam/vera/wiki/Rules  
Rule: T019 Control structures should have complete curly-braced block of code