C++代码格式化

C++代码格式化的工具有很多,比如astyle,clang-format。这里推荐使用clang-format,因为clang-format比astyle更强大,更灵活。但是clang-format也有很多缺点,不能在控制语句之间自动添加一个空白行,不能自动添加花括号等等;clang-format安装方式也有很多,比如源码编译安装,二进制包直接安装。这里选择使用二进制包直接安装。
 
 

安装


ubuntu18.04软件仓库中默认已经集成了clang-format工具,但是版本比较低,低版本的clang-format支持的功能比较少,这里安装12版本,12版本以及12版本以上支持GNU风格。

获取安装脚本

wget https://apt.llvm.org/llvm.sh

修改脚本权限

chmod 777 llvm.sh

执行脚本安装

[ 格式 ] ./llvm.sh 版本号

./llvm.sh 12

 

使用


官方提供了clang-format详细使用文档,地址:ClangFormat12.0.0

单文件格式化

clang-format 使用方式1
[ 格式 ] clang-format --style=<style_name> -i 需要格式化的文件

clang-format --style=gnu -i Server.cc

12版本支持的 style name 有:LLVM、Google、Chromium、Mozilla、WebKit、Microsoft、GNU

clang-format 使用方式2
[ 格式 ] clang-format --style=file -i 需要格式化的文件

clang-format --style=file -i Server.cc

这种方式,需要在使用clang-format命令的同级目录下创建一个.clang-format配置文件,配置文件内容参考官方使用文档。此处参考GNU格式化风格,做了一些调整。

---
Language:        Cpp
# BasedOnStyle:  GNU
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: None
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignEscapedNewlines: Right
AlignOperands:   Align
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortEnumsOnASingleLine: false
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
AttributeMacros:- __capability
BinPackArguments: true
BinPackParameters: true
BraceWrapping:AfterCaseLabel:  trueAfterClass:      trueAfterControlStatement: AlwaysAfterEnum:       trueAfterFunction:   trueAfterNamespace:  trueAfterObjCDeclaration: trueAfterStruct:     trueAfterUnion:      trueAfterExternBlock: trueBeforeCatch:     trueBeforeElse:      trueBeforeLambdaBody: falseBeforeWhile:     falseIndentBraces:    falseSplitEmptyFunction: trueSplitEmptyRecord: trueSplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: true
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit:     0
CommentPragmas:  '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 2
Cpp11BracedListStyle: false
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat:   false
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: false
ForEachMacros:- foreach- Q_FOREACH- BOOST_FOREACH
StatementAttributeLikeMacros:- Q_EMIT
IncludeBlocks:   Preserve
IncludeCategories:- Regex:           '^"(llvm|llvm-c|clang|clang-c)/'Priority:        2SortPriority:    0CaseSensitive:   false- Regex:           '^(<|"(gtest|gmock|isl|json)/)'Priority:        3SortPriority:    0CaseSensitive:   false- Regex:           '.*'Priority:        1SortPriority:    0CaseSensitive:   false
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentCaseLabels: false
IndentCaseBlocks: false
IndentGotoLabels: true
IndentPPDirectives: None
IndentExternBlock: AfterExternBlock
IndentRequires:  false
IndentWidth:     2
IndentWrappedFunctionNames: false
InsertTrailingCommas: None
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd:   ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PenaltyIndentedWhitespace: 0
PointerAlignment: Right
ReflowComments:  true
SortIncludes:    true
SortJavaStaticImport: Before
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: Always
SpaceAroundPointerQualifiers: Default
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles:  false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
BitFieldColonSpacing: Both
Standard:        Latest
StatementMacros:- Q_UNUSED- QT_REQUIRE_VERSION
TabWidth:        2
UseCRLF:         false
UseTab:          Never
WhitespaceSensitiveMacros:- STRINGIZE- PP_STRINGIZE- BOOST_PP_STRINGIZE- NS_SWIFT_NAME- CF_SWIFT_NAME
...
  • clang-format 只能格式化单个文件,如果需要一次性格式化多个文件,需要编写脚本;
  • -i 是将格式化的内容直接覆盖原文件;
  • --style 可以指定直接使用哪种代码风格,如gnu风格;也可以自己根据手动配置;

多文件格式化脚本

#!/bin/bash
CodePath=/root/ceph-14.2.22/src
LogPath=/root/clang.log
SubfixArray=("cc","cpp","c","h","hpp")function CodeFormat()
{for entry in `ls $1`doLogTime=$(date "+%Y.%m.%d %H:%M:%S")FilePath=$1/$entryif [ -f $FilePath ]thenif [[ ${SubfixArray[@]} =~ ${FilePath##*.} ]]thenecho "$LogTime $FilePath: file, do format..." | tee -a $LogPathclang-format --style=file -i $FilePathfielif [ -d $FilePath ]thenecho "$LogTime $FilePath: dir, do nothing..." | tee -a $LogPathCodeFormat $FilePathelseecho "$LogTime $FilePath: unknow, do nothing..." | tee -a $LogPathfidone
}function main()
{if [ -f $LogPath ]thencat /dev/null > $LogPathelsetouch $LogPathfiCodeFormat $CodePath
}main

[ 注 ] 这里不建议使用find命令搜索文件,在大型项目中,find命令搜索太慢了
 
 

本文链接:https://my.lmcjl.com/post/6483.html

展开阅读全文

4 评论

留下您的评论.