mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2024-11-26 07:21:54 +00:00
Customize clang-format coding styles based on Mozilla template (#770)
Customize clang-format coding styles for C source files based on Mozilla template. To check whether the C source codes are well formatted: ``` bash $ cd ${wamr-root} $ clang-format --Werror --dry-run --style=file path/to/file ``` To format the C source codes in place ``` bash $ cd ${wamr_root} $ clang-format -i --style=file path/to/file ``` Signed-off-by: Wenyong Huang <wenyong.huang@intel.com>
This commit is contained in:
parent
9ef37dd781
commit
7191ecf880
146
.clang-format
146
.clang-format
|
@ -1,5 +1,6 @@
|
||||||
|
# using [clang-formt-12 options](https://releases.llvm.org/12.0.0/tools/clang/docs/ClangFormatStyleOptions.html)
|
||||||
RawStringFormats:
|
RawStringFormats:
|
||||||
- Language: Cpp
|
- Language: Cpp
|
||||||
Delimiters:
|
Delimiters:
|
||||||
- c
|
- c
|
||||||
- C
|
- C
|
||||||
|
@ -13,35 +14,23 @@ RawStringFormats:
|
||||||
- h
|
- h
|
||||||
- hpp
|
- hpp
|
||||||
CanonicalDelimiter: ''
|
CanonicalDelimiter: ''
|
||||||
BasedOnStyle: google
|
BasedOnStyle: Mozilla
|
||||||
- Language: TextProto
|
|
||||||
Delimiters:
|
|
||||||
- pb
|
|
||||||
- PB
|
|
||||||
- proto
|
|
||||||
- PROTO
|
|
||||||
EnclosingFunctions:
|
|
||||||
- EqualsProto
|
|
||||||
- EquivToProto
|
|
||||||
- PARSE_PARTIAL_TEXT_PROTO
|
|
||||||
- PARSE_TEST_PROTO
|
|
||||||
- PARSE_TEXT_PROTO
|
|
||||||
- ParseTextOrDie
|
|
||||||
- ParseTextProtoOrDie
|
|
||||||
CanonicalDelimiter: ''
|
|
||||||
BasedOnStyle: google
|
|
||||||
|
|
||||||
Language: Cpp
|
Language: Cpp
|
||||||
BasedOnStyle: Mozilla
|
BasedOnStyle: Mozilla
|
||||||
|
# 6.1
|
||||||
IndentWidth: 4
|
IndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
# 6.2
|
||||||
|
TabWidth: 4
|
||||||
|
UseTab: Never
|
||||||
|
# 6.3
|
||||||
|
ColumnLimit: 80
|
||||||
|
# 6.9
|
||||||
AlignAfterOpenBracket: Align
|
AlignAfterOpenBracket: Align
|
||||||
AllowAllArgumentsOnNextLine: false
|
|
||||||
AlignConsecutiveMacros: true
|
|
||||||
AllowShortBlocksOnASingleLine: true
|
|
||||||
AlwaysBreakAfterReturnType: All
|
|
||||||
BinPackArguments: true
|
BinPackArguments: true
|
||||||
BinPackParameters: false
|
BinPackParameters: true
|
||||||
BreakBeforeBinaryOperators: NonAssignment
|
# 6.10
|
||||||
BreakBeforeBraces: Custom
|
BreakBeforeBraces: Custom
|
||||||
BraceWrapping:
|
BraceWrapping:
|
||||||
AfterCaseLabel: true
|
AfterCaseLabel: true
|
||||||
|
@ -60,104 +49,13 @@ BraceWrapping:
|
||||||
SplitEmptyFunction: true
|
SplitEmptyFunction: true
|
||||||
SplitEmptyRecord: false
|
SplitEmptyRecord: false
|
||||||
SplitEmptyNamespace: true
|
SplitEmptyNamespace: true
|
||||||
ColumnLimit: 79
|
# 6.27
|
||||||
ContinuationIndentWidth: 2
|
BreakBeforeBinaryOperators: NonAssignment
|
||||||
DerivePointerAlignment: false
|
|
||||||
IncludeBlocks: Regroup
|
# additional
|
||||||
IncludeCategories:
|
AlignEscapedNewlines: Left
|
||||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
Priority: 2
|
AllowAllArgumentsOnNextLine: false
|
||||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
|
||||||
Priority: 1
|
|
||||||
- Regex: ".*"
|
|
||||||
Priority: 3
|
|
||||||
IndentPPDirectives: None
|
|
||||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
|
||||||
NamespaceIndentation: None
|
|
||||||
PointerAlignment: Right
|
PointerAlignment: Right
|
||||||
ReflowComments: false
|
SpaceAroundPointerQualifiers: After
|
||||||
SortIncludes: false
|
SortIncludes: false
|
||||||
Standard: Auto
|
|
||||||
StatementMacros:
|
|
||||||
- Q_UNUSED
|
|
||||||
- QT_REQUIRE_VERSION
|
|
||||||
|
|
||||||
# AccessModifierOffset: -2
|
|
||||||
# AlignConsecutiveAssignments: false
|
|
||||||
# AlignConsecutiveDeclarations: false
|
|
||||||
# AlignEscapedNewlines: Right
|
|
||||||
# AlignOperands: true
|
|
||||||
# AlignTrailingComments: true
|
|
||||||
# AllowAllConstructorInitializersOnNextLine: true
|
|
||||||
# AllowAllParametersOfDeclarationOnNextLine: false
|
|
||||||
# AllowShortCaseLabelsOnASingleLine: false
|
|
||||||
# AllowShortFunctionsOnASingleLine: Inline
|
|
||||||
# AllowShortLambdasOnASingleLine: All
|
|
||||||
# AllowShortIfStatementsOnASingleLine: Never
|
|
||||||
# AllowShortLoopsOnASingleLine: false
|
|
||||||
# AlwaysBreakAfterDefinitionReturnType: TopLevel
|
|
||||||
# AlwaysBreakAfterReturnType: TopLevel
|
|
||||||
# AlwaysBreakBeforeMultilineStrings: false
|
|
||||||
# AlwaysBreakTemplateDeclarations: Yes
|
|
||||||
# BreakBeforeInheritanceComma: false
|
|
||||||
# BreakInheritanceList: BeforeComma
|
|
||||||
# BreakBeforeTernaryOperators: true
|
|
||||||
# BreakConstructorInitializersBeforeComma: false
|
|
||||||
# BreakConstructorInitializers: BeforeComma
|
|
||||||
# BreakAfterJavaFieldAnnotations: false
|
|
||||||
# BreakStringLiterals: true
|
|
||||||
# CommentPragmas: '^ IWYU pragma:'
|
|
||||||
# CompactNamespaces: false
|
|
||||||
# ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
|
||||||
# ConstructorInitializerIndentWidth: 2
|
|
||||||
# Cpp11BracedListStyle: false
|
|
||||||
# DisableFormat: false
|
|
||||||
# ExperimentalAutoDetectBinPacking: false
|
|
||||||
# FixNamespaceComments: false
|
|
||||||
# ForEachMacros:
|
|
||||||
# - foreach
|
|
||||||
# - Q_FOREACH
|
|
||||||
# - BOOST_FOREACH
|
|
||||||
# IncludeIsMainRegex: '(Test)?$'
|
|
||||||
# IndentCaseLabels: true
|
|
||||||
# IndentWrappedFunctionNames: false
|
|
||||||
# JavaScriptQuotes: Leave
|
|
||||||
# JavaScriptWrapImports: true
|
|
||||||
# KeepEmptyLinesAtTheStartOfBlocks: true
|
|
||||||
# MacroBlockBegin: ''
|
|
||||||
# MacroBlockEnd: ''
|
|
||||||
# MaxEmptyLinesToKeep: 1
|
|
||||||
# ObjCBinPackProtocolList: Auto
|
|
||||||
# ObjCBlockIndentWidth: 2
|
|
||||||
# ObjCSpaceAfterProperty: true
|
|
||||||
# ObjCSpaceBeforeProtocolList: false
|
|
||||||
# PenaltyBreakAssignment: 2
|
|
||||||
# PenaltyBreakBeforeFirstCallParameter: 19
|
|
||||||
# PenaltyBreakComment: 300
|
|
||||||
# PenaltyBreakFirstLessLess: 120
|
|
||||||
# PenaltyBreakString: 1000
|
|
||||||
# PenaltyBreakTemplateDeclaration: 10
|
|
||||||
# PenaltyExcessCharacter: 1000000
|
|
||||||
# PenaltyReturnTypeOnItsOwnLine: 200
|
|
||||||
# SortIncludes: true
|
|
||||||
# SortUsingDeclarations: true
|
|
||||||
# SpaceAfterCStyleCast: false
|
|
||||||
# SpaceAfterLogicalNot: false
|
|
||||||
# SpaceAfterTemplateKeyword: false
|
|
||||||
# SpaceBeforeAssignmentOperators: true
|
|
||||||
# SpaceBeforeCpp11BracedList: false
|
|
||||||
# SpaceBeforeCtorInitializerColon: true
|
|
||||||
# SpaceBeforeInheritanceColon: true
|
|
||||||
# SpaceBeforeParens: ControlStatements
|
|
||||||
# SpaceBeforeRangeBasedForLoopColon: true
|
|
||||||
# SpaceInEmptyParentheses: false
|
|
||||||
# SpacesBeforeTrailingComments: 1
|
|
||||||
# SpacesInAngles: false
|
|
||||||
# SpacesInContainerLiterals: true
|
|
||||||
# SpacesInCStyleCastParentheses: false
|
|
||||||
# SpacesInParentheses: false
|
|
||||||
# SpacesInSquareBrackets: false
|
|
||||||
# TabWidth: 4
|
|
||||||
# UseTab: Never
|
|
||||||
# ...
|
|
||||||
|
|
||||||
|
|
16
.clang-tidy
Normal file
16
.clang-tidy
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# refer to https://clang.llvm.org/extra/clang-tidy/checks/list.html
|
||||||
|
|
||||||
|
Checks: '-*, readability-identifier-naming, clang-analyzer-core.*,'
|
||||||
|
WarningsAsErrors: '-*'
|
||||||
|
HeaderFilterRegex: ''
|
||||||
|
FormatStyle: file
|
||||||
|
InheritParentConfig: false
|
||||||
|
AnalyzeTemporaryDtors: false
|
||||||
|
User: wamr
|
||||||
|
CheckOptions:
|
||||||
|
- key: readability-identifier-naming.VariableCase
|
||||||
|
value: lower_case
|
||||||
|
- key: readability-identifier-naming.ParameterCase
|
||||||
|
value: lower_case
|
||||||
|
- key: readability-identifier-naming.MacroDefinitionCase
|
||||||
|
value: UPPER_CASE
|
263
ci/run_pre_commit_check.py
Normal file
263
ci/run_pre_commit_check.py
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
#
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import pathlib
|
||||||
|
import queue
|
||||||
|
import re
|
||||||
|
import shlex
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
CLANG_CMD = "clang-13"
|
||||||
|
CLANG_CPP_CMD = "clang-cpp-13"
|
||||||
|
CLANG_FORMAT_CMD = "clang-format-13"
|
||||||
|
CLANG_TIDY_CMD = "clang-tidy-13"
|
||||||
|
CMAKE_CMD = "cmake"
|
||||||
|
|
||||||
|
|
||||||
|
# glob style patterns
|
||||||
|
EXCLUDE_PATHS = [
|
||||||
|
"**/.git/",
|
||||||
|
"**/.github/",
|
||||||
|
"**/.vscode/",
|
||||||
|
"**/assembly-script/",
|
||||||
|
"**/build/",
|
||||||
|
"**/build-scripts/",
|
||||||
|
"**/ci/",
|
||||||
|
"**/core/deps/",
|
||||||
|
"**/doc/",
|
||||||
|
"**/samples/workload/",
|
||||||
|
"**/test-tools/",
|
||||||
|
"**/wamr-sdk/",
|
||||||
|
"**/wamr-dev/",
|
||||||
|
"**/wamr-dev-simd/",
|
||||||
|
]
|
||||||
|
|
||||||
|
C_SUFFIXES = [".c", ".h"]
|
||||||
|
|
||||||
|
VALID_DIR_NAME = r"([a-zA-Z0-9]+\-*)+[a-zA-Z0-9]*"
|
||||||
|
VALID_FILE_NAME = r"\.?([a-zA-Z0-9]+\_*)+[a-zA-Z0-9]*\.*\w*"
|
||||||
|
|
||||||
|
|
||||||
|
def locate_command(command):
|
||||||
|
if not shutil.which(command):
|
||||||
|
print(f"Command '{command}'' not found")
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def is_excluded(path):
|
||||||
|
for exclude_path in EXCLUDE_PATHS:
|
||||||
|
if path.match(exclude_path):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def pre_flight_check(root):
|
||||||
|
def check_clang_foramt(root):
|
||||||
|
if not locate_command(CLANG_FORMAT_CMD):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Quick syntax check for .clang-format
|
||||||
|
try:
|
||||||
|
subprocess.check_call(
|
||||||
|
shlex.split(f"{CLANG_FORMAT_CMD} --dump-config"), cwd=root
|
||||||
|
)
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
print(f"Might have a typo in .clang-format")
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def check_clang_tidy(root):
|
||||||
|
if not locate_command(CLANG_TIDY_CMD):
|
||||||
|
return False
|
||||||
|
|
||||||
|
if (
|
||||||
|
not locate_command(CLANG_CMD)
|
||||||
|
or not locate_command(CLANG_CPP_CMD)
|
||||||
|
or not locate_command(CMAKE_CMD)
|
||||||
|
):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Quick syntax check for .clang-format
|
||||||
|
try:
|
||||||
|
subprocess.check_call(
|
||||||
|
shlex.split("{CLANG_TIDY_CMD} --dump-config"), cwd=root
|
||||||
|
)
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
print(f"Might have a typo in .clang-tidy")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# looking for compile command database
|
||||||
|
return True
|
||||||
|
|
||||||
|
def check_aspell(root):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return check_clang_foramt(root) and check_clang_tidy(root) and check_aspell(root)
|
||||||
|
|
||||||
|
|
||||||
|
def run_clang_format(file_path, root):
|
||||||
|
try:
|
||||||
|
subprocess.check_call(
|
||||||
|
shlex.split(
|
||||||
|
f"{CLANG_FORMAT_CMD} --style=file --Werror --dry-run {file_path}"
|
||||||
|
),
|
||||||
|
cwd=root,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
print(f"{file_path} failed the check of {CLANG_FORMAT_CMD}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def generate_compile_commands(compile_command_database, root):
|
||||||
|
CMD = f"{CMAKE_CMD} -DCMAKE_C_COMPILER={shutil.which(CLANG_CMD)} -DCMAKE_CXX_COMPILER={shutil.which(CLANG_CPP_CMD)} -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .."
|
||||||
|
|
||||||
|
try:
|
||||||
|
linux_mini_build = root.joinpath("product-mini/platforms/linux/build").resolve()
|
||||||
|
linux_mini_build.mkdir(exist_ok=True)
|
||||||
|
if subprocess.check_call(shlex.split(CMD), cwd=linux_mini_build):
|
||||||
|
return False
|
||||||
|
|
||||||
|
wamrc_build = root.joinpath("wamr-compiler/build").resolve()
|
||||||
|
wamrc_build.mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
if subprocess.check_call(shlex.split(CMD), cwd=wamrc_build):
|
||||||
|
return False
|
||||||
|
|
||||||
|
with open(linux_mini_build.joinpath("compile_commands.json"), "r") as f:
|
||||||
|
iwasm_compile_commands = json.load(f)
|
||||||
|
|
||||||
|
with open(wamrc_build.joinpath("compile_commands.json"), "r") as f:
|
||||||
|
wamrc_compile_commands = json.load(f)
|
||||||
|
|
||||||
|
all_compile_commands = iwasm_compile_commands + wamrc_compile_commands
|
||||||
|
# TODO: duplication items ?
|
||||||
|
with open(compile_command_database, "w") as f:
|
||||||
|
json.dump(all_compile_commands, f)
|
||||||
|
|
||||||
|
return True
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def run_clang_tidy(file_path, root):
|
||||||
|
# preparatoin
|
||||||
|
compile_command_database = pathlib.Path("/tmp/compile_commands.json")
|
||||||
|
if not compile_command_database.exists() and not generate_compile_commands(
|
||||||
|
compile_command_database, root
|
||||||
|
):
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
if subprocess.check_call(
|
||||||
|
shlex.split(f"{CLANG_TIDY_CMD} -p={compile_command_database} {file_path}"),
|
||||||
|
cwd=root,
|
||||||
|
):
|
||||||
|
print(f"{file_path} failed the check of {CLANG_TIDY_CMD}")
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
print(f"{file_path} failed the check of {CLANG_TIDY_CMD}")
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def run_aspell(file_path, root):
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def check_dir_name(path, root):
|
||||||
|
# since we don't want to check the path beyond root.
|
||||||
|
# we hope "-" only will be used in a dir name as separators
|
||||||
|
return all(
|
||||||
|
[
|
||||||
|
re.match(VALID_DIR_NAME, path_part)
|
||||||
|
for path_part in path.relative_to(root).parts
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def check_file_name(path):
|
||||||
|
# since we don't want to check the path beyond root.
|
||||||
|
# we hope "_" only will be used in a file name as separators
|
||||||
|
return re.match(VALID_FILE_NAME, path.name) is not None
|
||||||
|
|
||||||
|
|
||||||
|
def run_pre_commit_check(path, root=None):
|
||||||
|
path = path.resolve()
|
||||||
|
if path.is_dir():
|
||||||
|
if not check_dir_name(path, root):
|
||||||
|
print(f"{path} is not a valid directory name")
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
if path.is_file():
|
||||||
|
if not check_file_name(path):
|
||||||
|
print(f"{path} is not a valid file name")
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not path.suffix in C_SUFFIXES:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return (
|
||||||
|
run_clang_format(path, root)
|
||||||
|
and run_clang_tidy(path, root)
|
||||||
|
and run_aspell(path, root)
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f"{path} neither a file nor a directory")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
wamr_root = pathlib.Path(__file__).parent.joinpath("..").resolve()
|
||||||
|
|
||||||
|
if not pre_flight_check(wamr_root):
|
||||||
|
return False
|
||||||
|
|
||||||
|
invalid_file, invalid_directory = 0, 0
|
||||||
|
|
||||||
|
# in order to skip exclude directories ASAP,
|
||||||
|
# will not yield Path.
|
||||||
|
# since we will create every object
|
||||||
|
dirs = queue.Queue()
|
||||||
|
dirs.put(wamr_root)
|
||||||
|
while not dirs.empty():
|
||||||
|
qsize = dirs.qsize()
|
||||||
|
while qsize:
|
||||||
|
current_dir = dirs.get()
|
||||||
|
|
||||||
|
for path in current_dir.iterdir():
|
||||||
|
path = path.resolve()
|
||||||
|
|
||||||
|
if path.is_symlink():
|
||||||
|
continue
|
||||||
|
|
||||||
|
if path.is_dir() and not is_excluded(path):
|
||||||
|
invalid_directory += (
|
||||||
|
0 if run_pre_commit_check(path, wamr_root) else 1
|
||||||
|
)
|
||||||
|
dirs.put(path)
|
||||||
|
|
||||||
|
if not path.is_file():
|
||||||
|
continue
|
||||||
|
|
||||||
|
invalid_file += 0 if run_pre_commit_check(path) else 1
|
||||||
|
|
||||||
|
else:
|
||||||
|
qsize -= 1
|
||||||
|
|
||||||
|
print(f"invalid_directory={invalid_directory}, invalid_file={invalid_file}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
Reference in New Issue
Block a user