c++ - clang 格式:IncludeIsMainRegex 不起作用

标签 c++ include clang-format

我在为我的源文件查找主要包含时遇到问题。但是一步一步来。

文件 z.h

#include "test"
#include "azd"
#include <vector> 
#include <boost/something>
#include <map>

文件 z.C

#include "test"
#include "azd"
#include <vector>
#include <boost/something>
#include <map>
#include "z.h"

文件(部分).clang-format 与 z.h 和 z.C 位于一起

BasedOnStyle: LLVM
Language: Cpp
IncludeIsMainRegex: '(_test)?$'
IncludeCategories:
- Regex:    '^(<boost)'
  Priority: 3
- Regex:    '^<'
  Priority: 4
- Regex:    '.*'
  Priority: 1

现在,测试:

$ clang 格式 z.h

#include "azd"
#include "test"
#include <boost/something>
#include <map>
#include <vector>

在这里,一切看起来都很棒,包括按预期排序,但是

$ clang-format z.C

#include "azd"
#include "test"
#include "z.h"
#include <boost/something>
#include <map>
#include <vector>

这里,“a.z”在中间,虽然它应该被 '(_test)?$' 检测为主要包含。有趣的是,当我重命名 z.C -> z.cc 然后:

$ clang-format z.cc

#include "z.h"
#include "azd"
#include "test"
#include <boost/something>
#include <map>
#include <vector>

工作正常...

clang-format 似乎无法将 *.C 文件识别为 C++ 语言。我在 C++ 项目上工作,我无法将所有 *.C 文件重命名为 *.cc,所以请有人能告诉我如何强制 clang-format 在 *.C 文件上使用 C++ 样式格式吗? 或者用另一种方法找到主要包含来解决这个问题?

第二个问题。 我们有时将模板声明和定义拆分为 template.h 和 templateImpl.h 文件。如何强制 clang-format 将 templateImpl.h 视为源并将#include "template.h"作为主要包含?

问候

最佳答案

看起来唯一在您的情况下不起作用的是 IncludeIsMainRegex 选项,当源文件具有 *.C 扩展名时。

如果我没记错的话,这个选项目前只适用于扩展名为*.c、*.cc、*.cpp、*.c++、*.cxx 的源文件。

我的假设基于 clang (v7.0.0) 中的这段代码,文件 clang/lib/Tooling/Inclusions/HeaderIncludes.cpp:

IncludeCategoryManager::IncludeCategoryManager(const IncludeStyle &Style,
                                               StringRef FileName)
    : Style(Style), FileName(FileName) {
  FileStem = llvm::sys::path::stem(FileName);
  for (const auto &Category : Style.IncludeCategories)
    CategoryRegexs.emplace_back(Category.Regex, llvm::Regex::IgnoreCase);
  IsMainFile = FileName.endswith(".c") || FileName.endswith(".cc") ||
               FileName.endswith(".cpp") || FileName.endswith(".c++") ||
               FileName.endswith(".cxx") || FileName.endswith(".m") ||
               FileName.endswith(".mm");
}

int IncludeCategoryManager::getIncludePriority(StringRef IncludeName,
                                               bool CheckMainHeader) const {
  int Ret = INT_MAX;
  for (unsigned i = 0, e = CategoryRegexs.size(); i != e; ++i)
    if (CategoryRegexs[i].match(IncludeName)) {
      Ret = Style.IncludeCategories[i].Priority;
      break;
    }
  if (CheckMainHeader && IsMainFile && Ret > 0 && isMainHeader(IncludeName))
    Ret = 0;
  return Ret;
}

bool IncludeCategoryManager::isMainHeader(StringRef IncludeName) const {
  if (!IncludeName.startswith("\""))
    return false;
  StringRef HeaderStem =
      llvm::sys::path::stem(IncludeName.drop_front(1).drop_back(1));
  if (FileStem.startswith(HeaderStem) ||
      FileStem.startswith_lower(HeaderStem)) {
    llvm::Regex MainIncludeRegex(HeaderStem.str() + Style.IncludeIsMainRegex,
                                 llvm::Regex::IgnoreCase);
    if (MainIncludeRegex.match(FileStem))
      return true;
  }
  return false;
}

关于c++ - clang 格式:IncludeIsMainRegex 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45477581/

相关文章:

c++ - 为什么skb_transport_header计算不正确?

c++ - 使用 C++ 从 mp4 中提取音频到 mp3(不使用 args 执行 ffmpeg)

c - 包括类型定义,但不包括函数

c++ - clang-format (12.0.1) 的什么设置不会在 C++ 中的 R 前缀和原始字符串之间添加空格?

c++ - Qt 是否支持虚拟纯插槽?

c++ - 如何使用 GCC 编译器创建新的 OpenCV Mat 对象?

python - Django 模板 : Embed css from file

c - 错误 : linker command failed with exit code 1

c++ - 在 clang-format 中,惩罚有什么作用?

c++ - 格式化foreach宏的格式与使用clang-format的循环相同