xref: /openbmc/linux/scripts/dtc/of_unittest_expect (revision 9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e)
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*568a10bfSFrank Rowand$VUFX = "230211a";
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			}
65*568a10bfSFrank Rowand		} elsif ($type eq "all") {
66*568a10bfSFrank Rowand			return 1;
678e4296c2SFrank Rowand		} elsif ($type eq "") {
688e4296c2SFrank Rowand			if ($expect_next ne $got_next) {
698e4296c2SFrank Rowand				return 0;
708e4296c2SFrank Rowand			} else {
718e4296c2SFrank Rowand				return 1;
728e4296c2SFrank Rowand			}
738e4296c2SFrank Rowand		} else {
748e4296c2SFrank Rowand			$internal_err++;
758e4296c2SFrank Rowand			print "** ERROR: special pattern not recognized: <<$type>>, CONSOLE_LOG line: $.\n";
768e4296c2SFrank Rowand			return 0;
778e4296c2SFrank Rowand		}
788e4296c2SFrank Rowand
798e4296c2SFrank Rowand	}
808e4296c2SFrank Rowand
818e4296c2SFrank Rowand	# should not get here
828e4296c2SFrank Rowand	$internal_err++;
838e4296c2SFrank Rowand	print "** ERROR: $script_name internal error, at end of compare(), CONSOLE_LOG line: $.\n";
848e4296c2SFrank Rowand
858e4296c2SFrank Rowand	return 0;
868e4296c2SFrank Rowand}
878e4296c2SFrank Rowand
888e4296c2SFrank Rowand
898e4296c2SFrank Rowand#______________________________________________________________________________
908e4296c2SFrank Rowandsub usage {
918e4296c2SFrank Rowand
928e4296c2SFrank Rowand# ***** when editing, be careful to not put tabs in the string printed:
938e4296c2SFrank Rowand
948e4296c2SFrank Rowand	print STDERR
958e4296c2SFrank Rowand"
968e4296c2SFrank Rowandusage:
978e4296c2SFrank Rowand
988e4296c2SFrank Rowand  $script_name CONSOLE_LOG
998e4296c2SFrank Rowand
1008e4296c2SFrank Rowand     -h                print program usage
1018e4296c2SFrank Rowand    --help             print program usage
1028e4296c2SFrank Rowand    --hide-expect      suppress output of EXPECTed lines
1038e4296c2SFrank Rowand    --line-num         report line number of CONSOLE_LOG
1048e4296c2SFrank Rowand    --no-expect-stats  do not report EXPECT statistics
1058e4296c2SFrank Rowand    --no-strip-ts      do not strip leading console timestamps
1068e4296c2SFrank Rowand    --verbose          do not suppress EXPECT begin and end lines
1078e4296c2SFrank Rowand    --version          print program version and exit
1088e4296c2SFrank Rowand
1098e4296c2SFrank Rowand
1108e4296c2SFrank Rowand  Process a console log for EXPECTed test related messages to either
1118e4296c2SFrank Rowand  highlight expected devicetree unittest related messages or suppress
1128e4296c2SFrank Rowand  the messages.  Leading console timestamps will be stripped.
1138e4296c2SFrank Rowand
1148e4296c2SFrank Rowand  Various unittests may trigger kernel messages from outside the
1158e4296c2SFrank Rowand  unittest code.  The unittest annotates that it expects the message
1168e4296c2SFrank Rowand  to occur with an 'EXPECT \\ : text' (begin) before triggering the
1178e4296c2SFrank Rowand  message, and an 'EXPECT / : text' (end) after triggering the message.
1188e4296c2SFrank Rowand
1198e4296c2SFrank Rowand  If an expected message does not occur, that will be reported.
1208e4296c2SFrank Rowand
1218e4296c2SFrank Rowand  For each expected message, the 'EXPECT \\ : text' (begin) and
1228e4296c2SFrank Rowand  'EXPECT / : text' (end), 'text' will contain the message text.
1238e4296c2SFrank Rowand
1248e4296c2SFrank Rowand  If 'EXPECT \\' (begin) and 'EXPECT /' (end) lines do not contain
1258e4296c2SFrank Rowand  matching 'text', that will be reported.
1268e4296c2SFrank Rowand
1278e4296c2SFrank Rowand  If EXPECT lines are nested, 'EXPECT /' (end) lines must be in the
1288e4296c2SFrank Rowand  reverse order of the corresponding 'EXPECT \\' (begin) lines.
1298e4296c2SFrank Rowand
1308e4296c2SFrank Rowand  'EXPECT \\ : text' (begin) and 'EXPECT / : text' (end) lines can
1318e4296c2SFrank Rowand  contain special patterns in 'text':
1328e4296c2SFrank Rowand
1338e4296c2SFrank Rowand     <<int>> matches: [+-]*[0-9]+
1348e4296c2SFrank Rowand     <<hex>> matches: (0x)*[0-9a-f]+
135*568a10bfSFrank Rowand     <<all>> matches: anything to end of line
1368e4296c2SFrank Rowand
1378e4296c2SFrank Rowand  'EXPECT \\' (begin) and 'EXPECT /' (end) lines are suppressed.
1388e4296c2SFrank Rowand
1398e4296c2SFrank Rowand  A prefix is added to every line of output:
1408e4296c2SFrank Rowand
1418e4296c2SFrank Rowand    'ok ' Line matches an enclosing EXPECT begin/end pair
1428e4296c2SFrank Rowand
1438e4296c2SFrank Rowand    '** ' Line reports $script_name warning or error
1448e4296c2SFrank Rowand
1458e4296c2SFrank Rowand    '-> ' Line reports start or end of the unittests
1468e4296c2SFrank Rowand
1478e4296c2SFrank Rowand    '>> ' Line reports a unittest test FAIL
1488e4296c2SFrank Rowand
1498e4296c2SFrank Rowand    '   ' Lines that are not otherwise prefixed
1508e4296c2SFrank Rowand
1518e4296c2SFrank Rowand  Issues detected in CONSOLE_LOG are reported to STDOUT, not to STDERR.
1528e4296c2SFrank Rowand
1538e4296c2SFrank Rowand  Known Issues:
1548e4296c2SFrank Rowand
1558e4296c2SFrank Rowand    --line-num causes the CONSOLE_LOG line number to be printed in 4 columns.
1568e4296c2SFrank Rowand       If CONSOLE_LOG contains more than 9999 lines then more columns will be
1578e4296c2SFrank Rowand       used to report the line number for lines greater than 9999 (eg for
1588e4296c2SFrank Rowand       lines 10000 - 99999, 5 columns will be used).
1598e4296c2SFrank Rowand";
1608e4296c2SFrank Rowand
1618e4296c2SFrank Rowand	return {};
1628e4296c2SFrank Rowand}
1638e4296c2SFrank Rowand
1648e4296c2SFrank Rowand#______________________________________________________________________________
1658e4296c2SFrank Rowand#______________________________________________________________________________
1668e4296c2SFrank Rowand
1678e4296c2SFrank Rowandif (!GetOptions(
1688e4296c2SFrank Rowand	"h"               => \$help,
1698e4296c2SFrank Rowand	"help"            => \$help,
1708e4296c2SFrank Rowand	"hide-expect"     => \$hide_expect,
1718e4296c2SFrank Rowand	"line-num"        => \$print_line_num,
1728e4296c2SFrank Rowand	"no-expect-stats" => \$no_expect_stats,
1738e4296c2SFrank Rowand	"no-strip-ts"     => \$no_strip_ts,
1748e4296c2SFrank Rowand	"verbose"         => \$verbose,
1758e4296c2SFrank Rowand	"version"         => \$version,
1768e4296c2SFrank Rowand	)) {
1778e4296c2SFrank Rowand	print STDERR "\n";
1788e4296c2SFrank Rowand	print STDERR "ERROR processing command line options\n";
1798e4296c2SFrank Rowand	print STDERR "\n";
1808e4296c2SFrank Rowand	print STDERR "For help, type '$script_name --help'\n";
1818e4296c2SFrank Rowand	print STDERR "\n";
1828e4296c2SFrank Rowand
1838e4296c2SFrank Rowand	exit $EX_OK;
1848e4296c2SFrank Rowand}
1858e4296c2SFrank Rowand
1868e4296c2SFrank Rowand
1878e4296c2SFrank Rowandif ($no_strip_ts) {
1888e4296c2SFrank Rowand	$strip_ts = 1;
1898e4296c2SFrank Rowand	$no_strip_ts = 0;
1908e4296c2SFrank Rowand} else {
1918e4296c2SFrank Rowand	$strip_ts = 0;
1928e4296c2SFrank Rowand	$no_strip_ts = 1;
1938e4296c2SFrank Rowand}
1948e4296c2SFrank Rowand
1958e4296c2SFrank Rowand
1968e4296c2SFrank Rowand# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1978e4296c2SFrank Rowandif ($help){
1988e4296c2SFrank Rowand
1998e4296c2SFrank Rowand	&usage;
2008e4296c2SFrank Rowand
2018e4296c2SFrank Rowand	exit $EX_OK;
2028e4296c2SFrank Rowand}
2038e4296c2SFrank Rowand
2048e4296c2SFrank Rowand
2058e4296c2SFrank Rowand# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2068e4296c2SFrank Rowand
2078e4296c2SFrank Rowandif ($version) {
2088e4296c2SFrank Rowand	print STDERR "\n$script_name  $VUFX\n\n";
2098e4296c2SFrank Rowand	print STDERR "\n";
2108e4296c2SFrank Rowand
2118e4296c2SFrank Rowand	exit $EX_OK;
2128e4296c2SFrank Rowand}
2138e4296c2SFrank Rowand
2148e4296c2SFrank Rowand
2158e4296c2SFrank Rowand# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2168e4296c2SFrank Rowandif ($#ARGV != 0) {
2178e4296c2SFrank Rowand
2188e4296c2SFrank Rowand	# Limit input files to exactly one.
2198e4296c2SFrank Rowand	#
2208e4296c2SFrank Rowand	# 'while ($line = <ARGV>) {' in the code below supports multiple file
2218e4296c2SFrank Rowand	# names on the command line, but the EXPECT statistics are reported
2228e4296c2SFrank Rowand	# once for all input - it is not an expected use case to generate one
2238e4296c2SFrank Rowand	# set of statistics for multiple input files.
2248e4296c2SFrank Rowand
2258e4296c2SFrank Rowand	print STDERR "\n";
2268e4296c2SFrank Rowand	print STDERR "Required arguments: CONSOLE_LOG\n";
2278e4296c2SFrank Rowand	print STDERR "\n";
2288e4296c2SFrank Rowand
2298e4296c2SFrank Rowand	exit $EX_USAGE;
2308e4296c2SFrank Rowand}
2318e4296c2SFrank Rowand
2328e4296c2SFrank Rowand
2338e4296c2SFrank Rowand#______________________________________________________________________________
2348e4296c2SFrank Rowand
2358e4296c2SFrank Rowand# Patterns to match 'EXPECT \ : ' (begin) and 'EXPECT / : ' (end)
2368e4296c2SFrank Rowand#
2378e4296c2SFrank Rowand# $exp_* are used as regex match patterns,
2388e4296c2SFrank Rowand# so '\\\\' in $exp_begin matches a single '\'
2398e4296c2SFrank Rowand# quotemeta() does not do the right thing in this case
2408e4296c2SFrank Rowand#
2418e4296c2SFrank Rowand# $pr_fmt is the prefix that unittest prints for every message
2428e4296c2SFrank Rowand
2438e4296c2SFrank Rowand$pr_fmt = "### dt-test ### ";
2448e4296c2SFrank Rowand$exp_begin = "${pr_fmt}EXPECT \\\\ : ";
2458e4296c2SFrank Rowand$exp_end   = "${pr_fmt}EXPECT / : ";
246*568a10bfSFrank Rowand$expnot_begin = "${pr_fmt}EXPECT_NOT \\\\ : ";
247*568a10bfSFrank Rowand$expnot_end   = "${pr_fmt}EXPECT_NOT / : ";
2488e4296c2SFrank Rowand
2498e4296c2SFrank Rowand
2508e4296c2SFrank Rowand$line_num = "";
2518e4296c2SFrank Rowand$timestamp = "";
2528e4296c2SFrank Rowand
2538e4296c2SFrank RowandLINE:
2548e4296c2SFrank Rowandwhile ($line = <ARGV>) {
2558e4296c2SFrank Rowand
2568e4296c2SFrank Rowand	chomp $line;
2578e4296c2SFrank Rowand
258*568a10bfSFrank Rowand	$suppress_line = 0;
259*568a10bfSFrank Rowand
2608e4296c2SFrank Rowand	$prefix = "  ";  ## 2 characters
2618e4296c2SFrank Rowand
2628e4296c2SFrank Rowand
2638e4296c2SFrank Rowand	if ($strip_ts) {
2648e4296c2SFrank Rowand
2658e4296c2SFrank Rowand		$timestamp = $line;
2668e4296c2SFrank Rowand
2678e4296c2SFrank Rowand		if ($timestamp =~ /^\[\s*[0-9]+\.[0-9]*\] /) {
2688e4296c2SFrank Rowand			($timestamp, $null) = split(/]/, $line);
2698e4296c2SFrank Rowand			$timestamp = $timestamp . "] ";
2708e4296c2SFrank Rowand
2718e4296c2SFrank Rowand		} else {
2728e4296c2SFrank Rowand			$timestamp = "";
2738e4296c2SFrank Rowand		}
2748e4296c2SFrank Rowand	}
2758e4296c2SFrank Rowand
2768e4296c2SFrank Rowand	$line =~ s/^\[\s*[0-9]+\.[0-9]*\] //;
2778e4296c2SFrank Rowand
2788e4296c2SFrank Rowand
2798e4296c2SFrank Rowand	# -----  find EXPECT begin
2808e4296c2SFrank Rowand
2818e4296c2SFrank Rowand	if ($line =~ /^\s*$exp_begin/) {
2828e4296c2SFrank Rowand		$data = $line;
2838e4296c2SFrank Rowand		$data =~ s/^\s*$exp_begin//;
284511f3aa7SFrank Rowand		push @exp_begin_stack, $data;
2858e4296c2SFrank Rowand
2868e4296c2SFrank Rowand		if ($verbose) {
2878e4296c2SFrank Rowand			if ($print_line_num) {
2888e4296c2SFrank Rowand				$line_num = sprintf("%4s ", $.);
2898e4296c2SFrank Rowand			}
2908e4296c2SFrank Rowand			printf "%s %s%s%s\n", $prefix, $line_num,  $timestamp, $line;
2918e4296c2SFrank Rowand		}
2928e4296c2SFrank Rowand
2938e4296c2SFrank Rowand		next LINE;
2948e4296c2SFrank Rowand	}
2958e4296c2SFrank Rowand
2968e4296c2SFrank Rowand
2978e4296c2SFrank Rowand	# -----  find EXPECT end
2988e4296c2SFrank Rowand
2998e4296c2SFrank Rowand	if ($line =~ /^\s*$exp_end/) {
3008e4296c2SFrank Rowand		$data = $line;
3018e4296c2SFrank Rowand		$data =~ s/^\s*$exp_end//;
3028e4296c2SFrank Rowand
3038e4296c2SFrank Rowand		if ($verbose) {
3048e4296c2SFrank Rowand			if ($print_line_num) {
3058e4296c2SFrank Rowand				$line_num = sprintf("%4s ", $.);
3068e4296c2SFrank Rowand			}
3078e4296c2SFrank Rowand			printf "%s %s%s%s\n", $prefix, $line_num,  $timestamp, $line;
3088e4296c2SFrank Rowand		}
3098e4296c2SFrank Rowand
3108e4296c2SFrank Rowand		$found = 0;
3118e4296c2SFrank Rowand		$no_begin = 0;
312511f3aa7SFrank Rowand		if (@exp_found_or_begin > 0) {
313511f3aa7SFrank Rowand			$begin = pop @exp_found_or_begin;
3148e4296c2SFrank Rowand			if (compare($data, $begin)) {
3158e4296c2SFrank Rowand				$found = 1;
316*568a10bfSFrank Rowand				$exp_found++;
3178e4296c2SFrank Rowand			}
3188e4296c2SFrank Rowand		} elsif (@begin > 0) {
319511f3aa7SFrank Rowand			$begin = pop @exp_begin_stack;
3208e4296c2SFrank Rowand		} else {
3218e4296c2SFrank Rowand			$no_begin = 1;
3228e4296c2SFrank Rowand		}
3238e4296c2SFrank Rowand
3248e4296c2SFrank Rowand		if ($no_begin) {
3258e4296c2SFrank Rowand
326511f3aa7SFrank Rowand			$exp_missing_begin++;
327*568a10bfSFrank Rowand			print "** ERROR: EXPECT end without matching EXPECT begin:\n";
3288e4296c2SFrank Rowand			print "       end ---> $line\n";
3298e4296c2SFrank Rowand
3308e4296c2SFrank Rowand		} elsif (! $found) {
3318e4296c2SFrank Rowand
3328e4296c2SFrank Rowand			if ($print_line_num) {
3338e4296c2SFrank Rowand				$line_num = sprintf("%4s ", $.);
3348e4296c2SFrank Rowand			}
3358e4296c2SFrank Rowand
336511f3aa7SFrank Rowand			$exp_missing++;
3378e4296c2SFrank Rowand			printf "** %s%s$script_name WARNING - not found ---> %s\n",
3388e4296c2SFrank Rowand					$line_num,  $timestamp, $data;
3398e4296c2SFrank Rowand
340*568a10bfSFrank Rowand		} elsif (! compare($data, $begin) and ($data ne $begin)) {
3418e4296c2SFrank Rowand
342511f3aa7SFrank Rowand			$exp_missing_end++;
3438e4296c2SFrank Rowand			print "** ERROR: EXPECT end does not match EXPECT begin:\n";
3448e4296c2SFrank Rowand			print "       begin -> $begin\n";
3458e4296c2SFrank Rowand			print "       end ---> $line\n";
3468e4296c2SFrank Rowand
347*568a10bfSFrank Rowand		}
348*568a10bfSFrank Rowand
349*568a10bfSFrank Rowand		next LINE;
350*568a10bfSFrank Rowand	}
351*568a10bfSFrank Rowand
352*568a10bfSFrank Rowand
353*568a10bfSFrank Rowand	# -----  find EXPECT_NOT begin
354*568a10bfSFrank Rowand
355*568a10bfSFrank Rowand	if ($line =~ /^\s*$expnot_begin/) {
356*568a10bfSFrank Rowand		$data = $line;
357*568a10bfSFrank Rowand		$data =~ s/^\s*$expnot_begin//;
358*568a10bfSFrank Rowand		push @expnot_begin_stack, $data;
359*568a10bfSFrank Rowand
360*568a10bfSFrank Rowand		if ($verbose) {
361*568a10bfSFrank Rowand			if ($print_line_num) {
362*568a10bfSFrank Rowand				$line_num = sprintf("%4s ", $.);
363*568a10bfSFrank Rowand			}
364*568a10bfSFrank Rowand			printf "%s %s%s%s\n", $prefix, $line_num,  $timestamp, $line;
365*568a10bfSFrank Rowand		}
366*568a10bfSFrank Rowand
367*568a10bfSFrank Rowand		next LINE;
368*568a10bfSFrank Rowand	}
369*568a10bfSFrank Rowand
370*568a10bfSFrank Rowand
371*568a10bfSFrank Rowand	# -----  find EXPECT_NOT end
372*568a10bfSFrank Rowand
373*568a10bfSFrank Rowand	if ($line =~ /^\s*$expnot_end/) {
374*568a10bfSFrank Rowand		$data = $line;
375*568a10bfSFrank Rowand		$data =~ s/^\s*$expnot_end//;
376*568a10bfSFrank Rowand
377*568a10bfSFrank Rowand		if ($verbose) {
378*568a10bfSFrank Rowand			if ($print_line_num) {
379*568a10bfSFrank Rowand				$line_num = sprintf("%4s ", $.);
380*568a10bfSFrank Rowand			}
381*568a10bfSFrank Rowand			printf "%s %s%s%s\n", $prefix, $line_num,  $timestamp, $line;
382*568a10bfSFrank Rowand		}
383*568a10bfSFrank Rowand
384*568a10bfSFrank Rowand		$found = 0;
385*568a10bfSFrank Rowand		$no_begin = 0;
386*568a10bfSFrank Rowand		if (@expnot_found_or_begin > 0) {
387*568a10bfSFrank Rowand			$begin = pop @expnot_found_or_begin;
388*568a10bfSFrank Rowand			if (compare($data, $begin)) {
389*568a10bfSFrank Rowand				$found = 1;
390*568a10bfSFrank Rowand				$expnot_found++;
391*568a10bfSFrank Rowand			}
392*568a10bfSFrank Rowand		} elsif (@expnot_begin_stack <= 0) {
393*568a10bfSFrank Rowand			$no_begin = 1;
394*568a10bfSFrank Rowand		}
395*568a10bfSFrank Rowand
396*568a10bfSFrank Rowand		if ($no_begin) {
397*568a10bfSFrank Rowand
398*568a10bfSFrank Rowand			$expnot_missing_begin++;
399*568a10bfSFrank Rowand			print "** ERROR: EXPECT_NOT end without matching EXPECT_NOT begin:\n";
400*568a10bfSFrank Rowand			print "       end ---> $line\n";
401*568a10bfSFrank Rowand
402*568a10bfSFrank Rowand		}
403*568a10bfSFrank Rowand
404*568a10bfSFrank Rowand		if ($found) {
405*568a10bfSFrank Rowand
406*568a10bfSFrank Rowand			if ($print_line_num) {
407*568a10bfSFrank Rowand				$line_num = sprintf("%4s ", $.);
408*568a10bfSFrank Rowand			}
409*568a10bfSFrank Rowand
410*568a10bfSFrank Rowand			printf "** %s%s$script_name WARNING - next line matches EXPECT_NOT\n",
411*568a10bfSFrank Rowand					$line_num,  $timestamp;
412*568a10bfSFrank Rowand			printf "** %s%s%s\n", $line_num,  $timestamp, $line;
413*568a10bfSFrank Rowand
4148e4296c2SFrank Rowand		} else {
4158e4296c2SFrank Rowand
416*568a10bfSFrank Rowand			$expnot_missing++;
4178e4296c2SFrank Rowand
4188e4296c2SFrank Rowand		}
4198e4296c2SFrank Rowand
420*568a10bfSFrank Rowand		if (@expnot_begin_stack > 0) {
421*568a10bfSFrank Rowand			$begin = pop @expnot_begin_stack;
422*568a10bfSFrank Rowand
423*568a10bfSFrank Rowand			if (! compare($data, $begin) and ($data ne $begin)) {
424*568a10bfSFrank Rowand
425*568a10bfSFrank Rowand				$expnot_missing_end++;
426*568a10bfSFrank Rowand				print "** ERROR: EXPECT_NOT end does not match EXPECT_NOT begin:\n";
427*568a10bfSFrank Rowand				print "       begin -> $begin\n";
428*568a10bfSFrank Rowand				print "       end ---> $line\n";
429*568a10bfSFrank Rowand
430*568a10bfSFrank Rowand			}
431*568a10bfSFrank Rowand		}
432*568a10bfSFrank Rowand
4338e4296c2SFrank Rowand		next LINE;
4348e4296c2SFrank Rowand	}
4358e4296c2SFrank Rowand
4368e4296c2SFrank Rowand
4378e4296c2SFrank Rowand	# -----  not an EXPECT line
4388e4296c2SFrank Rowand
4398e4296c2SFrank Rowand	if (($line =~ /^${pr_fmt}start of unittest - you will see error messages$/) ||
4408e4296c2SFrank Rowand	    ($line =~ /^${pr_fmt}end of unittest - [0-9]+ passed, [0-9]+ failed$/ )   ) {
4418e4296c2SFrank Rowand		$prefix = "->"; # 2 characters
4428e4296c2SFrank Rowand	} elsif ($line =~ /^${pr_fmt}FAIL /) {
4438e4296c2SFrank Rowand		$unittest_fail++;
4448e4296c2SFrank Rowand		$prefix = ">>"; # 2 characters
4458e4296c2SFrank Rowand	}
4468e4296c2SFrank Rowand
4478e4296c2SFrank Rowand	$found = 0;
448511f3aa7SFrank Rowand	foreach $begin (@exp_begin_stack) {
4498e4296c2SFrank Rowand		if (compare($begin, $line)) {
4508e4296c2SFrank Rowand			$found = 1;
4518e4296c2SFrank Rowand			last;
4528e4296c2SFrank Rowand		}
4538e4296c2SFrank Rowand	}
4548e4296c2SFrank Rowand
4558e4296c2SFrank Rowand	if ($found) {
456511f3aa7SFrank Rowand		$begin = shift @exp_begin_stack;
4578e4296c2SFrank Rowand		while (! compare($begin, $line)) {
458511f3aa7SFrank Rowand			push @exp_found_or_begin, $begin;
459511f3aa7SFrank Rowand			$begin = shift @exp_begin_stack;
4608e4296c2SFrank Rowand		}
461511f3aa7SFrank Rowand		push @exp_found_or_begin, $line;
4628e4296c2SFrank Rowand
4638e4296c2SFrank Rowand		if ($hide_expect) {
4648e4296c2SFrank Rowand			$suppress_line = 1;
4658e4296c2SFrank Rowand		}
4668e4296c2SFrank Rowand		$prefix = "ok"; # 2 characters
4678e4296c2SFrank Rowand	}
4688e4296c2SFrank Rowand
4698e4296c2SFrank Rowand
470*568a10bfSFrank Rowand	$found = 0;
471*568a10bfSFrank Rowand	foreach $begin (@expnot_begin_stack) {
472*568a10bfSFrank Rowand		if (compare($begin, $line)) {
473*568a10bfSFrank Rowand			$found = 1;
474*568a10bfSFrank Rowand			last;
475*568a10bfSFrank Rowand		}
476*568a10bfSFrank Rowand	}
477*568a10bfSFrank Rowand
478*568a10bfSFrank Rowand	if ($found) {
479*568a10bfSFrank Rowand		$begin = shift @begin;
480*568a10bfSFrank Rowand		while (! compare($begin, $line)) {
481*568a10bfSFrank Rowand			push @expnot_found_or_begin, $begin;
482*568a10bfSFrank Rowand			$begin = shift @begin;
483*568a10bfSFrank Rowand		}
484*568a10bfSFrank Rowand		push @expnot_found_or_begin, $line;
485*568a10bfSFrank Rowand
486*568a10bfSFrank Rowand		if ($hide_expect) {
487*568a10bfSFrank Rowand			$suppress_line = 1;
488*568a10bfSFrank Rowand		}
489*568a10bfSFrank Rowand		$prefix = "**"; # 2 characters
490*568a10bfSFrank Rowand	}
491*568a10bfSFrank Rowand
492*568a10bfSFrank Rowand
493*568a10bfSFrank Rowand	if ($suppress_line) {
494*568a10bfSFrank Rowand		next LINE;
495*568a10bfSFrank Rowand	}
496*568a10bfSFrank Rowand
4978e4296c2SFrank Rowand	if ($print_line_num) {
4988e4296c2SFrank Rowand		$line_num = sprintf("%4s ", $.);
4998e4296c2SFrank Rowand	}
5008e4296c2SFrank Rowand
5018e4296c2SFrank Rowand	printf "%s %s%s%s\n", $prefix, $line_num,  $timestamp, $line;
5028e4296c2SFrank Rowand}
5038e4296c2SFrank Rowand
5048e4296c2SFrank Rowandif (! $no_expect_stats) {
5058e4296c2SFrank Rowand	print  "\n";
5068e4296c2SFrank Rowand	print  "** EXPECT statistics:\n";
5078e4296c2SFrank Rowand	print  "**\n";
508*568a10bfSFrank Rowand	printf "**   non-zero values expected:\n";
509*568a10bfSFrank Rowand	print  "**\n";
510511f3aa7SFrank Rowand	printf "**     EXPECT found              : %4i\n", $exp_found;
511*568a10bfSFrank Rowand	printf "**     EXPECT_NOT not found      : %4i\n", $expnot_missing;
512*568a10bfSFrank Rowand	print  "**\n";
513*568a10bfSFrank Rowand	printf "**   zero values expected:\n";
514*568a10bfSFrank Rowand	print  "**\n";
515511f3aa7SFrank Rowand	printf "**     EXPECT not found          : %4i\n", $exp_missing;
516511f3aa7SFrank Rowand	printf "**     missing EXPECT begin      : %4i\n", $exp_missing_begin;
517511f3aa7SFrank Rowand	printf "**     missing EXPECT end        : %4i\n", $exp_missing_end;
518*568a10bfSFrank Rowand	print  "**\n";
519*568a10bfSFrank Rowand	printf "**     EXPECT_NOT found          : %4i\n", $expnot_found;
520*568a10bfSFrank Rowand	printf "**     missing EXPECT_NOT begin  : %4i\n", $expnot_missing_begin;
521*568a10bfSFrank Rowand	printf "**     missing EXPECT_NOT end    : %4i\n", $expnot_missing_end;
522*568a10bfSFrank Rowand	print  "**\n";
5238e4296c2SFrank Rowand	printf "**     unittest FAIL             : %4i\n", $unittest_fail;
5248e4296c2SFrank Rowand	printf "**     internal error            : %4i\n", $internal_err;
5258e4296c2SFrank Rowand}
5268e4296c2SFrank Rowand
527511f3aa7SFrank Rowandif (@exp_begin_stack) {
528*568a10bfSFrank Rowand	print "** ERROR: EXPECT begin without matching EXPECT end:\n";
5298e4296c2SFrank Rowand	print "          This list may be misleading.\n";
530511f3aa7SFrank Rowand	foreach $begin (@exp_begin_stack) {
5318e4296c2SFrank Rowand		print "       begin ---> $begin\n";
5328e4296c2SFrank Rowand	}
5338e4296c2SFrank Rowand}
534*568a10bfSFrank Rowand
535*568a10bfSFrank Rowandif (@expnot_begin_stack) {
536*568a10bfSFrank Rowand	print "** ERROR: EXPECT_NOT begin without matching EXPECT_NOT end:\n";
537*568a10bfSFrank Rowand	print "          This list may be misleading.\n";
538*568a10bfSFrank Rowand	foreach $begin (@expnot_begin_stack) {
539*568a10bfSFrank Rowand		print "       begin ---> $begin\n";
540*568a10bfSFrank Rowand	}
541*568a10bfSFrank Rowand}
542