blob: 59cba101ea22d4922eadfcddf49479ba3395376c [file] [log] [blame]
Antonio de Angelis9ba31c32024-12-13 23:42:15 +00001#!/usr/bin/env bash
2
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +01003#-------------------------------------------------------------------------------
Antonio de Angelis9ba31c32024-12-13 23:42:15 +00004# Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +01005#
6# SPDX-License-Identifier: BSD-3-Clause
7#
8#-------------------------------------------------------------------------------
9
10##
11##@file
12##@brief Execute checkpatch
13##
14##This bash script can be used to execute checkpatch for the tf-m project.
15##The script can be started with -h to give help on usage.
16##
17
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010018##@var SKIP_PATHS
19##@brief Folders and files to not be analysed by checkpatch
20##
21##This variable specifies the list of directories which shall not be analysed
22##by checkpatch.
23##This is a colon (:) separated list.
24##
25#This is needed for Doxygen for now.
26#!string SKIP_PATHS;
Antonio de Angelis732d2842024-09-19 16:58:54 +010027SKIP_PATHS='./build-\*:./platform/\*:*/tz_\*:./lib/\*:./platform/ext/\*:./bl2/ext/\*:./docs/\*:./tools/\*:./interface/include/mbedtls/\*:./interface/include/psa/\*'
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010028
29##@var TFM_DIRECTORY_NAME
30##@brief Default path to tf-m source code.
31##
32#This is needed for Doxygen for now.
33#!path TFM_DIRECTORY_NAME;
34TFM_DIRECTORY_NAME="./"
35
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010036##@var CHECKPATCH_PATH_DEF
37##@brief Default Path to checkpatch executable.
38##
39#This is needed for Doxygen for now.
40#!path CHECKPATCH_PATH_DEF;
41CHECKPATCH_PATH_DEF=$(readlink -f $(dirname "$0")"/checkpatch")
42
43##@var CHECKPATCH_PATH
44##@brief Path to checkpatch executable.
45##
46## Checkpatch path can be overriden by user argument. Initialized with Default
47## value of ./checkpatch
48##
49#This is needed for Doxygen for now.
50#!path CHECKPATCH_PATH;
51CHECKPATCH_PATH=$CHECKPATCH_PATH_DEF
52
53##@fn usage(void)
54##@brief Print help text on usage.
55##@returns n/a
56##
57#This is needed for Doxygen for now.
58#!void usage(void){};
59usage() {
Antonio de Angelis9eb15a82024-12-13 10:49:53 +000060 echo "Usage: $(basename -- "$0") [-v] [-h] [-d <TF-M dir>] [-f <output_filename>] [-p <number>]"
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010061 echo " -v, Verbose output"
62 echo " -h, Script help"
63 echo " -d, <TF-M dir>, TF-M directory"
64 echo " -f, <output_filename>, Output filename"
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010065 echo " -l <number>, Check only the last <number> commits (HEAD~<number>)."
Dean Birch62c4f082020-01-17 16:13:26 +000066 echo " -p <path>, Provide location of directory containing checkpatch."
67 echo " -r, Print raw output. Implies verbose."
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010068 echo -e "\nNOTE: make sure checkpatch is located in '$CHECKPATCH_PATH'"
69}
70
71##@fn app_err(void)
72##@brief Print error massage.
73##@returns n/a
74##
75#This is needed for Doxygen for now.
76#!void app_err(void){};
77app_err() {
Antonio de Angelis9ba31c32024-12-13 23:42:15 +000078 echo "run-checkpatch.sh($LINENO): Error: "$1 >&2
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010079}
80
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010081##@fn check_tree()
82##@brief Run checkpatch in directory tree checking mode
83##@returns status code
84##
85##Execute checkpatch to check the full content of all source files under the
86##directory specified in \ref TFM_DIRECTORY_NAME. Directory content specified in
87##\ref SKIP_PATHS will be excluded.
88##This function uses xargs to execute multiple checkpatch instances in parallel.
89##
90#This is needed for Doxygen for now.
91#!void check_tree(){};
92check_tree() {
93 # Find all files to execute checkpatch on
94 FIND_CMD="find $TFM_DIRECTORY_NAME -name '*.[ch]' -a -not \( -path "${SKIP_PATHS//:/ -o -path }" \)"
Antonio de Angelis9ba31c32024-12-13 23:42:15 +000095 echo "run-checkpatch.sh($LINENO): Scanning "$TFM_DIRECTORY_NAME" dir to find all .c and .h files to check..."
96 # Modify checkpatch command line to make checkpatch work on files.
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010097 CHECKPATCH_CMD="$CHECKPATCH_CMD -f "
98 if [ $VERBOSE -eq 1 ]; then
99 eval "$FIND_CMD" | xargs -n 1 -i -P 8 $CHECKPATCH_CMD {} |tee -a "$OUTPUT_FILE_PATH"
Dean Birch62c4f082020-01-17 16:13:26 +0000100 RETURN_CODE=${PIPESTATUS[1]}
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100101 else
102 eval "$FIND_CMD" | xargs -n 1 -i -P 8 $CHECKPATCH_CMD {} >> $OUTPUT_FILE_PATH
Dean Birch62c4f082020-01-17 16:13:26 +0000103 RETURN_CODE=${PIPESTATUS[1]}
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100104 fi
105}
106
107##@fn check_diff()
108##@brief Run checkpatch in git diff mode.
109##@returns status code
110##
111##Execute checkpatch to check the last N (\ref CHECK_LAST_COMMITS) commits of
112##the branch checked out at directory specified in \ref TFM_DIRECTORY_NAME.
113##Directory content specified in \ref SKIP_PATHS will be excluded.
114##
115#This is needed for Doxygen for now.
116#!void check_diff(){};
117check_diff() {
118 BASE_COMMIT="HEAD~$CHECK_LAST_COMMITS"
119 #use find to limit diff content to the same set of files as when checking
120 #the whole tree.
121 FIND_CMD="find ./ -name '*.[ch]' -a -not \( -path "${SKIP_PATHS//:/ -o -path }" \)"
122
123 #enter tf-m working copy to make git commands execute fine
124 pushd "$TFM_DIRECTORY_NAME" > /dev/null
125 #Execute popd when shell exits
126 trap popd 0
127
128 #List of files we care about. Filter out changed files from interesting
129 #list of files. This is needed to avoid GIT_CMD to break the argument
130 #list length.
131 CARE_LIST=$(eval $FIND_CMD | grep "$(git diff $BASE_COMMIT --name-only)" -)
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100132
Minos Galanakisea421232019-06-20 17:11:28 +0100133 if [ ! -z "$CARE_LIST" ]; then
134 # Only run checkpatch if there are files to check
135 GIT_CMD="git diff $BASE_COMMIT -- $CARE_LIST"
Antonio de Angelis9ba31c32024-12-13 23:42:15 +0000136 echo "run-checkpatch.sh($LINENO): $GIT_CMD"
137 echo "run-checkpatch.sh($LINENO): Checking commits: $(git log "$BASE_COMMIT"..HEAD --format=%h | tr $"\n" " ")"
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100138
Minos Galanakisea421232019-06-20 17:11:28 +0100139 #Modify checkpatch parameters to give more details when working on
140 #diff:s
141 CHECKPATCH_CMD="$CHECKPATCH_CMD --showfile -"
142 fi
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100143
144 if [ $VERBOSE -eq 1 ]; then
145 $GIT_CMD | $CHECKPATCH_CMD | tee -a "$OUTPUT_FILE_PATH"
Dean Birch62c4f082020-01-17 16:13:26 +0000146 RETURN_CODE=${PIPESTATUS[1]}
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100147 else
148 $GIT_CMD | $CHECKPATCH_CMD >> $OUTPUT_FILE_PATH
Dean Birch62c4f082020-01-17 16:13:26 +0000149 RETURN_CODE=${PIPESTATUS[1]}
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100150 fi
151
152 popd > /dev/null
153 #Remove cleanup trap.
154 trap 0
155}
156
157#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
158#~~~~~~~~~~~~~~~~~~~~~~~~ Entry point ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
159#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
160#Internal variables not to be modified.
161VERBOSE=0
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100162
163##@var CHECK_LAST_COMMITS
164##@brief Number of commits to check.
165##
166##Number of commits relative to HEAD to check. When set to 0 full file content
167##is checked instead of commit diffs.
168##
169#This is needed for Doxygen for now.
170#!path CHECK_LAST_COMMITS;
171CHECK_LAST_COMMITS=0
172
Dean Birch62c4f082020-01-17 16:13:26 +0000173# Whether to print the output to screen.
174RAW_OUTPUT=0
175
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100176# Getting options and setting variables required to execute the script. This
177# script starts executing from here.
Antonio de Angelis9eb15a82024-12-13 10:49:53 +0000178while getopts "vhd:f:l:p:r" opt
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100179do
180 case $opt in
181 v) VERBOSE=1 ;;
182 h) usage ; exit 0 ;;
183 d) TFM_DIRECTORY_NAME="$OPTARG" ;;
184 f) OUTPUT_FILE_PATH="$OPTARG" ;;
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100185 l) CHECK_LAST_COMMITS="$OPTARG" ;;
186 p) CHECKPATCH_PATH="$OPTARG" ;;
Dean Birch62c4f082020-01-17 16:13:26 +0000187 r) RAW_OUTPUT=1
188 VERBOSE=1 ;;
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100189 \?) usage ; exit 1 ;;
190 esac
191done
192
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100193#Convert checkpath override path to full path
194CHECKPATCH_PATH=$(readlink -f "$CHECKPATCH_PATH")
195
Xinyu Zhang27449ac2021-12-29 12:01:49 +0800196# Convert TF-M specific type defs file to full path
197TFM_TYPE_DEF_FILE=$CHECKPATCH_PATH"/tfm_type_defs.txt"
198
199# Prepare CheckPatch config file
Antonio de Angelis9ba31c32024-12-13 23:42:15 +0000200CHECKPATCH_CONFIG_FILENAME=$CHECKPATCH_PATH_DEF"/checkpatch.conf"
201sed -i.bak "s#TFM_TYPE_DEF_FILE#$TFM_TYPE_DEF_FILE#g" $CHECKPATCH_CONFIG_FILENAME
Xinyu Zhang27449ac2021-12-29 12:01:49 +0800202
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100203# Create checkpatch command
204CHECKPATCH_APP=$CHECKPATCH_PATH"/checkpatch.pl"
Antonio de Angelis9ba31c32024-12-13 23:42:15 +0000205CHECKPATCH_CMD=$CHECKPATCH_APP" $(grep -o '^[^#]*' $CHECKPATCH_CONFIG_FILENAME)"
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100206
207# Check if checkpatch is present
208if ! [ -f "$CHECKPATCH_APP" ]; then
209 app_err "checkpatch.pl was not found. checkpatch.pl has to be located in $CHECKPATCH_PATH"
210 exit 1
211fi
212
Antonio de Angelis9ba31c32024-12-13 23:42:15 +0000213OUTPUT_FILE_PATH=${OUTPUT_FILE_PATH:-"tfm_checkpatch_report.txt"}
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100214#Truncate previous content
215: > $OUTPUT_FILE_PATH
216
217#Do we need to work on a git diff?
218if [ $CHECK_LAST_COMMITS -eq 0 ]
219then
220 #Working on files
221 check_tree
222else
223 #Working on git diff
224 check_diff
225fi
226
Antonio de Angelis9ba31c32024-12-13 23:42:15 +0000227#Restore the contents of the config file to original values
228sed -i.bak "s#$TFM_TYPE_DEF_FILE#TFM_TYPE_DEF_FILE#g" $CHECKPATCH_CONFIG_FILENAME
229rm $CHECKPATCH_CONFIG_FILENAME.bak
230
Dean Birch62c4f082020-01-17 16:13:26 +0000231if [ "$RAW_OUTPUT" == "1" ] ; then
232 rm $OUTPUT_FILE_PATH
233 exit $RETURN_CODE
234else
Antonio de Angelis9ba31c32024-12-13 23:42:15 +0000235 echo "run-checkpatch.sh($LINENO): checkpatch report \"$(readlink -f ${OUTPUT_FILE_PATH})\" is ready!"
Dean Birch62c4f082020-01-17 16:13:26 +0000236fi