我试图将clang格式应用于现有的代码库,遇到了以下问题:
简化(和格式化(示例代码:
#define QUERY_BEGIN()
#define QUERY_NORESULT()
#define QUERY_END()
void foo()
{
int a = 0;
QUERY_BEGIN()
a = 1;
QUERY_NORESULT()
a = 2;
QUERY_END()
}
我设置了以下选项:
MacroBlockEnd: 'QUERY_END'
MacroBlockBegin: 'QUERY_BEGIN'
我想要实现的是宏部分的以下格式:
QUERY_BEGIN()
a = 1;
QUERY_NORESULT()
a = 2;
QUERY_END()
我的第一个猜测是将QUERY_NORESULT
设置为MacroBlockEnd
和MacroBlockBegin
,但这没有帮助。它产生以下格式:
QUERY_BEGIN()
a = 1;
QUERY_NORESULT
a = 2;
QUERY_END()
目前有没有一种方法可以实现如上所示的缩进?
- 坏消息:很抱歉,这在clang格式(7(的当前发布版本中不可用
- 好消息:有一个
StatementMacros
选项,它从clang format 8开始就可用(尚未发布,但您可以从源代码构建(
查看此提交:
摘要:有些宏在函数体中使用,实际上包含尾随分号:因此,它们应该自动后跟一行新行,而不是与下一行合并。例如,Qt的Q_UNUSED宏就是这样:
void foo(int a, int b) { Q_UNUSED(a) return b; }
此补丁通过引入一个新选项来指定语句宏列表来处理这些情况。这将重新使用foreach宏的现有系统,以确保不会对性能产生影响。
文档:
◆语句宏
std::vector clang::format::FormatStyle::StatementMacros应解释为完整语句的宏向量。
典型的宏是表达式,需要添加分号;有时情况并非如此,这允许clang格式了解此类情况。
例如:Q_UNUSED
文件Format.h 第1061行的定义
由clang::format::FormatTokenLexer::FormatToken Lexer((,clang:;format::getLLVMStyle((,llvm::yaml::MappingTraits<FormatStyle>::mapping((,运算符==((。
解决方案:
从源代码构建clang/等待llvm/crang8发布,然后将StatementMacros ['QUERY_BEGIN()', 'QUERY_NORESULT()', 'QUERY_END()']
放入您的.clang-format
中。
旧clang格式的解决方案
// clang-format off
void unformatted_code ;
// clang-format on
关闭此宏语句中的clang格式。
clang format 3.7在名称MacroBlockBegin
和MacroBlockEnd
下添加了对此的支持。这些配置选项比新样式的(Attribute|Statement|If|Foreach)Macros
选项(采用列表(更奇怪;旧样式的MacroBlock(Begin|End)
选项采用正则表达式,这意味着如果您有多个开始/结束宏,则必须像这样将它们粘合在一起:
MacroBlockBegin: '(FIRST_MACRO|SECOND_MACRO)'
不管怎样,对于您的确切输入,以及这个.clang格式的文件:
$ cat .clang-format
---
Language: Cpp
BasedOnStyle: LLVM
MacroBlockBegin: 'QUERY_BEGIN'
MacroBlockEnd: 'QUERY_END'
...
clang格式14.0.6产生以下格式化输出:
#define QUERY_BEGIN()
#define QUERY_NORESULT()
#define QUERY_END()
void foo() {
int a = 0;
QUERY_BEGIN()
a = 1;
QUERY_NORESULT()
a = 2;
QUERY_END()
}