#! /bin/sh # Check various WiredTiger function behaviors. t=__wt.$$ trap 'rm -f $t' 0 1 2 3 13 15 cd .. # Turn a C file into a line per function so we can use grep on it. file_parse() { sed -n \ -e '/^{$/,/^}$/{=;p;}' $1 | sed 'N;s/\n/:/' | sed -e '/./{H;/^[0-9][0-9]*:}$/!d;}' \ -e x \ -e 's/\n/ /g' \ -e p \ -e '{s/.*//;x;}' } # Returns in functions after a jump to the error label, or an infinite loop # where there's a jump to the error label after the error label. for f in `find bench examples ext src test -name '*.[ci]'`; do file_parse $f | egrep '(WT_ERR[_A-Z]*|WT_ILLEGAL_VALUE_ERR)\(.*(WT_ILLEGAL_VALUE|WT_RET[_A-Z]*)\(.*err:|[^a-z_]err:.*(WT_ERR|WT_ILLEGAL_VALUE_ERR)\(' | sed 's/:.*//' > $t test -s $t && { echo "$f: return after a jump to the error label or a jump to the error label after the error label" sed 's/^/function @ line:/' < $t } done # Returns before jumps to an error label within the same loop. # Jumps before returns have already been detected above. for f in `find bench examples ext src test -name '*.[ci]'`; do file_parse $f | sed "s=^=$f:=" done | python dist/s_function_loop.py | egrep '\{@[^@]*(WT_ILLEGAL_VALUE|WT_RET[_A-Z]*)\([^@]*(WT_ERR[_A-Z]*|WT_ILLEGAL_VALUE_ERR)\(.*err:' | sed -e 's/^\([^:]*\): *\([^:]*\):.*/\1:\2: mix of returns and jump to the error label within a loop/' # Return of 0 in functions after a jump to the error label. for f in `find bench examples ext src test -name '*.[ci]'`; do file_parse $f | egrep -v '[^a-z_]err:.*return \(ret|[^a-z_]err:.*WT_RET' | egrep '[^a-z_]err:.*return \(0\);' | sed 's/:.*//' > $t test -s $t && { echo "$f: error label followed by a return of 0" sed 's/^/function @ line:/' < $t } done # Jumps inside va_start/va_end pairs. for f in `find bench examples ext src test -name '*.[ci]'`; do file_parse $f | egrep 'va_start.*(WT_RET|goto).*va_end' | sed 's/:.*//' > $t file_parse $f | egrep -v 'va_start.*WT_ERR.*[^a-z_]err: va_end' | egrep 'va_start.*WT_ERR.*va_end' | sed 's/:.*//' >> $t test -s $t && { echo "$f: va_end of va_start/va_end pair can be skipped" sed 's/^/function @ line:/' < $t } done # Early exits from critical loops. for f in `find bench examples ext src test -name '*.[ci]'`; do sed -n -e '/API_CALL.*;$/,/API_END.*;/{=;p;}' \ -e '/LSM_.*ENTER*;$/,/LSM_.*LEAVE*;/{=;p;}' \ -e '/va_start/,/va_end/{=;p;}' $f | \ sed 'N;s/\n/:/' | \ egrep -w 'return|WT_RET' | \ sed -e "s,^,$f:," -e 's/$/ [return skips API_END call]/' done # API_END with a return for f in `find bench examples ext src test -name '*.[ci]'`; do file_parse $f | egrep '[^A-Z_]API_END.*return' | sed 's/:.*//' > $t test -s $t && { echo "$f: API_END followed by return." sed 's/^/function @ line:/' < $t } done # S2C with a local WT_CONNECTION_IMPL variable. for f in `find bench examples ext src test -name '*.[ci]'`; do file_parse $f | egrep 'conn = S2C.*S2C' | sed 's/:.*//' > $t test -s $t && { echo "$f: S2C with a local WT_CONNECTION_IMPL variable." sed 's/^/function @ line:/' < $t } done # S2B with a local WT_BTREE variable. for f in `find bench examples ext src test -name '*.[ci]'`; do file_parse $f | egrep 'btree = S2B.*S2B' | sed 's/:.*//' > $t test -s $t && { echo "$f: S2B with a local WT_BTREE variable." sed 's/^/function @ line:/' < $t } done exit 0