summaryrefslogtreecommitdiffstats
path: root/tools/checkpatch.sh
blob: 73421784fa812b7a42c2917bc7c1ba4cfba4765b (plain)
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
#!/bin/bash
# Check a patch for style errors.
usage="./checkpatch.sh <patch> <tree>"
patch=$1
tree=$2
checkpatch="$tree/tools/checkpatch.pl --no-tree -f"
ignore="ldpd\|babeld"
cwd=${PWD##*/}
dirty=0
stat=0

if [[ -z "$1" || -z "$2" ]]; then
  echo "$usage"
  exit 0
fi

# remove temp directories
rm -rf /tmp/f1 /tmp/f2

# 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 /tmp/f1 /tmp/f2
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 --> /tmp/f1/$file"
    cp $tree/$file /tmp/f1/
  done
  git -C $tree reset --hard
  git -C $tree clean -fd
  for file in $mod; do
    if [ -f $tree/$file ]; then
      echo "$tree/$file --> /tmp/f2/$file"
      cp $tree/$file /tmp/f2/
    fi
  done
  echo "Running style checks..."
  for file in /tmp/f1/*; do
    echo "$checkpatch $file > $file _cp"
    $checkpatch $file > "$file"_cp 2> /dev/null
  done
  for file in /tmp/f2/*; do
    echo "$checkpatch $file > $file _cp"
    $checkpatch $file > "$file"_cp 2> /dev/null
  done
  echo "Done."
  for file in /tmp/f1/*_cp; do
    echo "Report for $(basename $file _cp)" 1>&2
    echo "===============================================" 1>&2
    if [ -a /tmp/f2/$(basename $file) ]; then
      diff $file /tmp/f2/$(basename $file) | grep -v "normally be const" | grep -A3 "ERROR\|WARNING" | grep -A2 -B2 '/tmp/f1' 1>&2
    else
      cat $file | grep -v "normally be const" | grep -A3 "ERROR\|WARNING" 1>&2
    fi
    if [ "$?" -eq "0" ]; then
      stat=1
    fi
  done
fi

# restore working 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

exit $stat