1#!/bin/sh
2
3#
4# This program is intended to take a check.log file generated by a failed run of
5# sanity.sh as input and run expr line by line on it.  It seems a much easier
6# way of spotting a single failed line in a 100 line test result.
7#
8
9#
10# This script falls under the GNU General Public License and is intended to
11# be distributed with CVS.
12#
13
14#
15# No warranties, express or implied.
16#
17
18#
19# Contributed by Derek R. Price <derek.price@openavenue.com>
20#
21
22
23
24usage ()
25{
26	echo "\
27usage: $0 [-afh] [file...]
28
29       -a          process alternate pattern
30       -f          process first pattern (default)
31       -h          print this text
32
33     file          files to process (default = check.log)"
34}
35
36# Do a line by line match with expr
37#
38# INPUTS
39#    $1 = text file name
40#    $2 = pattern file name
41expr_line_by_line ()
42{
43	dcl_line=0
44	dcl_wrong=
45	# We are assuming a newline at the end of the file.  The way sanity.sh
46	# uses echo to create the log message guarantees this newline and since
47	# expr ignores the last newline when the anchor is present anyhow, no
48	# information is being lost in the transition
49	while test $dcl_line -lt `wc -l <$1` -a $dcl_line -lt `wc -l <$2`; do
50		dcl_line=`expr $dcl_line + 1`
51		if test `sed -ne${dcl_line}p <$1 |wc -c` -eq 1 \
52				-a `sed -ne${dcl_line}p <$2 |wc -c` -eq 1; then
53			# This is a workaround for what I am calling a bug in GNU
54			# expr - it won't match the empty string to the empty
55			# string.  In this case the assumption is that a single
56			# character is always a newline.  Since we already checked
57			# for the end of the file, we know sed will echo the
58			# newline.
59			:
60		elif expr "`sed -ne${dcl_line}p <$1`" : \
61				"`sed -ne${dcl_line}p <$2`\$" >/dev/null; then
62			:
63		else
64			echo "$dcl_line: `sed -ne${dcl_line}p <$1`"
65			echo "$dcl_line: `sed -ne${dcl_line}p <$2`\$"
66			dcl_wrong="$dcl_wrong $dcl_line"
67		fi
68	done
69	if test `wc -l <$1` -ne `wc -l <$2`; then
70		echo "output & pattern contain differing number of lines"
71	elif test -z "$dcl_wrong"; then
72		echo "no mismatched lines"
73	else
74		echo "mismatched lines: $dcl_wrong"
75	fi
76}
77
78# Process a single check.log file
79#
80# INPUTS
81#    $1 = filename
82process_check_log ()
83{
84	# abort if we can't find any expressions
85	if grep '^\*\* got: $' <$1 >/dev/null; then
86		:
87	else
88		echo "WARNING:  No expressions in file: $1" >&2
89		echo "          Either not a check.log or sanity.sh exited for some other reason," >&2
90		echo "          like bad exit status.  Try tail." >&2
91		return
92	fi
93
94	dcl_exprfiles=""
95	if grep '^\*\* or: $' <$1 >/dev/null; then
96		# file contains a second regex
97		if test $dcl_dofirst -eq 1; then
98			# get the first pattern
99			sed -ne '/^\*\* expected: $/,/^\*\* or: $/p' <$1 >/tmp/dcle$$
100			dcl_exprfiles="$dcl_exprfiles /tmp/dcle$$"
101		fi
102		if test $dcl_doalternate -eq 1; then
103			# get the alternate pattern
104			sed -ne '/^\*\* or: $/,/^\*\* got: $/p' <$1 >/tmp/dclo$$
105			dcl_exprfiles="$dcl_exprfiles /tmp/dclo$$"
106		else
107			echo "WARNING:  Ignoring alternate pattern in file: $1" >&2
108		fi
109	else
110		# file doesn't contain a second regex
111		if test $dcl_dofirst = 1; then
112			# get the only pattern
113			sed -ne '/^\*\* expected: $/,/^\*\* got: $/p' <$1 >/tmp/dcle$$
114			dcl_exprfiles="$dcl_exprfiles /tmp/dcle$$"
115		fi
116		if test $dcl_doalternate -eq 1; then
117			echo "WARNING:  No alternate pattern in file:  $1" >&2
118		fi
119	fi
120
121	# and get the actual output
122	sed -ne '/^\*\* got: $/,$p' <$1 >/tmp/dclg$$
123	sed -ne '1D
124$D
125p' </tmp/dclg$$ >/tmp/dclh$$
126	mv /tmp/dclh$$ /tmp/dclg$$
127
128	# compare the output against each pattern requested
129	for dcl_f in $dcl_exprfiles; do
130		sed -ne '1D
131$D
132p' <$dcl_f >/tmp/dclp$$
133		mv /tmp/dclp$$ $dcl_f
134
135		case $dcl_f in
136			/tmp/dcle*)
137				echo "********** $1 : Primary **********"
138				;;
139			/tmp/dclo*)
140				echo "********** $1 : Alternate **********"
141				;;
142		esac
143
144		expr_line_by_line /tmp/dclg$$ $dcl_f
145
146		rm $dcl_f
147	done
148
149	rm /tmp/dclg$$
150}
151
152###
153### MAIN
154###
155
156# set up defaults
157dcl_doalternate=0
158dcl_dofirst=0
159
160# process options
161while getopts afh arg; do
162	case $arg in
163		a)
164			dcl_doalternate=1
165			;;
166		f)
167			dcl_dofirst=1
168			;;
169		\?|h)
170			usage
171			exit 1
172			;;
173	esac
174done
175
176# dispose of processed args
177shift `expr $OPTIND - 1`
178OPTIND=1
179
180# set the default mode
181if test $dcl_doalternate -eq 0; then
182	dcl_dofirst=1
183fi
184
185# set default arg
186if test $# -eq 0; then
187	dcl_argvar=dcl_default
188	dcl_default=check.log
189else
190	dcl_argvar=@
191fi
192
193eval for file in \"\$$dcl_argvar\"\; do \
194	process_check_log \$file\; \
195done
196
197exit 0
198