Merge branch 'po/range-doc'
[git] / t / valgrind / analyze.sh
1 #!/bin/sh
2
3 # Get TEST_OUTPUT_DIRECTORY from GIT-BUILD-OPTIONS if it's there...
4 . "$(dirname "$0")/../../GIT-BUILD-OPTIONS"
5 # ... otherwise set it to the default value.
6 : ${TEST_OUTPUT_DIRECTORY=$(dirname "$0")/..}
7
8 output=
9 count=0
10 total_count=0
11 missing_message=
12 new_line='
13 '
14
15 # start outputting the current valgrind error in $out_prefix.++$count,
16 # and the test case which failed in the corresponding .message file
17 start_output () {
18         test -z "$output" || return
19
20         # progress
21         total_count=$(($total_count+1))
22         test -t 2 && printf "\rFound %d errors" $total_count >&2
23
24         count=$(($count+1))
25         output=$out_prefix.$count
26         : > $output
27
28         echo "*** $1 ***" > $output.message
29 }
30
31 finish_output () {
32         test ! -z "$output" || return
33         output=
34
35         # if a test case has more than one valgrind error, we need to
36         # copy the last .message file to the previous errors
37         test -z "$missing_message" || {
38                 while test $missing_message -lt $count
39                 do
40                         cp $out_prefix.$count.message \
41                                 $out_prefix.$missing_message.message
42                         missing_message=$(($missing_message+1))
43                 done
44                 missing_message=
45         }
46 }
47
48 # group the valgrind errors by backtrace
49 output_all () {
50         last_line=
51         j=0
52         i=1
53         while test $i -le $count
54         do
55                 # output <number> <backtrace-in-one-line>
56                 echo "$i $(tr '\n' ' ' < $out_prefix.$i)"
57                 i=$(($i+1))
58         done |
59         sort -t ' ' -k 2 | # order by <backtrace-in-one-line>
60         while read number line
61         do
62                 # find duplicates, do not output backtrace twice
63                 if test "$line" != "$last_line"
64                 then
65                         last_line=$line
66                         j=$(($j+1))
67                         printf "\nValgrind error $j:\n\n"
68                         cat $out_prefix.$number
69                         printf "\nfound in:\n"
70                 fi
71                 # print the test case where this came from
72                 printf "\n"
73                 cat $out_prefix.$number.message
74         done
75 }
76
77 handle_one () {
78         OLDIFS=$IFS
79         IFS="$new_line"
80         while read line
81         do
82                 case "$line" in
83                 # backtrace, possibly a new one
84                 ==[0-9]*)
85
86                         # Does the current valgrind error have a message yet?
87                         case "$output" in
88                         *.message)
89                                 test -z "$missing_message" &&
90                                 missing_message=$count
91                                 output=
92                         esac
93
94                         start_output $(basename $1)
95                         echo "$line" |
96                         sed 's/==[0-9]*==/==valgrind==/' >> $output
97                         ;;
98                 # end of backtrace
99                 '}')
100                         test -z "$output" || {
101                                 echo "$line" >> $output
102                                 test $output = ${output%.message} &&
103                                 output=$output.message
104                         }
105                         ;;
106                 # end of test case
107                 '')
108                         finish_output
109                         ;;
110                 # normal line; if $output is set, print the line
111                 *)
112                         test -z "$output" || echo "$line" >> $output
113                         ;;
114                 esac
115         done < $1
116         IFS=$OLDIFS
117
118         # just to be safe
119         finish_output
120 }
121
122 for test_script in "$TEST_OUTPUT_DIRECTORY"/test-results/*.out
123 do
124         handle_one $test_script
125 done
126
127 output_all