1#! /bin/sh 2# SPDX-License-Identifier: BSD-3-Clause 3# Copyright 2015 6WIND S.A. 4 5# Load config options: 6# - DPDK_CHECKPATCH_PATH 7# - DPDK_CHECKPATCH_LINE_LENGTH 8. $(dirname $(readlink -e $0))/load-devel-config 9 10VALIDATE_NEW_API=$(dirname $(readlink -e $0))/check-symbol-change.sh 11 12length=${DPDK_CHECKPATCH_LINE_LENGTH:-80} 13 14# override default Linux options 15options="--no-tree" 16options="$options --max-line-length=$length" 17options="$options --show-types" 18options="$options --ignore=LINUX_VERSION_CODE,\ 19FILE_PATH_CHANGES,MAINTAINERS_STYLE,SPDX_LICENSE_TAG,\ 20VOLATILE,PREFER_PACKED,PREFER_ALIGNED,PREFER_PRINTF,\ 21PREFER_KERNEL_TYPES,BIT_MACRO,CONST_STRUCT,\ 22SPLIT_STRING,LONG_LINE_STRING,\ 23LINE_SPACING,PARENTHESIS_ALIGNMENT,NETWORKING_BLOCK_COMMENT_STYLE,\ 24NEW_TYPEDEFS,COMPARISON_TO_NULL" 25 26clean_tmp_files() { 27 if echo $tmpinput | grep -q '^checkpatches\.' ; then 28 rm -f "$tmpinput" 29 fi 30} 31 32trap "clean_tmp_files" INT 33 34print_usage () { 35 cat <<- END_OF_HELP 36 usage: $(basename $0) [-q] [-v] [-nX|patch1 [patch2] ...]] 37 38 Run Linux kernel checkpatch.pl with DPDK options. 39 The environment variable DPDK_CHECKPATCH_PATH must be set. 40 41 The patches to check can be from stdin, files specified on the command line, 42 or latest git commits limited with -n option (default limit: origin/master). 43 END_OF_HELP 44} 45 46check_forbidden_additions() { # <patch> 47 # refrain from new additions of rte_panic() and rte_exit() 48 # multiple folders and expressions are separated by spaces 49 awk -v FOLDERS="lib drivers" \ 50 -v EXPRESSIONS="rte_panic\\\( rte_exit\\\(" \ 51 -v RET_ON_FAIL=1 \ 52 -v MESSAGE='Using rte_panic/rte_exit' \ 53 -f $(dirname $(readlink -e $0))/check-forbidden-tokens.awk \ 54 "$1" 55 # svg figures must be included with wildcard extension 56 # because of png conversion for pdf docs 57 awk -v FOLDERS='doc' \ 58 -v EXPRESSIONS='::[[:space:]]*[^[:space:]]*\\.svg' \ 59 -v RET_ON_FAIL=1 \ 60 -v MESSAGE='Using explicit .svg extension instead of .*' \ 61 -f $(dirname $(readlink -e $0))/check-forbidden-tokens.awk \ 62 "$1" 63} 64 65number=0 66quiet=false 67verbose=false 68while getopts hn:qv ARG ; do 69 case $ARG in 70 n ) number=$OPTARG ;; 71 q ) quiet=true ;; 72 v ) verbose=true ;; 73 h ) print_usage ; exit 0 ;; 74 ? ) print_usage ; exit 1 ;; 75 esac 76done 77shift $(($OPTIND - 1)) 78 79if [ ! -f "$DPDK_CHECKPATCH_PATH" ] || [ ! -x "$DPDK_CHECKPATCH_PATH" ] ; then 80 print_usage >&2 81 echo 82 echo 'Cannot execute DPDK_CHECKPATCH_PATH' >&2 83 exit 1 84fi 85 86print_headline() { # <title> 87 printf '\n### %s\n\n' "$1" 88 headline_printed=true 89} 90 91total=0 92status=0 93 94check () { # <patch> <commit> <title> 95 local ret=0 96 headline_printed=false 97 98 total=$(($total + 1)) 99 ! $verbose || print_headline "$3" 100 if [ -n "$1" ] ; then 101 tmpinput=$1 102 elif [ -n "$2" ] ; then 103 tmpinput=$(mktemp -t dpdk.checkpatches.XXXXXX) 104 git format-patch --find-renames \ 105 --no-stat --stdout -1 $commit > "$tmpinput" 106 else 107 tmpinput=$(mktemp -t dpdk.checkpatches.XXXXXX) 108 cat > "$tmpinput" 109 fi 110 111 ! $verbose || printf 'Running checkpatch.pl:\n' 112 report=$($DPDK_CHECKPATCH_PATH $options "$tmpinput" 2>/dev/null) 113 if [ $? -ne 0 ] ; then 114 $headline_printed || print_headline "$3" 115 printf '%s\n' "$report" | sed -n '1,/^total:.*lines checked$/p' 116 ret=1 117 fi 118 119 ! $verbose || printf '\nChecking API additions/removals:\n' 120 report=$($VALIDATE_NEW_API "$tmpinput") 121 if [ $? -ne 0 ] ; then 122 $headline_printed || print_headline "$3" 123 printf '%s\n' "$report" 124 ret=1 125 fi 126 127 ! $verbose || printf '\nChecking forbidden tokens additions:\n' 128 report=$(check_forbidden_additions "$tmpinput") 129 if [ $? -ne 0 ] ; then 130 $headline_printed || print_headline "$3" 131 printf '%s\n' "$report" 132 ret=1 133 fi 134 135 clean_tmp_files 136 [ $ret -eq 0 ] && return 0 137 138 status=$(($status + 1)) 139} 140 141if [ -n "$1" ] ; then 142 for patch in "$@" ; do 143 # Subject can be on 2 lines 144 subject=$(sed '/^Subject: */!d;s///;N;s,\n[[:space:]]\+, ,;s,\n.*,,;q' "$patch") 145 check "$patch" '' "$subject" 146 done 147elif [ ! -t 0 ] ; then # stdin 148 subject=$(while read header value ; do 149 if [ "$header" = 'Subject:' ] ; then 150 IFS= read next 151 continuation=$(echo "$next" | sed -n 's,^[[:space:]]\+, ,p') 152 echo $value$continuation 153 break 154 fi 155 done) 156 check '' '' "$subject" 157else 158 if [ $number -eq 0 ] ; then 159 commits=$(git rev-list --reverse origin/master..) 160 else 161 commits=$(git rev-list --reverse --max-count=$number HEAD) 162 fi 163 for commit in $commits ; do 164 subject=$(git log --format='%s' -1 $commit) 165 check '' $commit "$subject" 166 done 167fi 168pass=$(($total - $status)) 169$quiet || printf '\n%d/%d valid patch' $pass $total 170$quiet || [ $pass -le 1 ] || printf 'es' 171$quiet || printf '\n' 172exit $status 173