diff --git a/scripts/check_format.sh b/scripts/check_format.sh index 7b43a6672..d0d73c23e 100755 --- a/scripts/check_format.sh +++ b/scripts/check_format.sh @@ -18,6 +18,19 @@ function version_lt() { [ $(echo -e "$1\n$2" | sort -V | head -1) != "$1" ] } +function array_contains_string() { + name="$1[@]" + array=("${!name}") + + for element in "${array[@]}"; do + if [ "$element" = "$2" ]; then + return $(true) + fi + done + + return $(false) +} + rc=0 echo -n "Checking file permissions..." @@ -195,6 +208,57 @@ else fi rm -f scripts/posix.log +echo -n "Checking for proper function naming conventions..." +failed_naming_conventions=false +changed_c_libs=() +declared_symbols=() + +# Build an array of all the modified C files. +mapfile -t changed_c_libs < <(git diff --name-only HEAD origin/master -- lib/**/*.c module/**/*.c) +# Matching groups are 1. qualifiers / return type. 2. function name 3. argument list / comments and stuff after that. +# Capture just the names of newly added (or modified) function definitions. +mapfile -t declared_symbols < <(git diff -U0 origin/master HEAD -- include/spdk*/*.h | sed -En 's/(^[+].*)(spdk[a-z,A-Z,0-9,_]*)(\(.*)/\2/p') + +for c_file in "${changed_c_libs[@]}"; do + lib_map_file="mk/spdk_blank.map" + defined_symbols=() + exported_symbols=() + if ls "$(dirname $c_file)"/*.map &> /dev/null; then + lib_map_file="$(ls "$(dirname $c_file)"/*.map)" + fi + # Matching groups are 1. leading +sign. 2, function name 3. argument list / anything after that. + # Capture just the names of newly added (or modified) functions that start with "spdk_" + mapfile -t defined_symbols < <(git diff -U0 origin/master HEAD -- $c_file | sed -En 's/(^[+])(spdk[a-z,A-Z,0-9,_]*)(\(.*)/\2/p') + # It's possible that we just modified a functions arguments so unfortunately we can't just look at changed lines in this function. + # matching groups are 1. All leading whitespace 2. function name. Capture just the symbol name. + mapfile -t exported_symbols < <(sed -En 's/(^[[:space:]]*)(spdk[a-z,A-Z,0-9,_]*);/\2/p' < $lib_map_file) + for defined_symbol in "${defined_symbols[@]}"; do + not_exported=true + not_declared=true + if array_contains_string exported_symbols $defined_symbol; then + not_exported=false + fi + + if array_contains_string declared_symbols $defined_symbol; then + not_declared=false + fi + + if $not_exported || $not_declared; then + if ! $failed_naming_conventions; then + echo " found naming convention errors." + fi + echo "function $defined_symbol starts with spdk_ which is reserved for public API functions." + echo "Please add this function to its corresponding map file and a public header or remove the spdk_ prefix." + failed_naming_conventions=true + rc=1 + fi + done +done + +if ! $failed_naming_conventions; then + echo " OK" +fi + echo -n "Checking #include style..." git grep -I -i --line-number "#include scripts/includes.log || true if [ -s scripts/includes.log ]; then