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 && printf "\n$msg\n" 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 && printf "\n$msg\n" 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' $* 44hiegrep 'INIT_VLC_USE_STATIC' 'forbidden ancient vlc type' $* 45 46hiegrep2 '(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' $* 47 48hiegrep '\+= *1 *;' 'can be simplified to ++' $* 49hiegrep '-= *1 *;' 'can be simplified to --' $* 50hiegrep '((!|=)= *(0|NULL)[^0-9a-z]|[^0-9a-z](0|NULL) *(!|=)=)' 'x==0 / x!=0 can be simplified to !x / x' $* 51 52egrep $OPT '^\+ *(const *|)static' $*| egrep --color=always '[^=]= *(0|NULL)[^0-9a-zA-Z]'> $TMP && printf '\nuseless 0 init\n' 53cat $TMP 54hiegrep '# *ifdef * (HAVE|CONFIG)_' 'ifdefs that should be #if' $* 55 56hiegrep '\b(awnser|cant|dont|quantised|quantisation|teh|wont)\b' 'common typos' $* 57 58hiegrep 'av_log\( *NULL' 'Missing context in av_log' $* 59hiegrep '[^sn]printf' 'Please use av_log' $* 60hiegrep '\bmalloc' 'Please use av_malloc' $* 61hiegrep '\) *av_malloc' 'useless casts' $* 62hiegrep ':\+ *'"$ERE_PRITYP"' *inline' 'non static inline or strangely ordered inline+static' $* 63hiegrep "$ERE_FUNCS"' *\)' 'missing void' $* 64hiegrep '(sprintf|strcat|strcpy)' 'Possible security issue, make sure this is safe or use snprintf/av_strl*' $* 65hiegrep '/ *(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' $* 66hiegrep '#(el|)if *(0|1)' 'useless #if' $* 67hiegrep 'if *\( *(0|1) *\)' 'useless if()' $* 68hiegrep '& *[a-zA-Z0-9_]* *\[ *0 *\]' 'useless & [0]' $* 69hiegrep '(\( *[0-9] *(&&|\|\|)|(&&|\|\|) *[0-9] *\))' 'overriding condition' $* 70hiegrep '(:\+|,|;)( *|static|\*)*'"$ERE_PRITYP"' *\*( |\*)*(src|source|input|in[^a-z])' 'missing const?' $* 71hiegrep '(:\+|,|;)( *|static|\*)*'"$ERE_PRITYP"' *(src|source|input|in)([0-9A-Z_][0-9A-Za-z_]*){1,} *\[' 'missing const (test2)?' $* 72hiegrep ' *static *'"$ERE_FUNCS"'[^)]*\);' 'static prototype, maybe you should reorder your functions' $* 73 74hiegrep2 '\.long_name *=' 'NULL_IF_CONFIG_SMAL' 'missing NULL_IF_CONFIG_SMAL' $* 75hiegrep2 '\.pix_fmts *= *\(' 'const' 'missing const for pix_fmts array' $* 76hiegrep2 '\.sample_fmts *= *\(' 'const' 'missing const for sample_fmts array' $* 77hiegrep2 '\.supported_framerates *= *\(' 'const' 'missing const for supported_framerates array' $* 78hiegrep2 '\.channel_layouts *= *\(' 'const' 'missing const for channel_layouts array' $* 79 80#egrep $OPT '^\+.*const ' $*| grep -v 'static'> $TMP && printf '\nnon static const\n' 81#cat $TMP 82 83hiegrep2 "$ERE_TYPES" '(static|av_|ff_|typedef|:\+[^a-zA-Z_])' 'Non static with no ff_/av_ prefix' $* 84 85hiegrep ':\+[^}#]*else' 'missing } prior to else' $* 86 87#FIXME this should print the previous statement maybe 88hiegrep ':\+ *{ *$' '{ should be on the same line as the related previous statement' $* 89 90 91rm $TMP 92for i in `grep -H '^+.*@param' $*| sed 's/^\([^:]*\):.*@param\(\[.*\]\|\) *\([a-zA-Z0-9_]*\) .*$/\1:\3/'` ; do 93 doxpar=`echo $i | sed 's/^.*:\(.*\)$/\1/'` 94 file=`echo $i | sed 's/^\([^:]*\):.*$/\1/'` 95 grep " *$doxpar *[),]" $file | grep -v '@param' >/dev/null || grep --color=always "@param *$doxpar" $file >>$TMP 96done 97if test -e $TMP ; then 98 printf '\nmismatching doxy params\n' 99 cat $TMP 100fi 101 102egrep -B2 $OPT '^(\+|) *('"$ERE_TYPES"'|# *define)' $* | egrep -A2 --color=always '(:|-)\+[^/]*/(\*([^*]|$)|/([^/]|$))' > $TMP && printf "\n Non doxy comments\n" 103cat $TMP 104 105rm $TMP 106for i in \ 107 `egrep -H '^\+ *'"$ERE_TYPES" $* |\ 108 grep -v '(' | egrep -v '\Wgoto\W' |\ 109 xargs -d '\n' -n 1 |\ 110 grep -o '[* ][* ]*[a-zA-Z][0-9a-zA-Z_]* *[,;=]' |\ 111 sed 's/.[* ]*\([a-zA-Z][0-9a-zA-Z_]*\) *[,;=]/\1/'` \ 112 ; do 113 echo $i | grep '^NULL$' && continue 114 egrep $i' *(\+|-|\*|/|\||&|%|)=[^=]' $* >/dev/null || echo "possibly never written:"$i >> $TMP 115 egrep '(=|\(|return).*'$i'[^=]*$' $* >/dev/null || echo "possibly never read :"$i >> $TMP 116 egrep -o $i' *((\+|-|\*|/|\||&|%|)=[^=]|\+\+|--) *(0x|)[0-9]*(;|)' $* |\ 117 egrep -v $i' *= *(0x|)[0-9]{1,};'>/dev/null || echo "possibly constant :"$i >> $TMP 118done 119if test -e $TMP ; then 120 printf '\npossibly unused variables\n' 121 cat $TMP 122fi 123 124grep '^Index:.*Changelog' $* >/dev/null || printf "\nMissing changelog entry (ignore if minor change)\n" 125 126cat $* | tr '\n' '@' | egrep --color=always -o '(fprintf|av_log|printf)\([^)]*\)[+ ;@]*\1' >$TMP && printf "\nMergeable calls\n" 127cat $TMP | tr '@' '\n' 128 129cat $* | 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" 130cat $TMP | tr '@' '\n' 131 132cat $* | tr '\n' '@' | egrep --color=always -o '\+ *if *\( *([A-Za-z0-9_]*) *[<>]=? *([A-Za-z0-9_]*) *\)[ @\\+]*(\1|\2) *= *(\1|\2) *;' >$TMP && printf "\nFFMIN/FFMAX\n" 133cat $TMP | tr '@' '\n' 134 135cat $* | tr '\n' '@' | egrep --color=always -o '\+ *if *\( *([A-Za-z0-9_]*) *\)[ @\\+]*av_free(p|) *\( *(&|) *\1[^-.]' >$TMP && printf "\nav_free(NULL) is safe\n" 136cat $TMP | tr '@' '\n' 137 138cat $* | tr '\n' '@' | egrep --color=always -o '[^a-zA-Z0-9_]([a-zA-Z0-9_]*) *= *av_malloc *\([^)]*\)[ @;\\+]*memset *\( *\1' >$TMP && printf "\nav_mallocz()\n" 139cat $TMP | tr '@' '\n' 140 141 142# doesnt work 143#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" 144#cat $TMP | tr '@' '\n' 145 146exit 147 148TODO/idea list: 149 150for all demuxers & muxers 151 grep for "avctx->priv_data" 152 153vertical align = 154/* and * align 155arrays fitting in smaller types 156variables written to twice with no interspaced read 157memset(block, 0, 6*64*sizeof(DCTELEM)); -> clear_blocks 158check existence of long_name in AVCodec 159check that the patch does not touch codec & (de)muxer layer at the same time ->split 160 161write a regression test containing at least a line that triggers each warning once 162