Merge pull request #6705 from davidhorstmann-arm/code-style-script-non-corrected

Add code style correction script
This commit is contained in:
Manuel Pégourié-Gonnard 2022-12-09 09:41:14 +01:00 committed by GitHub
commit 1a100b69a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 437 additions and 1 deletions

254
.uncrustify.cfg Normal file
View File

@ -0,0 +1,254 @@
# Configuration options for Uncrustify specifying the Mbed TLS code style.
#
# Note: The code style represented by this file has not yet been introduced
# to Mbed TLS.
#
# Copyright The Mbed TLS Contributors
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Line length options
# Wrap lines at 100 characters
code_width = 100
# Allow splitting long for statements between the condition statements
ls_for_split_full = true
# Allow splitting function calls between arguments
ls_func_split_full = true
input_tab_size = 4
# Spaces-only indentation
indent_with_tabs = 0
indent_columns = 4
# Indent 'case' 1 level from 'switch'
indent_switch_case = indent_columns
# Line-up strings broken by '\'
indent_align_string = true
# Braces on the same line (Egyptian-style braces)
nl_enum_brace = remove
nl_union_brace = remove
nl_struct_brace = remove
nl_do_brace = remove
nl_if_brace = remove
nl_for_brace = remove
nl_else_brace = remove
nl_while_brace = remove
nl_switch_brace = remove
# Braces on same line as keywords that follow them - 'else' and the 'while' in 'do {} while ()';
nl_brace_else = remove
nl_brace_while = remove
# Space before else on the same line
sp_brace_else = add
# If else is on the same line as '{', force exactly 1 space between them
sp_else_brace = force
# Functions are the exception and have braces on the next line
nl_fcall_brace = add
nl_fdef_brace = add
# Force exactly one space between ')' and '{' in statements
sp_sparen_brace = force
# At least 1 space around assignment
sp_assign = add
# Remove spaces around the preprocessor '##' token-concatenate
sp_pp_concat = ignore
# At least 1 space around '||' and '&&'
sp_bool = add
# But no space after the '!' operator
sp_not = remove
# No space after the bitwise-not '~' operator
sp_inv = remove
# No space after the addressof '&' operator
sp_addr = remove
# No space around the member '.' and '->' operators
sp_member = remove
# No space after the dereference '*' operator
sp_deref = remove
# No space after a unary negation '-'
sp_sign = remove
# No space between the '++'/'--' operator and its operand
sp_incdec = remove
# At least 1 space around comparison operators
sp_compare = add
# Remove spaces inside all kinds of parentheses:
# Remove spaces inside parentheses
sp_inside_paren = remove
# No spaces inside statement parentheses
sp_inside_sparen = remove
# No spaces inside cast parentheses '( char )x' -> '(char)x'
sp_inside_paren_cast = remove
# No spaces inside function parentheses
sp_inside_fparen = remove
# (The case where the function has no parameters/arguments)
sp_inside_fparens = remove
# No spaces inside the first parentheses in a function type
sp_inside_tparen = remove
# (Uncrustify >= 0.74.0) No spaces inside parens in for statements
sp_inside_for = remove
# Remove spaces between nested parentheses '( (' -> '(('
sp_paren_paren = remove
# (Uncrustify >= 0.74.0)
sp_sparen_paren = remove
# Remove spaces between ')' and adjacent '('
sp_cparen_oparen = remove
# (Uncrustify >= 0.73.0) space between 'do' and '{'
sp_do_brace_open = force
# (Uncrustify >= 0.73.0) space between '}' and 'while'
sp_brace_close_while = force
# At least 1 space before a '*' pointer star
sp_before_ptr_star = add
# Remove spaces between pointer stars
sp_between_ptr_star = remove
# No space after a pointer star
sp_after_ptr_star = remove
# But allow a space in the case of e.g. char * const x;
sp_after_ptr_star_qualifier = ignore
# Remove space after star in a function return type
sp_after_ptr_star_func = remove
# At least 1 space after a type in variable definition etc
sp_after_type = add
# Force exactly 1 space between a statement keyword (e.g. 'if') and an opening parenthesis
sp_before_sparen = force
# Remove a space before a ';'
sp_before_semi = remove
# (Uncrustify >= 0.73.0) Remove space before a semi in a non-empty for
sp_before_semi_for = remove
# (Uncrustify >= 0.73.0) Remove space in empty first statement of a for
sp_before_semi_for_empty = remove
# (Uncrustify >= 0.74.0) Remove space in empty middle statement of a for
sp_between_semi_for_empty = remove
# Add a space after a ';' (unless a comment follows)
sp_after_semi = add
# (Uncrustify >= 0.73.0) Add a space after a semi in non-empty for statements
sp_after_semi_for = add
# (Uncrustify >= 0.73.0) No space after final semi in empty for statements
sp_after_semi_for_empty = remove
# Remove spaces on the inside of square brackets '[]'
sp_inside_square = remove
# Must have at least 1 space after a comma
sp_after_comma = add
# Must not have a space before a comma
sp_before_comma = remove
# No space before the ':' in a case statement
sp_before_case_colon = remove
# No space after a cast - '(char) x' -> '(char)x'
sp_after_cast = remove
# No space between 'sizeof' and '('
sp_sizeof_paren = remove
# At least 1 space inside '{ }'
sp_inside_braces = add
# At least 1 space inside '{ }' in an enum
sp_inside_braces_enum = add
# At least 1 space inside '{ }' in a struct
sp_inside_braces_struct = add
# At least 1 space between a function return type and the function name
sp_type_func = add
# No space between a function name and its arguments/parameters
sp_func_proto_paren = remove
sp_func_def_paren = remove
sp_func_call_paren = remove
# No space between '__attribute__' and '('
sp_attribute_paren = remove
# No space between 'defined' and '(' in preprocessor conditions
sp_defined_paren = remove
# At least 1 space between a macro's name and its definition
sp_macro = add
sp_macro_func = add
# Force exactly 1 space between a '}' and the name of a typedef if on the same line
sp_brace_typedef = force
# At least 1 space before a '\' line continuation
sp_before_nl_cont = add
# At least 1 space around '?' and ':' in ternary statements
sp_cond_colon = add
sp_cond_question = add
# Space between #else/#endif and comment afterwards
sp_endif_cmt = add
# Remove newlines at the start of a file
nl_start_of_file = remove
# At least 1 newline at the end of a file
nl_end_of_file = add
nl_end_of_file_min = 1
# Add braces in single-line statements
mod_full_brace_do = add
mod_full_brace_for = add
mod_full_brace_if = add
mod_full_brace_while = add
# Remove parentheses from return statements
mod_paren_on_return = remove
# Disable removal of leading spaces in a multi-line comment if the first and
# last lines are the same length
cmt_multi_check_last = false

View File

@ -23,6 +23,7 @@
#ifndef MBEDTLS_CHECK_CONFIG_H
#define MBEDTLS_CHECK_CONFIG_H
/* *INDENT-OFF* */
/*
* We assume CHAR_BIT is 8 in many places. In practice, this is true on our
* target platforms, so not an issue, but let's just be extra sure.
@ -1099,4 +1100,5 @@
*/
typedef int mbedtls_iso_c_forbids_empty_translation_units;
/* *INDENT-ON* */
#endif /* MBEDTLS_CHECK_CONFIG_H */

View File

@ -713,4 +713,6 @@ usage_failure:
usage( );
return( EXIT_FAILURE );
}
#endif /* MBEDTLS_SHA256_C && MBEDTLS_MD_C && MBEDTLS_AES_C && MBEDTLS_CCM_C && MBEDTLS_PSA_CRYPTO_C && MBEDTLS_FS_IO */
#endif /* MBEDTLS_SHA256_C && MBEDTLS_MD_C &&
MBEDTLS_AES_C && MBEDTLS_CCM_C &&
MBEDTLS_PSA_CRYPTO_C && MBEDTLS_FS_IO */

158
scripts/code_style.py Executable file
View File

@ -0,0 +1,158 @@
#!/usr/bin/env python3
"""Check or fix the code style by running Uncrustify.
Note: The code style enforced by this script is not yet introduced to
Mbed TLS. At present this script will only be used to prepare for a future
change of code style.
"""
# Copyright The Mbed TLS Contributors
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
import io
import os
import subprocess
import sys
from typing import List
UNCRUSTIFY_SUPPORTED_VERSION = "0.75.1"
CONFIG_FILE = ".uncrustify.cfg"
UNCRUSTIFY_EXE = "uncrustify"
UNCRUSTIFY_ARGS = ["-c", CONFIG_FILE]
STDOUT_UTF8 = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
STDERR_UTF8 = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
def print_err(*args):
print("Error: ", *args, file=STDERR_UTF8)
def get_src_files() -> List[str]:
"""
Use git ls-files to get a list of the source files
"""
git_ls_files_cmd = ["git", "ls-files",
"*.[hc]",
"tests/suites/*.function",
"scripts/data_files/*.fmt"]
result = subprocess.run(git_ls_files_cmd, stdout=subprocess.PIPE, \
stderr=STDERR_UTF8, check=False)
if result.returncode != 0:
print_err("git ls-files returned: " + str(result.returncode))
return []
else:
src_files = str(result.stdout, "utf-8").split()
# Don't correct style for files in 3rdparty/
src_files = list(filter( \
lambda filename: not filename.startswith("3rdparty/"), \
src_files))
return src_files
def get_uncrustify_version() -> str:
"""
Get the version string from Uncrustify
"""
result = subprocess.run([UNCRUSTIFY_EXE, "--version"], \
stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=False)
if result.returncode != 0:
print_err("Could not get Uncrustify version:", str(result.stderr, "utf-8"))
return ""
else:
return str(result.stdout, "utf-8")
def check_style_is_correct(src_file_list: List[str]) -> bool:
"""
Check the code style and output a diff for each file whose style is
incorrect.
"""
style_correct = True
for src_file in src_file_list:
uncrustify_cmd = [UNCRUSTIFY_EXE] + UNCRUSTIFY_ARGS + [src_file]
subprocess.run(uncrustify_cmd, stdout=subprocess.PIPE, \
stderr=subprocess.PIPE, check=False)
# Uncrustify makes changes to the code and places the result in a new
# file with the extension ".uncrustify". To get the changes (if any)
# simply diff the 2 files.
diff_cmd = ["diff", "-u", src_file, src_file + ".uncrustify"]
result = subprocess.run(diff_cmd, stdout=subprocess.PIPE, \
stderr=STDERR_UTF8, check=False)
if len(result.stdout) > 0:
print(src_file + " - Incorrect code style.", file=STDOUT_UTF8)
print("File changed - diff:", file=STDOUT_UTF8)
print(str(result.stdout, "utf-8"), file=STDOUT_UTF8)
style_correct = False
else:
print(src_file + " - OK.", file=STDOUT_UTF8)
# Tidy up artifact
os.remove(src_file + ".uncrustify")
return style_correct
def fix_style_single_pass(src_file_list: List[str]) -> None:
"""
Run Uncrustify once over the source files.
"""
code_change_args = UNCRUSTIFY_ARGS + ["--no-backup"]
for src_file in src_file_list:
uncrustify_cmd = [UNCRUSTIFY_EXE] + code_change_args + [src_file]
subprocess.run(uncrustify_cmd, check=False, stdout=STDOUT_UTF8, \
stderr=STDERR_UTF8)
def fix_style(src_file_list: List[str]) -> int:
"""
Fix the code style. This takes 2 passes of Uncrustify.
"""
fix_style_single_pass(src_file_list)
fix_style_single_pass(src_file_list)
# Guard against future changes that cause the codebase to require
# more passes.
if not check_style_is_correct(src_file_list):
print("Code style still incorrect after second run of Uncrustify.")
return 1
else:
return 0
def main() -> int:
"""
Main with command line arguments.
"""
uncrustify_version = get_uncrustify_version().strip()
if UNCRUSTIFY_SUPPORTED_VERSION not in uncrustify_version:
print("Warning: Using unsupported Uncrustify version '" \
+ uncrustify_version + "' (Note: The only supported version" \
"is " + UNCRUSTIFY_SUPPORTED_VERSION + ")", file=STDOUT_UTF8)
src_files = get_src_files()
parser = argparse.ArgumentParser()
parser.add_argument('-f', '--fix', action='store_true', \
help='modify source files to fix the code style')
args = parser.parse_args()
if args.fix:
# Fix mode
return fix_style(src_files)
else:
# Check mode
if check_style_is_correct(src_files):
return 0
else:
return 1
if __name__ == '__main__':
sys.exit(main())

View File

@ -3662,6 +3662,26 @@ support_test_psa_compliance () {
[ "$ver_major" -eq 3 ] && [ "$ver_minor" -ge 10 ]
}
component_test_corrected_code_style () {
./scripts/code_style.py --fix
msg "build: make, default config (out-of-box), corrected code style"
make
msg "test: main suites make, default config (out-of-box), corrected code style"
make test
# Clean up code-style corrections
git checkout -- .
}
support_test_corrected_code_style() {
case $(uncrustify --version) in
*0.75.1*) true;;
*) false;;
esac
}
component_check_python_files () {
msg "Lint: Python scripts"
tests/scripts/check-python-files.sh