Patch check script.
[ffmpeg.git] / tools / patcheck
1 #!/bin/sh
2
3 TMP=patcheck.tmp
4 OPT="-nH"
5 #FILES=`grep '^+++' $* | sed 's/+++ //g'`
6
7 echo patCHeck 1e10.0
8 echo This tool is intended to help a human check/review patches it is very far from
9 echo being free of false positives and negatives, its output are just hints of what
10 echo may or may not be bad. When you use it and it misses something or detects
11 echo something wrong, fix it and send a patch to the ffmpeg-dev ML
12 echo License:GPL Autor: Michael Niedermayer
13
14 ERE_PRITYP='(unsigned *|)(char|short|long|int|long *int|short *int|void|float|double|(u|)int(8|16|32|64)_t)'
15 ERE_TYPES='(const|static|av_cold|inline| *)*('$ERE_PRITYP'|[a-zA-Z][a-zA-Z0-9_]*)[* ]{1,}[a-zA-Z][a-zA-Z0-9_]*'
16 ERE_FUNCS="$ERE_TYPES"' *\('
17
18 hiegrep(){
19     arg="$1"
20     msg="$2"
21     shift 2
22     grep $OPT '^+' $* | grep -v ':+++'| egrep --color=always -- "$arg"> $TMP && echo -e "\n$msg"
23     cat $TMP
24 }
25
26 hiegrep '[[:space:]]$'    'trailing whitespace' $*
27 hiegrep "`echo x | tr 'x' '\t'`"         'tabs' $*
28 #hiegrep ':\+$'          'Empty lines' $*
29 hiegrep ';;'              'double ;' $*
30 hiegrep '\b_[a-zA-Z0-9_]' 'reserved identifer' $*
31 hiegrep '//[-/<\* ]*$'    'empty comment' $*
32 hiegrep '/\*[-<\* ]*\*/'  'empty comment' $*
33 hiegrep 'for *\( *'"$ERE_PRITYP"' '  'not gcc 2.95 compatible' $*
34
35 egrep $OPT '^\+(int|unsigned|static|void)[a-zA-Z0-9 _]*(init|end)[a-zA-Z0-9 _]*\(.*[^;]$' $* | grep -v 'av_cold'> $TMP && echo -e '\nThese functions may need av_cold, please review the whole patch for similar functions needing av_cold'
36 cat $TMP
37
38 hiegrep '\+= *1 *;'     'can be simplified to ++' $*
39 hiegrep '-= *1 *;'      'can be simplified to --' $*
40 hiegrep '((!|=)= *(0|NULL)[^0-9a-z]|[^0-9a-z](0|NULL) *(!|=)=)' 'x==0 / x!=0 can be simplified to !x / x' $*
41
42 egrep $OPT '^\+ *(const *|)static' $*| egrep --color=always '[^=]= *(0|NULL)[^0-9a-zA-Z]'> $TMP && echo -e '\nuseless 0 init'
43 cat $TMP
44 hiegrep '# *ifdef * (HAVE|CONFIG)_' 'ifdefs that should be #if' $*
45
46 hiegrep '\b(awnser|cant|dont|quantised|quantisation|teh|wont)\b' 'common typos' $*
47
48 hiegrep 'av_log\( *NULL' 'Missing context in av_log' $*
49 hiegrep '[^sn]printf' 'Please use av_log' $*
50 hiegrep '\bmalloc' 'Please use av_malloc' $*
51 hiegrep '\) *av_malloc' 'useless casts' $*
52 hiegrep ':\+ *'"$ERE_PRITYP"' *inline' 'non static inline or strangely ordered inline+static' $*
53 hiegrep "$ERE_FUNCS"' *\)' 'missing void' $*
54 hiegrep '(sprintf|strcat|strcpy)' 'Possible security issue, make sure this is safe or use snprintf/av_strl*' $*
55 hiegrep '/ *(2|4|8|16|32|64|128|256|512|1024|2048|4096|8192|16384|32768|65536)[^0-9]' 'divide by 2^x could use >> maybe' $*
56 hiegrep '#(el|)if *(0|1)' 'useless #if' $*
57 hiegrep 'if *\( *(0|1) *\)' 'useless if()' $*
58 hiegrep '& *[a-zA-Z0-9_]* *\[ *0 *\]' 'useless & [0]' $*
59 hiegrep '(\( *[0-9] *(&&|\|\|)|(&&|\|\|) *[0-9] *\))' 'overriding condition' $*
60
61
62 egrep $OPT '^\+.*\.long_name *=' $*| grep -v 'NULL_IF_CONFIG_SMAL'> $TMP && echo -e '\nmissing NULL_IF_CONFIG_SMAL'
63 cat $TMP
64
65 #egrep $OPT '^\+.*const ' $*| grep -v 'static'> $TMP && echo -e '\nnon static const'
66 #cat $TMP
67
68 egrep $OPT '^\+'"$ERE_TYPES" $*| grep ':+[a-zA-Z]' | egrep -v '(static|av_|ff_|typedef)'> $TMP && echo -e '\nNon static with no ff_/av_ prefix'
69 cat $TMP
70
71 hiegrep ':\+[^}]*else' 'missing } prior to else' $*
72
73 #FIXME this should print the previous statement maybe
74 hiegrep ':\+  *{ *$' '{ should be on the same line as the related previous statement' $*
75
76
77 rm $TMP
78 for i in `grep -H '^+.*@param' $*| sed 's/^\([^:]*\):.*@param *\([a-zA-Z0-9_]*\) .*$/\1:\2/'` ; do
79     doxpar=`echo $i | sed 's/^.*:\(.*\)$/\1/'`
80     file=`echo $i | sed 's/^\([^:]*\):.*$/\1/'`
81     grep " *$doxpar *[),]" $file | grep -v '@param' >/dev/null || grep --color=always "@param *$doxpar" $file >>$TMP
82 done
83 if test -e $TMP ; then
84     echo -e '\nmismatching doxy params'
85     cat $TMP
86 fi
87
88 egrep -B2 $OPT '^(\+|) *'"$ERE_TYPES" $* | egrep -A2 --color=always '(:|-)\+.*[^/]/(\*([^*]|$)|/([^/]|$))' > $TMP && echo -e "\n Non doxy comments"
89 cat $TMP
90
91 rm $TMP
92 for i in \
93     `egrep -H '^\+ *'"$ERE_TYPES" $* |\
94     grep -v '(' | egrep -v '\Wgoto\W' |\
95     xargs -d '\n' -n 1 |\
96     grep -o '[* ][* ]*[a-zA-Z][0-9a-zA-Z_]* *[,;=]' |\
97     sed 's/.[* ]*\([a-zA-Z][0-9a-zA-Z_]*\) *[,;=]/\1/'` \
98     ; do
99     echo $i | grep '^NULL$' && continue
100     egrep $i' *(\+|-|\*|/|\||&|%|)=[^=]' $* >/dev/null || echo "possibly never written:"$i >> $TMP
101     egrep '(=|\(|return).*'$i'[^=]*$'    $* >/dev/null || echo "possibly never read   :"$i >> $TMP
102     egrep -o $i' *((\+|-|\*|/|\||&|%|)=[^=]|\+\+|--) *(0x|)[0-9]*(;|)'   $* |\
103            egrep -v $i' *= *(0x|)[0-9]{1,};'>/dev/null || echo "possibly constant     :"$i >> $TMP
104 done
105 if test -e $TMP ; then
106     echo -e '\npossibly unused variables'
107     cat $TMP
108 fi
109
110 grep '^Index:.*Changelog' $* >/dev/null || echo -e "\nMissing changelog entry (ignore if minor change)"
111
112 cat $* | tr '\n' '@' | egrep --color=always -o '(fprintf|av_log|printf)\([^)]*\)[+ ;@]*\1'  >$TMP && echo -e "\nMergeable calls"
113 cat $TMP | tr '@' '\n'
114
115 cat $* | tr '\n' '@' | egrep --color=always -o '\+ *if *\( *([A-Za-z0-9_]*) *[<>]=? *[0-9]* *\) * \1 *= *[0-9]* *;[ @\\+]*else *if *\( *\1 *[<>]=? *[0-9]* *\) *\1 *= *[0-9]* *;'  >$TMP && echo -e "\nav_clip / av_clip_uint8 / av_clip_int16 / ..."
116 cat $TMP | tr '@' '\n'
117
118 cat $* | tr '\n' '@' | egrep --color=always -o '\+ *if *\( *([A-Za-z0-9_]*) *[<>]=? *([A-Za-z0-9_]*) *\)[ @\\+]*(\1|\2) *= *(\1|\2) *;'  >$TMP && echo -e "\nFFMIN/FFMAX"
119 cat $TMP | tr '@' '\n'
120
121 cat $* | tr '\n' '@' | egrep --color=always -o '\+ *if *\( *([A-Za-z0-9_]*) *\)[ @\\+]*av_free(p|) *\( *(&|) *\1[^-.]'  >$TMP && echo -e "\nav_free(NULL) is safe"
122 cat $TMP | tr '@' '\n'
123
124 cat $* | tr '\n' '@' | egrep --color=always -o '[^a-zA-Z0-9_]([a-zA-Z0-9_]*) *= *av_malloc *\([^)]*\)[ @;\\+]*memset *\( *\1'  >$TMP && echo -e "\nav_mallocz()"
125 cat $TMP | tr '@' '\n'
126
127
128 # doesnt work
129 #cat $* | tr '\n' '@' | egrep -o '[^a-zA-Z_0-9]([a-zA-Z][a-zA-Z_0-9]*) *=[^=].*\1' | egrep -o '[^a-zA-Z_0-9]([a-zA-Z][a-zA-Z_0-9]*) *=[^=].*\1 *=[^=]'  >$TMP && echo -e "\nPossibly written 2x before read"
130 #cat $TMP | tr '@' '\n'
131
132 exit
133
134 TODO/idea list:
135
136 for all demuxers & muxers
137     grep for "avctx->priv_data"
138
139 vertical align =
140 /* and * align
141 arrays fitting in smaller types
142 variables written to twice with no interspaced read
143 memset(block, 0, 6*64*sizeof(DCTELEM)); -> clear_blocks
144 check existence of long_name in AVCodec
145 check that the patch does not touch codec & (de)muxer layer at the same time ->split
146
147 write a regression test containing at least a line that triggers each warning once