xref: /linux/scripts/dtc/of_unittest_expect (revision 511f3aa71029ef4d9408065f94110c0e8f9dccba)
18e4296c2SFrank Rowand#!/usr/bin/perl
28e4296c2SFrank Rowand# SPDX-License-Identifier: GPL-2.0
38e4296c2SFrank Rowand#
48e4296c2SFrank Rowand# Copyright 2020, 2022 Sony Corporation
58e4296c2SFrank Rowand#
68e4296c2SFrank Rowand# Author: Frank Rowand
78e4296c2SFrank Rowand
88e4296c2SFrank Rowand# This program is meant to be an aid to reading the verbose output of
98e4296c2SFrank Rowand# on the console log that results from executing the Linux kernel
108e4296c2SFrank Rowand# devicetree unittest (drivers/of/unitest.c).
118e4296c2SFrank Rowand
12*511f3aa7SFrank Rowand$VUFX = "230121a";
138e4296c2SFrank Rowand
148e4296c2SFrank Rowanduse strict 'refs';
158e4296c2SFrank Rowanduse strict subs;
168e4296c2SFrank Rowand
178e4296c2SFrank Rowanduse Getopt::Long;
188e4296c2SFrank Rowanduse Text::Wrap;
198e4296c2SFrank Rowand
208e4296c2SFrank Rowand# strip off everything before final "/"
218e4296c2SFrank Rowand(undef, $script_name) = split(/^.*\//, $0);
228e4296c2SFrank Rowand
238e4296c2SFrank Rowand# following /usr/include/sysexits.h
248e4296c2SFrank Rowand$EX_OK=0;
258e4296c2SFrank Rowand$EX_USAGE=64;
268e4296c2SFrank Rowand
278e4296c2SFrank Rowand
288e4296c2SFrank Rowand#______________________________________________________________________________
298e4296c2SFrank Rowandsub compare {
308e4296c2SFrank Rowand	my ($expect, $got) = @_;
318e4296c2SFrank Rowand	my $expect_next;
328e4296c2SFrank Rowand	my $expect_next_lit;
338e4296c2SFrank Rowand	my $got_next;
348e4296c2SFrank Rowand	my $type;
358e4296c2SFrank Rowand
368e4296c2SFrank Rowand	while ($expect) {
378e4296c2SFrank Rowand
388e4296c2SFrank Rowand		($expect_next, $type) = split(/<</, $expect);
398e4296c2SFrank Rowand		($type) = split(/>>/, $type);
408e4296c2SFrank Rowand		$expect =~ s/^.*?>>//;	# '?' is non-greedy, minimal match
418e4296c2SFrank Rowand
428e4296c2SFrank Rowand		# literal, ignore all metacharacters when used in a regex
438e4296c2SFrank Rowand		$expect_next_lit = quotemeta($expect_next);
448e4296c2SFrank Rowand
458e4296c2SFrank Rowand		$got_next = $got;
468e4296c2SFrank Rowand		$got_next =~ s/^($expect_next_lit).*/\1/;
478e4296c2SFrank Rowand		$got       =~ s/^$expect_next_lit//;
488e4296c2SFrank Rowand
498e4296c2SFrank Rowand		if ($expect_next ne $got_next) {
508e4296c2SFrank Rowand			return 0;
518e4296c2SFrank Rowand		}
528e4296c2SFrank Rowand
538e4296c2SFrank Rowand		if ($type eq "int") {
548e4296c2SFrank Rowand			if ($got =~ /^[+-]*[0-9]+/) {
558e4296c2SFrank Rowand				$got =~ s/^[+-]*[0-9]+//;
568e4296c2SFrank Rowand			} else {
578e4296c2SFrank Rowand				return 0;
588e4296c2SFrank Rowand			}
598e4296c2SFrank Rowand		} elsif ($type eq "hex") {
608e4296c2SFrank Rowand			if ($got =~ /^(0x)*[0-9a-f]+/) {
618e4296c2SFrank Rowand				$got =~ s/^(0x)*[0-9a-f]+//;
628e4296c2SFrank Rowand			} else {
638e4296c2SFrank Rowand				return 0;
648e4296c2SFrank Rowand			}
658e4296c2SFrank Rowand		} elsif ($type eq "") {
668e4296c2SFrank Rowand			if ($expect_next ne $got_next) {
678e4296c2SFrank Rowand				return 0;
688e4296c2SFrank Rowand			} else {
698e4296c2SFrank Rowand				return 1;
708e4296c2SFrank Rowand			}
718e4296c2SFrank Rowand		} else {
728e4296c2SFrank Rowand			$internal_err++;
738e4296c2SFrank Rowand			print "** ERROR: special pattern not recognized: <<$type>>, CONSOLE_LOG line: $.\n";
748e4296c2SFrank Rowand			return 0;
758e4296c2SFrank Rowand		}
768e4296c2SFrank Rowand
778e4296c2SFrank Rowand	}
788e4296c2SFrank Rowand
798e4296c2SFrank Rowand	# should not get here
808e4296c2SFrank Rowand	$internal_err++;
818e4296c2SFrank Rowand	print "** ERROR: $script_name internal error, at end of compare(), CONSOLE_LOG line: $.\n";
828e4296c2SFrank Rowand
838e4296c2SFrank Rowand	return 0;
848e4296c2SFrank Rowand}
858e4296c2SFrank Rowand
868e4296c2SFrank Rowand
878e4296c2SFrank Rowand#______________________________________________________________________________
888e4296c2SFrank Rowandsub usage {
898e4296c2SFrank Rowand
908e4296c2SFrank Rowand# ***** when editing, be careful to not put tabs in the string printed:
918e4296c2SFrank Rowand
928e4296c2SFrank Rowand	print STDERR
938e4296c2SFrank Rowand"
948e4296c2SFrank Rowandusage:
958e4296c2SFrank Rowand
968e4296c2SFrank Rowand  $script_name CONSOLE_LOG
978e4296c2SFrank Rowand
988e4296c2SFrank Rowand     -h                print program usage
998e4296c2SFrank Rowand    --help             print program usage
1008e4296c2SFrank Rowand    --hide-expect      suppress output of EXPECTed lines
1018e4296c2SFrank Rowand    --line-num         report line number of CONSOLE_LOG
1028e4296c2SFrank Rowand    --no-expect-stats  do not report EXPECT statistics
1038e4296c2SFrank Rowand    --no-strip-ts      do not strip leading console timestamps
1048e4296c2SFrank Rowand    --verbose          do not suppress EXPECT begin and end lines
1058e4296c2SFrank Rowand    --version          print program version and exit
1068e4296c2SFrank Rowand
1078e4296c2SFrank Rowand
1088e4296c2SFrank Rowand  Process a console log for EXPECTed test related messages to either
1098e4296c2SFrank Rowand  highlight expected devicetree unittest related messages or suppress
1108e4296c2SFrank Rowand  the messages.  Leading console timestamps will be stripped.
1118e4296c2SFrank Rowand
1128e4296c2SFrank Rowand  Various unittests may trigger kernel messages from outside the
1138e4296c2SFrank Rowand  unittest code.  The unittest annotates that it expects the message
1148e4296c2SFrank Rowand  to occur with an 'EXPECT \\ : text' (begin) before triggering the
1158e4296c2SFrank Rowand  message, and an 'EXPECT / : text' (end) after triggering the message.
1168e4296c2SFrank Rowand
1178e4296c2SFrank Rowand  If an expected message does not occur, that will be reported.
1188e4296c2SFrank Rowand
1198e4296c2SFrank Rowand  For each expected message, the 'EXPECT \\ : text' (begin) and
1208e4296c2SFrank Rowand  'EXPECT / : text' (end), 'text' will contain the message text.
1218e4296c2SFrank Rowand
1228e4296c2SFrank Rowand  If 'EXPECT \\' (begin) and 'EXPECT /' (end) lines do not contain
1238e4296c2SFrank Rowand  matching 'text', that will be reported.
1248e4296c2SFrank Rowand
1258e4296c2SFrank Rowand  If EXPECT lines are nested, 'EXPECT /' (end) lines must be in the
1268e4296c2SFrank Rowand  reverse order of the corresponding 'EXPECT \\' (begin) lines.
1278e4296c2SFrank Rowand
1288e4296c2SFrank Rowand  'EXPECT \\ : text' (begin) and 'EXPECT / : text' (end) lines can
1298e4296c2SFrank Rowand  contain special patterns in 'text':
1308e4296c2SFrank Rowand
1318e4296c2SFrank Rowand     <<int>> matches: [+-]*[0-9]+
1328e4296c2SFrank Rowand     <<hex>> matches: (0x)*[0-9a-f]+
1338e4296c2SFrank Rowand
1348e4296c2SFrank Rowand  'EXPECT \\' (begin) and 'EXPECT /' (end) lines are suppressed.
1358e4296c2SFrank Rowand
1368e4296c2SFrank Rowand  A prefix is added to every line of output:
1378e4296c2SFrank Rowand
1388e4296c2SFrank Rowand    'ok ' Line matches an enclosing EXPECT begin/end pair
1398e4296c2SFrank Rowand
1408e4296c2SFrank Rowand    '** ' Line reports $script_name warning or error
1418e4296c2SFrank Rowand
1428e4296c2SFrank Rowand    '-> ' Line reports start or end of the unittests
1438e4296c2SFrank Rowand
1448e4296c2SFrank Rowand    '>> ' Line reports a unittest test FAIL
1458e4296c2SFrank Rowand
1468e4296c2SFrank Rowand    '   ' Lines that are not otherwise prefixed
1478e4296c2SFrank Rowand
1488e4296c2SFrank Rowand  Issues detected in CONSOLE_LOG are reported to STDOUT, not to STDERR.
1498e4296c2SFrank Rowand
1508e4296c2SFrank Rowand  Known Issues:
1518e4296c2SFrank Rowand
1528e4296c2SFrank Rowand    --line-num causes the CONSOLE_LOG line number to be printed in 4 columns.
1538e4296c2SFrank Rowand       If CONSOLE_LOG contains more than 9999 lines then more columns will be
1548e4296c2SFrank Rowand       used to report the line number for lines greater than 9999 (eg for
1558e4296c2SFrank Rowand       lines 10000 - 99999, 5 columns will be used).
1568e4296c2SFrank Rowand";
1578e4296c2SFrank Rowand
1588e4296c2SFrank Rowand	return {};
1598e4296c2SFrank Rowand}
1608e4296c2SFrank Rowand
1618e4296c2SFrank Rowand#______________________________________________________________________________
1628e4296c2SFrank Rowand#______________________________________________________________________________
1638e4296c2SFrank Rowand
1648e4296c2SFrank Rowandif (!GetOptions(
1658e4296c2SFrank Rowand	"h"               => \$help,
1668e4296c2SFrank Rowand	"help"            => \$help,
1678e4296c2SFrank Rowand	"hide-expect"     => \$hide_expect,
1688e4296c2SFrank Rowand	"line-num"        => \$print_line_num,
1698e4296c2SFrank Rowand	"no-expect-stats" => \$no_expect_stats,
1708e4296c2SFrank Rowand	"no-strip-ts"     => \$no_strip_ts,
1718e4296c2SFrank Rowand	"verbose"         => \$verbose,
1728e4296c2SFrank Rowand	"version"         => \$version,
1738e4296c2SFrank Rowand	)) {
1748e4296c2SFrank Rowand	print STDERR "\n";
1758e4296c2SFrank Rowand	print STDERR "ERROR processing command line options\n";
1768e4296c2SFrank Rowand	print STDERR "\n";
1778e4296c2SFrank Rowand	print STDERR "For help, type '$script_name --help'\n";
1788e4296c2SFrank Rowand	print STDERR "\n";
1798e4296c2SFrank Rowand
1808e4296c2SFrank Rowand	exit $EX_OK;
1818e4296c2SFrank Rowand}
1828e4296c2SFrank Rowand
1838e4296c2SFrank Rowand
1848e4296c2SFrank Rowandif ($no_strip_ts) {
1858e4296c2SFrank Rowand	$strip_ts = 1;
1868e4296c2SFrank Rowand	$no_strip_ts = 0;
1878e4296c2SFrank Rowand} else {
1888e4296c2SFrank Rowand	$strip_ts = 0;
1898e4296c2SFrank Rowand	$no_strip_ts = 1;
1908e4296c2SFrank Rowand}
1918e4296c2SFrank Rowand
1928e4296c2SFrank Rowand
1938e4296c2SFrank Rowand# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1948e4296c2SFrank Rowandif ($help){
1958e4296c2SFrank Rowand
1968e4296c2SFrank Rowand	&usage;
1978e4296c2SFrank Rowand
1988e4296c2SFrank Rowand	exit $EX_OK;
1998e4296c2SFrank Rowand}
2008e4296c2SFrank Rowand
2018e4296c2SFrank Rowand
2028e4296c2SFrank Rowand# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2038e4296c2SFrank Rowand
2048e4296c2SFrank Rowandif ($version) {
2058e4296c2SFrank Rowand	print STDERR "\n$script_name  $VUFX\n\n";
2068e4296c2SFrank Rowand	print STDERR "\n";
2078e4296c2SFrank Rowand
2088e4296c2SFrank Rowand	exit $EX_OK;
2098e4296c2SFrank Rowand}
2108e4296c2SFrank Rowand
2118e4296c2SFrank Rowand
2128e4296c2SFrank Rowand# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2138e4296c2SFrank Rowandif ($#ARGV != 0) {
2148e4296c2SFrank Rowand
2158e4296c2SFrank Rowand	# Limit input files to exactly one.
2168e4296c2SFrank Rowand	#
2178e4296c2SFrank Rowand	# 'while ($line = <ARGV>) {' in the code below supports multiple file
2188e4296c2SFrank Rowand	# names on the command line, but the EXPECT statistics are reported
2198e4296c2SFrank Rowand	# once for all input - it is not an expected use case to generate one
2208e4296c2SFrank Rowand	# set of statistics for multiple input files.
2218e4296c2SFrank Rowand
2228e4296c2SFrank Rowand	print STDERR "\n";
2238e4296c2SFrank Rowand	print STDERR "Required arguments: CONSOLE_LOG\n";
2248e4296c2SFrank Rowand	print STDERR "\n";
2258e4296c2SFrank Rowand
2268e4296c2SFrank Rowand	exit $EX_USAGE;
2278e4296c2SFrank Rowand}
2288e4296c2SFrank Rowand
2298e4296c2SFrank Rowand
2308e4296c2SFrank Rowand#______________________________________________________________________________
2318e4296c2SFrank Rowand
2328e4296c2SFrank Rowand# Patterns to match 'EXPECT \ : ' (begin) and 'EXPECT / : ' (end)
2338e4296c2SFrank Rowand#
2348e4296c2SFrank Rowand# $exp_* are used as regex match patterns,
2358e4296c2SFrank Rowand# so '\\\\' in $exp_begin matches a single '\'
2368e4296c2SFrank Rowand# quotemeta() does not do the right thing in this case
2378e4296c2SFrank Rowand#
2388e4296c2SFrank Rowand# $pr_fmt is the prefix that unittest prints for every message
2398e4296c2SFrank Rowand
2408e4296c2SFrank Rowand$pr_fmt = "### dt-test ### ";
2418e4296c2SFrank Rowand$exp_begin = "${pr_fmt}EXPECT \\\\ : ";
2428e4296c2SFrank Rowand$exp_end   = "${pr_fmt}EXPECT / : ";
2438e4296c2SFrank Rowand
2448e4296c2SFrank Rowand
2458e4296c2SFrank Rowand$line_num = "";
2468e4296c2SFrank Rowand$timestamp = "";
2478e4296c2SFrank Rowand
2488e4296c2SFrank RowandLINE:
2498e4296c2SFrank Rowandwhile ($line = <ARGV>) {
2508e4296c2SFrank Rowand
2518e4296c2SFrank Rowand	chomp $line;
2528e4296c2SFrank Rowand
2538e4296c2SFrank Rowand	$prefix = "  ";  ## 2 characters
2548e4296c2SFrank Rowand
2558e4296c2SFrank Rowand
2568e4296c2SFrank Rowand	if ($strip_ts) {
2578e4296c2SFrank Rowand
2588e4296c2SFrank Rowand		$timestamp = $line;
2598e4296c2SFrank Rowand
2608e4296c2SFrank Rowand		if ($timestamp =~ /^\[\s*[0-9]+\.[0-9]*\] /) {
2618e4296c2SFrank Rowand			($timestamp, $null) = split(/]/, $line);
2628e4296c2SFrank Rowand			$timestamp = $timestamp . "] ";
2638e4296c2SFrank Rowand
2648e4296c2SFrank Rowand		} else {
2658e4296c2SFrank Rowand			$timestamp = "";
2668e4296c2SFrank Rowand		}
2678e4296c2SFrank Rowand	}
2688e4296c2SFrank Rowand
2698e4296c2SFrank Rowand	$line =~ s/^\[\s*[0-9]+\.[0-9]*\] //;
2708e4296c2SFrank Rowand
2718e4296c2SFrank Rowand
2728e4296c2SFrank Rowand	# -----  find EXPECT begin
2738e4296c2SFrank Rowand
2748e4296c2SFrank Rowand	if ($line =~ /^\s*$exp_begin/) {
2758e4296c2SFrank Rowand		$data = $line;
2768e4296c2SFrank Rowand		$data =~ s/^\s*$exp_begin//;
277*511f3aa7SFrank Rowand		push @exp_begin_stack, $data;
2788e4296c2SFrank Rowand
2798e4296c2SFrank Rowand		if ($verbose) {
2808e4296c2SFrank Rowand			if ($print_line_num) {
2818e4296c2SFrank Rowand				$line_num = sprintf("%4s ", $.);
2828e4296c2SFrank Rowand			}
2838e4296c2SFrank Rowand			printf "%s %s%s%s\n", $prefix, $line_num,  $timestamp, $line;
2848e4296c2SFrank Rowand		}
2858e4296c2SFrank Rowand
2868e4296c2SFrank Rowand		next LINE;
2878e4296c2SFrank Rowand	}
2888e4296c2SFrank Rowand
2898e4296c2SFrank Rowand
2908e4296c2SFrank Rowand	# -----  find EXPECT end
2918e4296c2SFrank Rowand
2928e4296c2SFrank Rowand	if ($line =~ /^\s*$exp_end/) {
2938e4296c2SFrank Rowand		$data = $line;
2948e4296c2SFrank Rowand		$data =~ s/^\s*$exp_end//;
2958e4296c2SFrank Rowand
2968e4296c2SFrank Rowand		if ($verbose) {
2978e4296c2SFrank Rowand			if ($print_line_num) {
2988e4296c2SFrank Rowand				$line_num = sprintf("%4s ", $.);
2998e4296c2SFrank Rowand			}
3008e4296c2SFrank Rowand			printf "%s %s%s%s\n", $prefix, $line_num,  $timestamp, $line;
3018e4296c2SFrank Rowand		}
3028e4296c2SFrank Rowand
3038e4296c2SFrank Rowand		$found = 0;
3048e4296c2SFrank Rowand		$no_begin = 0;
305*511f3aa7SFrank Rowand		if (@exp_found_or_begin > 0) {
306*511f3aa7SFrank Rowand			$begin = pop @exp_found_or_begin;
3078e4296c2SFrank Rowand			if (compare($data, $begin)) {
3088e4296c2SFrank Rowand				$found = 1;
3098e4296c2SFrank Rowand			}
3108e4296c2SFrank Rowand		} elsif (@begin > 0) {
311*511f3aa7SFrank Rowand			$begin = pop @exp_begin_stack;
3128e4296c2SFrank Rowand		} else {
3138e4296c2SFrank Rowand			$no_begin = 1;
3148e4296c2SFrank Rowand		}
3158e4296c2SFrank Rowand
3168e4296c2SFrank Rowand		if ($no_begin) {
3178e4296c2SFrank Rowand
318*511f3aa7SFrank Rowand			$exp_missing_begin++;
3198e4296c2SFrank Rowand			print "** ERROR: EXPECT end without any EXPECT begin:\n";
3208e4296c2SFrank Rowand			print "       end ---> $line\n";
3218e4296c2SFrank Rowand
3228e4296c2SFrank Rowand		} elsif (! $found) {
3238e4296c2SFrank Rowand
3248e4296c2SFrank Rowand			if ($print_line_num) {
3258e4296c2SFrank Rowand				$line_num = sprintf("%4s ", $.);
3268e4296c2SFrank Rowand			}
3278e4296c2SFrank Rowand
328*511f3aa7SFrank Rowand			$exp_missing++;
3298e4296c2SFrank Rowand			printf "** %s%s$script_name WARNING - not found ---> %s\n",
3308e4296c2SFrank Rowand					$line_num,  $timestamp, $data;
3318e4296c2SFrank Rowand
3328e4296c2SFrank Rowand		} elsif (! compare($data, $begin)) {
3338e4296c2SFrank Rowand
334*511f3aa7SFrank Rowand			$exp_missing_end++;
3358e4296c2SFrank Rowand			print "** ERROR: EXPECT end does not match EXPECT begin:\n";
3368e4296c2SFrank Rowand			print "       begin -> $begin\n";
3378e4296c2SFrank Rowand			print "       end ---> $line\n";
3388e4296c2SFrank Rowand
3398e4296c2SFrank Rowand		} else {
3408e4296c2SFrank Rowand
341*511f3aa7SFrank Rowand			$exp_found++;
3428e4296c2SFrank Rowand
3438e4296c2SFrank Rowand		}
3448e4296c2SFrank Rowand
3458e4296c2SFrank Rowand		next LINE;
3468e4296c2SFrank Rowand	}
3478e4296c2SFrank Rowand
3488e4296c2SFrank Rowand
3498e4296c2SFrank Rowand	# -----  not an EXPECT line
3508e4296c2SFrank Rowand
3518e4296c2SFrank Rowand	if (($line =~ /^${pr_fmt}start of unittest - you will see error messages$/) ||
3528e4296c2SFrank Rowand	    ($line =~ /^${pr_fmt}end of unittest - [0-9]+ passed, [0-9]+ failed$/ )   ) {
3538e4296c2SFrank Rowand		$prefix = "->"; # 2 characters
3548e4296c2SFrank Rowand	} elsif ($line =~ /^${pr_fmt}FAIL /) {
3558e4296c2SFrank Rowand		$unittest_fail++;
3568e4296c2SFrank Rowand		$prefix = ">>"; # 2 characters
3578e4296c2SFrank Rowand	}
3588e4296c2SFrank Rowand
3598e4296c2SFrank Rowand	$found = 0;
360*511f3aa7SFrank Rowand	foreach $begin (@exp_begin_stack) {
3618e4296c2SFrank Rowand		if (compare($begin, $line)) {
3628e4296c2SFrank Rowand			$found = 1;
3638e4296c2SFrank Rowand			last;
3648e4296c2SFrank Rowand		}
3658e4296c2SFrank Rowand	}
3668e4296c2SFrank Rowand
3678e4296c2SFrank Rowand	if ($found) {
368*511f3aa7SFrank Rowand		$begin = shift @exp_begin_stack;
3698e4296c2SFrank Rowand		while (! compare($begin, $line)) {
370*511f3aa7SFrank Rowand			push @exp_found_or_begin, $begin;
371*511f3aa7SFrank Rowand			$begin = shift @exp_begin_stack;
3728e4296c2SFrank Rowand		}
373*511f3aa7SFrank Rowand		push @exp_found_or_begin, $line;
3748e4296c2SFrank Rowand
3758e4296c2SFrank Rowand		if ($hide_expect) {
3768e4296c2SFrank Rowand			$suppress_line = 1;
3778e4296c2SFrank Rowand			next LINE;
3788e4296c2SFrank Rowand		}
3798e4296c2SFrank Rowand		$prefix = "ok"; # 2 characters
3808e4296c2SFrank Rowand	}
3818e4296c2SFrank Rowand
3828e4296c2SFrank Rowand
3838e4296c2SFrank Rowand	if ($print_line_num) {
3848e4296c2SFrank Rowand		$line_num = sprintf("%4s ", $.);
3858e4296c2SFrank Rowand	}
3868e4296c2SFrank Rowand
3878e4296c2SFrank Rowand	printf "%s %s%s%s\n", $prefix, $line_num,  $timestamp, $line;
3888e4296c2SFrank Rowand}
3898e4296c2SFrank Rowand
3908e4296c2SFrank Rowandif (! $no_expect_stats) {
3918e4296c2SFrank Rowand	print  "\n";
3928e4296c2SFrank Rowand	print  "** EXPECT statistics:\n";
3938e4296c2SFrank Rowand	print  "**\n";
394*511f3aa7SFrank Rowand	printf "**   EXPECT found          : %4i\n", $exp_found;
395*511f3aa7SFrank Rowand	printf "**   EXPECT not found      : %4i\n", $exp_missing;
396*511f3aa7SFrank Rowand	printf "**   missing EXPECT begin  : %4i\n", $exp_missing_begin;
397*511f3aa7SFrank Rowand	printf "**   missing EXPECT end    : %4i\n", $exp_missing_end;
3988e4296c2SFrank Rowand	printf "**   unittest FAIL         : %4i\n", $unittest_fail;
3998e4296c2SFrank Rowand	printf "**   internal error        : %4i\n", $internal_err;
4008e4296c2SFrank Rowand}
4018e4296c2SFrank Rowand
402*511f3aa7SFrank Rowandif (@exp_begin_stack) {
4038e4296c2SFrank Rowand	print "** ERROR: EXPECT begin without any EXPECT end:\n";
4048e4296c2SFrank Rowand	print "          This list may be misleading.\n";
405*511f3aa7SFrank Rowand	foreach $begin (@exp_begin_stack) {
4068e4296c2SFrank Rowand		print "       begin ---> $begin\n";
4078e4296c2SFrank Rowand	}
4088e4296c2SFrank Rowand}
409