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