summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/dist/s_function
blob: 07f7ace2c8338f95e71783f3b75b246653c68e79 (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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#! /bin/sh

# Check various WiredTiger function behaviors.
t=__wt.$$
trap 'rm -f $t' 0 1 2 3 13 15

fast=1
case "$1" in
    -F) # Run fast.
        fast=0
        shift;;
    *)
        if test $# -gt 1 ; then
            echo "Usage: $0 [-F]"
            echo "-F only run function validation on modified soure files."
        fi
        break;;
esac

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;}'
}

if test $fast -eq 1 ; then
    files=`find bench examples ext src test -name '*.c' -o -name '*_inline.h'`
else
    files=`git diff --name-only $(git merge-base --fork-point develop) bench examples ext src test | grep -E '(.c|_inline.h)$'`
fi

# 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 $files; do
    file_parse $f |
    egrep '(WT_ERR[_A-Z]*)\(.*(WT_RET[_A-Z]*)\(.*err:|[^a-z_]err:.*(WT_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 $files; do
    file_parse $f | sed "s=^=$f:="
done | python dist/s_function_loop.py |
    egrep '\{@[^@]*(WT_RET[_A-Z]*)\([^@]*(WT_ERR[_A-Z]*)\(.*err:' |
    sed -e 's/^\([^:]*\): *\([^:]*\):.*/\1:\2: mix of returns and jump to the error label within a loop/'

# Early exits from WT_WITH_* macros.
for f in $(grep -l 'WT_WITH_' $files); do
    echo "===$f==="
    cat $f
done | python dist/s_function_with.py 2>&1 $t || exit 1
test -s $t && {
    echo "Misuse of WT_WITH_* macros:"
    cat $t
}

# Return of 0 in functions after a jump to the error label.
for f in $files; 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

# Early exits from critical loops.
for f in $files; 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 $files; 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 $files; 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 $files; 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

if test $fast -eq 1 ; then
    files=`find src -name '*.c' -o -name '*._inline.h'`
else
    files=`git diff --name-only $(git merge-base --fork-point develop) src | grep -E '(.c|_inline.h)$'`
fi

# __wt_verbose with a bitwise OR category parameter.
for f in $files; do
    file_parse $f | python dist/s_function_verbose.py > $t
    test -s $t && {
        echo "$f: Invalid use of verbose category parameter (bitwise OR)."
        sed 's/^/function @ line:/' < $t
    }
done

exit 0