yading@11
|
1 #!/bin/sh
|
yading@11
|
2
|
yading@11
|
3 # if no argument provided, write stdin to a file and re-run the script
|
yading@11
|
4 if [ $# = 0 ]; then
|
yading@11
|
5 cat > patcheck.stdout
|
yading@11
|
6 $0 patcheck.stdout
|
yading@11
|
7 rm -f patcheck.stdout
|
yading@11
|
8 exit
|
yading@11
|
9 fi
|
yading@11
|
10
|
yading@11
|
11 GREP=grep
|
yading@11
|
12 EGREP=egrep
|
yading@11
|
13 TMP=patcheck.tmp
|
yading@11
|
14 OPT="-nH"
|
yading@11
|
15 #FILES=$($GREP '^+++' $* | sed 's/+++ //g')
|
yading@11
|
16
|
yading@11
|
17 echo patCHeck 1e10.0
|
yading@11
|
18 echo This tool is intended to help a human check/review patches. It is very far from
|
yading@11
|
19 echo being free of false positives and negatives, and its output are just hints of what
|
yading@11
|
20 echo may or may not be bad. When you use it and it misses something or detects
|
yading@11
|
21 echo something wrong, fix it and send a patch to the ffmpeg-devel mailing list.
|
yading@11
|
22 echo License: GPL, Author: Michael Niedermayer
|
yading@11
|
23
|
yading@11
|
24 ERE_PRITYP='(unsigned *|)(char|short|long|int|long *int|short *int|void|float|double|(u|)int(8|16|32|64)_t)'
|
yading@11
|
25 ERE_TYPES='(const|static|av_cold|inline| *)*('$ERE_PRITYP'|[a-zA-Z][a-zA-Z0-9_]*)[* ]{1,}[a-zA-Z][a-zA-Z0-9_]*'
|
yading@11
|
26 ERE_FUNCS="$ERE_TYPES"' *\('
|
yading@11
|
27
|
yading@11
|
28 hiegrep(){
|
yading@11
|
29 arg="$1"
|
yading@11
|
30 msg="$2"
|
yading@11
|
31 shift 2
|
yading@11
|
32 $GREP $OPT '^+' $* | $GREP -v ':+++'| $EGREP --color=always -- "$arg"> $TMP && printf "\n$msg\n"
|
yading@11
|
33 cat $TMP
|
yading@11
|
34 }
|
yading@11
|
35
|
yading@11
|
36 hiegrep2(){
|
yading@11
|
37 arg="$1"
|
yading@11
|
38 varg="$2"
|
yading@11
|
39 msg="$3"
|
yading@11
|
40 shift 3
|
yading@11
|
41 $GREP $OPT '^+' $* | $GREP -v ':+++' | $EGREP -v -- "$varg" | $EGREP --color=always -- "$arg" > $TMP && printf "\n$msg\n"
|
yading@11
|
42 cat $TMP
|
yading@11
|
43 }
|
yading@11
|
44
|
yading@11
|
45 hiegrep '[[:space:]]$' 'trailing whitespace' $*
|
yading@11
|
46 hiegrep "$(echo x | tr 'x' '\t')" 'tabs' $*
|
yading@11
|
47 #hiegrep ':\+$' 'Empty lines' $*
|
yading@11
|
48 hiegrep ';;' 'double ;' $*
|
yading@11
|
49 hiegrep2 '\b_[a-zA-Z0-9_]{1,}' '__(asm|attribute)([^a-zA-Z0-9]|$)' 'reserved identifer' $*
|
yading@11
|
50 hiegrep '//[-/<\* ]*$' 'empty comment' $*
|
yading@11
|
51 hiegrep '/\*[-<\* ]*\*/' 'empty comment' $*
|
yading@11
|
52 hiegrep 'for *\( *'"$ERE_PRITYP"' ' 'not gcc 2.95 compatible' $*
|
yading@11
|
53 hiegrep '(static|inline|const) *\1' 'duplicate word' $*
|
yading@11
|
54 hiegrep 'INIT_VLC_USE_STATIC' 'forbidden ancient vlc type' $*
|
yading@11
|
55 hiegrep '=[-+\*\&] ' 'looks like compound assignment' $*
|
yading@11
|
56 hiegrep2 '/\*\* *[a-zA-Z0-9].*' '\*/' 'Inconsistently formatted doxygen comment' $*
|
yading@11
|
57 hiegrep '; */\*\*[^<]' 'Misformatted doxygen comment' $*
|
yading@11
|
58 hiegrep '//!|/\*!' 'inconsistent doxygen syntax' $*
|
yading@11
|
59
|
yading@11
|
60 hiegrep2 '(int|unsigned|static|void)[a-zA-Z0-9 _]*(init|end)[a-zA-Z0-9 _]*\(.*[^;]$' '(av_cold|:\+[^a-zA-Z_])' 'These functions may need av_cold, please review the whole patch for similar functions needing av_cold' $*
|
yading@11
|
61
|
yading@11
|
62 hiegrep '\+= *1 *;' 'can be simplified to ++' $*
|
yading@11
|
63 hiegrep '-= *1 *;' 'can be simplified to --' $*
|
yading@11
|
64 hiegrep '((!|=)= *(0|NULL)[^0-9a-z]|[^0-9a-z](0|NULL) *(!|=)=)' 'x==0 / x!=0 can be simplified to !x / x' $*
|
yading@11
|
65
|
yading@11
|
66 $EGREP $OPT '^\+ *(const *|)static' $*| $EGREP --color=always '[^=]= *(0|NULL)[^0-9a-zA-Z]'> $TMP && printf '\nuseless 0 init\n'
|
yading@11
|
67 cat $TMP
|
yading@11
|
68 hiegrep '# *ifdef * (HAVE|CONFIG)_' 'ifdefs that should be #if' $*
|
yading@11
|
69
|
yading@11
|
70 hiegrep '\b(awnser|cant|dont|wont|usefull|successfull|occured|teh|alot|wether|skiped|skiping|heigth|informations|colums|loosy|loosing|ouput|seperate|preceed|upto|paket|posible|unkown|inpossible|dimention|acheive|funtions|overriden|outputing|seperation|initalize|compatibilty|bistream|knwon|unknwon)\b' 'common typos' $*
|
yading@11
|
71
|
yading@11
|
72 hiegrep 'av_log\( *NULL' 'Missing context in av_log' $*
|
yading@11
|
73 hiegrep '[^sn]printf' 'Please use av_log' $*
|
yading@11
|
74 hiegrep '\bmalloc' 'Please use av_malloc' $*
|
yading@11
|
75 hiegrep '\) *av_malloc' 'useless casts' $*
|
yading@11
|
76 hiegrep ':\+ *'"$ERE_PRITYP"' *inline' 'non static inline or strangely ordered inline+static' $*
|
yading@11
|
77 hiegrep "$ERE_FUNCS"' *\)' 'missing void' $*
|
yading@11
|
78 hiegrep '(sprintf|strcat|strcpy)' 'Possible security issue, make sure this is safe or use snprintf/av_strl*' $*
|
yading@11
|
79 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' $*
|
yading@11
|
80 hiegrep '#(el|)if *(0|1)' 'useless #if' $*
|
yading@11
|
81 hiegrep 'if *\( *(0|1) *\)' 'useless if()' $*
|
yading@11
|
82 hiegrep '& *[a-zA-Z0-9_]* *\[ *0 *\]' 'useless & [0]' $*
|
yading@11
|
83 hiegrep '(\( *[0-9] *(&&|\|\|)|(&&|\|\|) *[0-9] *\))' 'overriding condition' $*
|
yading@11
|
84 hiegrep '(:\+|,|;)( *|static|\*)*'"$ERE_PRITYP"' *\*( |\*)*(src|source|input|in[^a-z])' 'missing const?' $*
|
yading@11
|
85 hiegrep '(:\+|,|;)( *|static|\*)*'"$ERE_PRITYP"' *(src|source|input|in)([0-9A-Z_][0-9A-Za-z_]*){1,} *\[' 'missing const (test2)?' $*
|
yading@11
|
86 hiegrep ' *static *'"$ERE_FUNCS"'[^)]*\);' 'static prototype, maybe you should reorder your functions' $*
|
yading@11
|
87 hiegrep '@file: *[a-zA-Z0-9_]' 'doxy filetag with filename can in the future cause problems when forgotten during a rename' $*
|
yading@11
|
88 hiegrep '\bassert' 'Please use av_assert0, av_assert1 or av_assert2' $*
|
yading@11
|
89
|
yading@11
|
90 hiegrep2 '\.long_name *=' 'NULL_IF_CONFIG_SMAL' 'missing NULL_IF_CONFIG_SMAL' $*
|
yading@11
|
91 hiegrep2 '\.pix_fmts *= *\(' 'const' 'missing const for pix_fmts array' $*
|
yading@11
|
92 hiegrep2 '\.sample_fmts *= *\(' 'const' 'missing const for sample_fmts array' $*
|
yading@11
|
93 hiegrep2 '\.supported_framerates *= *\(' 'const' 'missing const for supported_framerates array' $*
|
yading@11
|
94 hiegrep2 '\.channel_layouts *= *\(' 'const' 'missing const for channel_layouts array' $*
|
yading@11
|
95
|
yading@11
|
96 #$EGREP $OPT '^\+.*const ' $*| $GREP -v 'static'> $TMP && printf '\nnon static const\n'
|
yading@11
|
97 #cat $TMP
|
yading@11
|
98
|
yading@11
|
99 hiegrep2 "$ERE_TYPES" '(static|av_|ff_|typedef|:\+[^a-zA-Z_])' 'Non static with no ff_/av_ prefix' $*
|
yading@11
|
100
|
yading@11
|
101 hiegrep ':\+[^}#]*else' 'missing } prior to else' $*
|
yading@11
|
102 hiegrep '(if|while|for)\(' 'missing whitespace between keyword and ( (feel free to ignore)' $*
|
yading@11
|
103 hiegrep '(else|do){' 'missing whitespace between keyword and { (feel free to ignore)' $*
|
yading@11
|
104 hiegrep '}(else|while)' 'missing whitespace between } and keyword (feel free to ignore)' $*
|
yading@11
|
105
|
yading@11
|
106 #FIXME this should print the previous statement maybe
|
yading@11
|
107 hiegrep ':\+ *{ *$' '{ should be on the same line as the related previous statement' $*
|
yading@11
|
108
|
yading@11
|
109
|
yading@11
|
110 rm $TMP
|
yading@11
|
111 for i in $($GREP -H '^+.*@param' $*| sed 's/^\([^:]*\):.*@param\(\[.*\]\|\) *\([a-zA-Z0-9_]*\) .*$/\1:\3/') ; do
|
yading@11
|
112 doxpar=$(echo $i | sed 's/^.*:\(.*\)$/\1/')
|
yading@11
|
113 file=$(echo $i | sed 's/^\([^:]*\):.*$/\1/')
|
yading@11
|
114 $GREP " *$doxpar *[),]" $file | $GREP -v '@param' >/dev/null || $GREP --color=always "@param *$doxpar" $file >>$TMP
|
yading@11
|
115 done
|
yading@11
|
116 if test -e $TMP ; then
|
yading@11
|
117 printf '\nmismatching doxy params\n'
|
yading@11
|
118 cat $TMP
|
yading@11
|
119 fi
|
yading@11
|
120
|
yading@11
|
121 $EGREP -B2 $OPT '^(\+|) *('"$ERE_TYPES"'|# *define)' $* | $EGREP -A2 --color=always '(:|-)\+[^/]*/(\*([^*]|$)|/([^/]|$))' > $TMP && printf "\n Non doxy comments\n"
|
yading@11
|
122 cat $TMP
|
yading@11
|
123
|
yading@11
|
124 rm $TMP
|
yading@11
|
125 for i in \
|
yading@11
|
126 $($EGREP -H '^\+ *'"$ERE_TYPES" $* |\
|
yading@11
|
127 $GREP -v '(' | $EGREP -v '\Wgoto\W' |\
|
yading@11
|
128 xargs -d '\n' -n 1 |\
|
yading@11
|
129 $GREP -o '[* ][* ]*[a-zA-Z][0-9a-zA-Z_]* *[,;=]' |\
|
yading@11
|
130 sed 's/.[* ]*\([a-zA-Z][0-9a-zA-Z_]*\) *[,;=]/\1/') \
|
yading@11
|
131 ; do
|
yading@11
|
132 echo $i | $GREP '^NULL$' && continue
|
yading@11
|
133 $EGREP $i' *(\+|-|\*|/|\||&|%|)=[^=]' $* >/dev/null || echo "possibly never written:"$i >> $TMP
|
yading@11
|
134 $EGREP '(=|\(|return).*'$i'(==|[^=])*$' $* >/dev/null || echo "possibly never read :"$i >> $TMP
|
yading@11
|
135 $EGREP -o $i' *((\+|-|\*|/|\||&|%|)=[^=]|\+\+|--) *(0x|)[0-9]*(;|)' $* |\
|
yading@11
|
136 $EGREP -v $i' *= *(0x|)[0-9]{1,};'>/dev/null || echo "possibly constant :"$i >> $TMP
|
yading@11
|
137 done
|
yading@11
|
138 if test -e $TMP ; then
|
yading@11
|
139 printf '\npossibly unused variables\n'
|
yading@11
|
140 cat $TMP
|
yading@11
|
141 fi
|
yading@11
|
142
|
yading@11
|
143 $GREP '^+++ .*Changelog' $* >/dev/null || printf "\nMissing changelog entry (ignore if minor change)\n"
|
yading@11
|
144
|
yading@11
|
145 cat $* | tr '\n' '@' | $EGREP --color=always -o '(fprintf|av_log|printf)\([^)]*\)[+ ;@]*\1' >$TMP && printf "\nMergeable calls\n"
|
yading@11
|
146 cat $TMP | tr '@' '\n'
|
yading@11
|
147
|
yading@11
|
148 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 && printf "\nav_clip / av_clip_uint8 / av_clip_int16 / ...\n"
|
yading@11
|
149 cat $TMP | tr '@' '\n'
|
yading@11
|
150
|
yading@11
|
151 cat $* | tr '\n' '@' | $EGREP --color=always -o '\+ *if *\( *([A-Za-z0-9_]*) *[<>]=? *([A-Za-z0-9_]*) *\)[ @\\+]*(\1|\2) *= *(\1|\2) *;' >$TMP && printf "\nFFMIN/FFMAX\n"
|
yading@11
|
152 cat $TMP | tr '@' '\n'
|
yading@11
|
153
|
yading@11
|
154 cat $* | tr '\n' '@' | $EGREP --color=always -o '\+ *if *\( *([A-Za-z0-9_]*) *\)[ @\\+]*av_free(p|) *\( *(&|) *\1[^-.]' >$TMP && printf "\nav_free(NULL) is safe\n"
|
yading@11
|
155 cat $TMP | tr '@' '\n'
|
yading@11
|
156
|
yading@11
|
157 cat $* | tr '\n' '@' | $EGREP --color=always -o '[^a-zA-Z0-9_]([a-zA-Z0-9_]*) *= *av_malloc *\([^)]*\)[ @;\\+]*memset *\( *\1' >$TMP && printf "\nav_mallocz()\n"
|
yading@11
|
158 cat $TMP | tr '@' '\n'
|
yading@11
|
159
|
yading@11
|
160
|
yading@11
|
161 # does not work
|
yading@11
|
162 #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 && printf "\nPossibly written 2x before read\n"
|
yading@11
|
163 #cat $TMP | tr '@' '\n'
|
yading@11
|
164
|
yading@11
|
165 exit
|
yading@11
|
166
|
yading@11
|
167 TODO/idea list:
|
yading@11
|
168
|
yading@11
|
169 for all demuxers & muxers
|
yading@11
|
170 $EGREP for "avctx->priv_data"
|
yading@11
|
171
|
yading@11
|
172 vertical align =
|
yading@11
|
173 /* and * align
|
yading@11
|
174 arrays fitting in smaller types
|
yading@11
|
175 variables written to twice with no interspaced read
|
yading@11
|
176 memset(block, 0, 6*64*sizeof(int16_t)); -> clear_blocks
|
yading@11
|
177 check existence of long_name in AVCodec
|
yading@11
|
178 check that the patch does not touch codec & (de)muxer layer at the same time ->split
|
yading@11
|
179
|
yading@11
|
180 write a regression test containing at least a line that triggers each warning once
|