]> git.ipfire.org Git - thirdparty/gcc.git/blame - contrib/dg-cmp-results.sh
* dg-cmp-results.sh: New script for comparing DejaGNU logs.
[thirdparty/gcc.git] / contrib / dg-cmp-results.sh
CommitLineData
afef9a5b
JL
1#!/bin/bash
2# Copyright (C) 2006 Free Software Foundation
3#
4# Analyze changes in GCC DejaGNU test logs for binutils, gcc, gdb, etc.
5# Original version written in 2005 by James Lemke <jwlemke@wasabisystems.com>.
6#
7# See usage() below.
8
9usage () {
10 cat <<EOF >&2
11Usage:
12 dg-cmp-results.sh [-v] [-v] [-v] <variant-name> <old-file> <new-file>
13 <variant-name> names the desired variant, "/" must be written as "\/".
14 Use the empty string ("") for the first variant in each file.
15 Output is to stdout.
16 Non-verbose output is degradation info like PASS->FAIL.
17 -v adds improvement info like FAIL->PASS.
18 -v -v adds info like tests that are no longer run.
19 -v -v -v adds info for tests that have not changed status.
20 -v -v -v -v is used for debugging.
21EOF
22}
23
24verbose=0
25while test "$1" = "-v"; do
26 verbose=`expr $verbose + 1`
27 shift
28done
29
30if test $# -ne 3 -o ! -f "$2" -o ! -f "$3"; then
31 usage
32 exit 1
33fi
34
35# Command differences for various platforms.
36case `uname -s` in
37Darwin|NetBSD)
38 E=-E # sed
39 ;;
40*)
41 E=-r # sed
42 ;;
43esac
44
45# sections are identified by separator lines beginning with '\t\t==='.
46# section 0 identifies run date, target, and host.
47# section 1 and subsequent contain test data for a target variant.
48# -skip to /^Running target/ and use that line to identify the variant.
49# -subsequent lines contain the result data. They begin with:
50# '(PASS|FAIL|XFAIL|XPASS|UNTESTED|UNSUPPORTED|UNRESOLVED):'
51VARIANT="$1"
52OFILE="$2"
53OBASE=`basename "$2"`
54NFILE="$3"
55NBASE=`basename "$3"`
56
57echo "dg-cmp-results.sh: Verbosity is ${verbose}, Variant is \"${VARIANT}\""
58echo
59
60header="^Running target $VARIANT"
61
62temp=`grep "$header" $OFILE`
63if test -z "$temp"; then
64 echo "Error: variant \"$VARIANT\" not found in $OFILE."
65 exit 1
66fi
67temp=`grep "$header" $NFILE`
68if test -z "$temp"; then
69 echo "Error: variant \"$VARIANT\" not found in $NFILE."
70 exit 1
71fi
72unset temp
73
74# Copy out the old file's section 0.
75echo "Older log file: $OFILE"
76sed $E -e '/^[[:space:]]+===/,$d' $OFILE
77
78# Copy out the new file's section 0.
79echo "Newer log file: $NFILE"
80sed $E -e '/^[[:space:]]+===/,$d' $NFILE
81
82# Create a temporary file from the old file's interesting section.
83sed $E -e "1,/$header/d" \
84 -e '/^[[:space:]]+===/,$d' \
85 -e '/^[A-Z]+:/!d' \
86 -e '/^(WARNING|ERROR):/d' \
87 -e 's/\r$//' \
88 -e 's/^/O:/' \
89 $OFILE |
90 sort -s -t : -k 3b - \
91 >/tmp/o$$-$OBASE
92
93# Create a temporary file from the new file's interesting section.
94sed $E -e "1,/$header/d" \
95 -e '/^[[:space:]]+===/,$d' \
96 -e '/^[A-Z]+:/!d' \
97 -e '/^(WARNING|ERROR):/d' \
98 -e 's/\r$//' \
99 -e 's/^/N:/' \
100 $NFILE |
101 sort -s -t : -k 3b - \
102 >/tmp/n$$-$NBASE
103
104# Merge the two files, then compare adjacent lines.
105# Comparison is complicated by tests that may be run multiple times.
106# If that case, we assume that the order is the same in both files.
107cat <<EOF >compare-$$.awk
108BEGIN {
109 FS = ":"
110 queue1 = 1; queueN = 0; status[queue1] = ""; name[queue1] = ""
111 verbose = verbose + 0 # Make sure it's defined.
112}
113
114# FIFO circular queue
115function push(st, nm) {
116 queueN += 1; status[queueN] = st; name[queueN] = nm
117}
118function peek() {
119 result = 0
120 if (queueN >= queue1) result = queue1
121 return result
122}
123function drop() {
124 queue1 += 1
125 if (queue1 > queueN) { queue1 = 1; queueN = 0; }
126}
127
128function compare(st, nm) {
129 old = peek()
130 if (old == 0) {
131 # This new test wasn't run last time.
132 if (verbose >= 2) printf("NA->%s:%s\n", st, nm)
133 }
134 else {
135 # Compare this new test to the first queued old one.
136 if (verbose >= 4) {
137 printf("Comparing two lines:\n O:%s:%s\n N:%s:%s\n",
138 status[old], nm[old], st, nm)
139 }
140 if (name[old] != nm) {
141 # The old test wasn't run this time and
142 # the new test wasn't run last time.
143 if (verbose >= 2) {
144 printf("%s->NA:%s\n", status[old], name[old])
145 if (nm != "") printf("NA->%s:%s\n", st, nm)
146 }
147 drop()
148 }
149 else {
150 notable = 0
151 if (status[old] == st) {
152 # Status of this test has not changed.
153 if (verbose >= 3) printf("%s:%s\n", st, nm)
154 }
155 else if(status[old] == "PASS" && st == "XFAIL") {
156 if (verbose >= 1) notable = 1
157 }
158 else if(status[old] == "PASS" || st == "FAIL") {
159 # Test did pass but doesn't now
160 # or didn't fail but does now.
161 notable = 1
162 }
163 else if(st == "PASS") {
164 # Test didn't pass but does now.
165 if (verbose >= 1) notable = 1
166 }
167 else if(verbose >= 2) {
168 # Miscellaneous status change.
169 notable = 1
170 }
171 if (notable > 0) printf("%s->%s:%s\n", status[old], st, nm)
172 drop()
173 }
174 }
175}
176
177/^O:/ {
178 while (old = peek()) {
179 if (name[old] == \$3) break;
180 # The queued test is no longer run.
181 compare("", "");
182 }
183 # Save this test for later comparison.
184 push(\$2, \$3)
185}
186
187/^N:/ {
188 compare(\$2, \$3)
189}
190
191END {
192 while (old = peek()) compare("", "")
193}
194EOF
195sort -m -s -t : -k 3b /tmp/o$$-$OBASE /tmp/n$$-$NBASE |
196 awk -v verbose=$verbose -f compare-$$.awk /dev/stdin
197
198# Delete the temporary files.
199rm -f compare-$$.awk /tmp/o$$-$OBASE /tmp/n$$-$NBASE
200
201exit 0