如何以 clang 格式为外部标头创建类别
How to create category for external headers in clang-format?
我想配置 clang 格式以C++包含的标头进行排序,如下所示:
- 主标头(与当前 cpp 文件相关联(,
- 通过 " 包含的本地标头,
- 通过<>包含的其他标头,
- 来自特定外部库的标头(例如 boost、catch2(,
- 系统/标准标头。
我在 macOS 上使用 clang 格式的 8.0.0。我当前的配置(仅与包含相关的代码片段(如下:
SortIncludes: true
IncludeBlocks: Regroup
IncludeCategories:
# Headers in <> without extension.
- Regex: '<([A-Za-z0-9/-_])+>'
Priority: 4
# Headers in <> from specific external libraries.
- Regex: '<((bboostb)|(bcatch2b))/([A-Za-z0-9./-_])+>'
Priority: 3
# Headers in <> with extension.
- Regex: '<([A-Za-z0-9./-_])+>'
Priority: 2
# Headers in "" with extension.
- Regex: '"([A-Za-z0-9./-_])+"'
Priority: 1
在此配置中,我假设系统/标准标头没有扩展名。它不适用于 UNIX/POSIX 标头。自动检测主标头并分配优先级 0。到目前为止,除了外部库的类别外,一切似乎都按预期工作。看起来 clang 格式将其分配给优先级 2。
预期成果:
#include "test.h"
#include <allocator/region.hpp>
#include <page.hpp>
#include <page_allocator.hpp>
#include <test_utils.hpp>
#include <utils.hpp>
#include <zone_allocator.hpp>
#include <catch2/catch.hpp> // <--------
#include <array>
#include <cmath>
#include <cstring>
#include <map>
实际结果:
#include "test.h"
#include <allocator/region.hpp>
#include <catch2/catch.hpp> // <--------
#include <page.hpp>
#include <page_allocator.hpp>
#include <test_utils.hpp>
#include <utils.hpp>
#include <zone_allocator.hpp>
#include <array>
#include <cmath>
#include <cstring>
#include <map>
如何配置优先级 3 以获得预期的结果?
我通过使用和修改此选项的 clang 格式文档中的示例来让它工作:
SortIncludes: true
IncludeBlocks: Regroup
IncludeCategories:
# Headers in <> without extension.
- Regex: '<([A-Za-z0-9Q/-_E])+>'
Priority: 4
# Headers in <> from specific external libraries.
- Regex: '<(catch2|boost)/'
Priority: 3
# Headers in <> with extension.
- Regex: '<([A-Za-z0-9.Q/-_E])+>'
Priority: 2
# Headers in "" with extension.
- Regex: '"([A-Za-z0-9.Q/-_E])+"'
Priority: 1
特别是,我将优先级 3 正则表达式更改为更像原始示例:
'^(<|"(gtest|gmock|isl|json)/)'
此外,我添加了 \Q 和 \E 修饰符以避免 Julio 提到的问题。现在一切都按预期工作。但是我仍然不知道为什么问题帖子中的解决方案不起作用。
问题是Clan格式使用POSIX ERE正则表达式。这些不支持单词边界。
所以<catch2/catch.hpp>
永远无法匹配第二条规则。然后,为匹配的第三个规则计算相同的字符串。
如果它符合第二条规则,它就会停在那里,但由于它没有,它继续下一个规则。
只需删除正则表达式上的所有b
即可。删除它们是安全的,因为您已经有单词边界:在左侧你有<
,在右侧你有/
所以即使你可以使用单词boudaries,它也毫无用处。
- Regex: '<(boost|catch2)/([A-Za-z0-9./-_])+>'
Priority: 3
注意:请记住,[]
内部的-
应用反斜杠转义,除非将其放置在最后一个位置。那是因为它用于范围。所以当你写[A-Za-z0-9./-_]
时,你的意思是A-Za-z0-9.
或范围从/
到_
,你可能不是故意的。
如果您遵循将所有外部标头放在 <>
中并将本地标头放在 ""
中的约定,则可以使用以下配置文件。它将根据标题的类别对标题进行很好的排序:
.clang-format
SortIncludes: CaseSensitive
IncludeBlocks: Regroup
IncludeCategories:
# Specific external headers in <> to put first
- Regex: '<(catch2|gtest).*>'
Priority: 1
# External headers in <> with extension or /
- Regex: '<[-w/-_]+[./][-w/-_]+>'
Priority: 2
# Standard headers in <>
- Regex: '<[-w/-_]+>'
Priority: 3
# Local headers in ""
- Regex: '"[-w/-_]*"'
Priority: 4
这将像这样对包含进行排序:
#include <catch2/catch_test_macros.hpp>
#include <Eigen/Core>
#include <fmt/format.h>
#include <yaml-cpp/yaml.h>
#include <algorithm>
#include <cmath>
#include <concepts>
#include <filesystem>
#include "../some_other_local_header"
#include "./some_local_header.hpp"
- 在函数内创建的对象的范围 - 如果在函数外部存储和访问引用,它们是否有效?
- C++:在"try"外部创建的类型会导致错误,但在内部不会
- 当外部源代码中发生异常时,无法正确使用自创建的小型转储文件的堆栈跟踪
- 创建类时已定义的未解析外部符号
- 电子内部或外部方法创建自己的右键单击上下文菜单 - Windows
- 如何访问在 if 语句内、外部创建的指针
- 无法使用外部QOpenGLWidget创建的上下文
- 如何创建外部不可修改的变量
- 链接到外部库的G 创建了未定义的参考
- 在Qt中创建二进制外部资源文件
- 通过使用新操作员创建对象会导致未解决的外部符号错误C FTGL
- LNK2019未解析的外部符号.创建二叉树
- 在 CUDA 设备代码和主机代码中创建模板类对象时未解析的外部函数
- C++在外部dll上的dilogex控件上创建hdc
- 创建对象时未解析的外部符号
- 在C++中创建静态实例的未解析外部
- 如何在具有多态性的函数外部创建对象
- 创建无需任何外部执行即可连续侦听的守护程序文件
- 从类中创建一个信号来调用外部函数
- 如何创建外部数组模板