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