summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/dist/s_function
blob: 314a8c5bb0645f2b2f300a33995f9ceac0a50490 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#! /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 '/WT_TRACK_OP_INIT/,/WT_TRACK_OP_END/{=;p;}' \
	       -e '/va_start/,/va_end/{=;p;}' $f | \
		sed 'N;s/\n/:/' | \
		egrep -w 'return;|return \(|WT_RET' | \
		sed -e "s,^,$f:," -e 's/$/ [return skips matching 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