我在查找源文件的主要包含时遇到问题。但是一步一步。
档案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格式与z.h和z.C
一起定位BasedOnStyle: LLVM
Language: Cpp
IncludeIsMainRegex: '(_test)?$'
IncludeCategories:
- Regex: '^(<boost)'
Priority: 3
- Regex: '^<'
Priority: 4
- Regex: '.*'
Priority: 1
现在,测试:
$ clang-format 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 - &gt; 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格式在* .C文件上使用C ++样式格式吗? 或者用另一种方法找到main include来解决这个问题?
第二个问题/问题。 我们有时会将模板声明和定义拆分为template.h和templateImpl.h文件。如何强制clang-format将templateImpl.h视为源代码并将#include“template.h”作为主要包含?
此致
答案 0 :(得分:0)
在源文件扩展名为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;
}