1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
#!/bin/bash
# Check a patch for style errors.
usage="./checkpatch.sh <patch> <tree>"
patch=$1
tree=$2
scriptdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)"
checkpatch="$scriptdir/checkpatch.pl --no-tree -f"
ignore="ldpd"
cwd=${PWD##*/}
dirty=0
stat=0
tmp1=/tmp/f1-$$
tmp2=/tmp/f2-$$
# Function to clean up git working tree if it was dirty
cleanup_dirty_tree() {
if [ $dirty -eq 1 ]; then
git -C $tree read-tree $WORKTREE;
git -C $tree checkout-index -af;
git -C $tree read-tree $INDEX;
if [ -n "$td" ]; then
rm $td
fi
git -C $tree config --unset gc.auto;
fi
}
# Function to check checkpatch.pl return code and handle errors
check_checkpatch_exit_code() {
local exit_code=$1
local file=$2
if [ $exit_code -gt 1 ]; then
echo "ERROR: checkpatch.pl failed with exit code $exit_code for file $file" 1>&2
echo "This indicates a configuration or environment error." 1>&2
# Clean up and exit immediately
cleanup_dirty_tree
rm -rf ${tmp1} ${tmp2}
exit $exit_code
fi
}
if [[ -z "$1" || -z "$2" ]]; then
echo "$usage"
exit 0
fi
# remove temp directories
rm -rf ${tmp1} ${tmp2}
# save working tree
if git -C $tree status --porcelain | egrep --silent '^(\?\?|.[DM])'; then
echo "Detected dirty tree, caching state..."
dirty=1
git -C $tree config gc.auto 0;
td=$(git -C $tree status -z | grep -z "^[ARM]D" | cut -z -d' ' -f2- | tr '\0' '\n')
INDEX=$(git -C $tree write-tree)
git -C $tree add -f .
WORKTREE=$(git -C $tree write-tree)
echo "Saved index to $INDEX"
echo "Saved working tree to $WORKTREE"
fi
# double check
if git -C $tree status --porcelain | egrep --silent '^(\?\?|.[DM])'; then
echo "[!] git working directory must be clean."
exit 1
fi
git -C $tree reset --hard
git -C $tree apply < $patch
mkdir -p ${tmp1} ${tmp2}
mod=$(git -C $tree ls-files -m | grep ".*\.[ch]" | grep -v $ignore)
mod+=" $(git -C $tree ls-files --others --exclude-standard | grep '.*\.[ch]' | grep -v $ignore)"
echo $mod
if [ -z "$mod" ]; then
echo "There doesn't seem to be any changes."
else
echo "Copying source to temp directory..."
for file in $mod; do
echo "$tree/$file --> ${tmp1}/$file"
cp $tree/$file ${tmp1}/
done
git -C $tree reset --hard
git -C $tree clean -fd
for file in $mod; do
if [ -f $tree/$file ]; then
echo "$tree/$file --> ${tmp2}/$file"
cp $tree/$file ${tmp2}/
fi
done
echo "Running style checks..."
for file in ${tmp1}/*; do
echo "$checkpatch $file > $file _cp"
$checkpatch $file > "$file"_cp 2> /dev/null
check_checkpatch_exit_code $? $file
done
for file in ${tmp2}/*; do
echo "$checkpatch $file > $file _cp"
$checkpatch $file > "$file"_cp 2> /dev/null
check_checkpatch_exit_code $? $file
done
echo "Done."
for file in ${tmp1}/*_cp; do
if [ -a ${tmp2}/$(basename $file) ]; then
result=$(diff $file ${tmp2}/$(basename $file) | awk '/< ERROR|< WARNING/,/^< $|^< #|^<[^ ]/ { print $0; ++n }; END { exit n }')
else
result=$(cat $file | awk '/ERROR|WARNING/,/^$/ { print $0; ++n }; END { exit n }')
fi
ni="$?"
if [ "$ni" -ne "0" ]; then
echo "Report for $(basename $file _cp) | $ni issues" 1>&2
echo "===============================================" 1>&2
echo "$result" 1>&2
if echo $result | grep -q "ERROR"; then
stat=2
elif [ "$stat" -eq "0" ]; then
stat=1
fi
fi
done
fi
# restore working tree
cleanup_dirty_tree
# remove temp directories
rm -rf ${tmp1} ${tmp2}
exit $stat
|