Better test diagnostics for the numbers tests.
[p5sagit/p5-mst-13.2.git] / t / TEST
CommitLineData
8d063cd8 1#!./perl
2
8d063cd8 3# This is written in a peculiar style, since we're trying to avoid
1de9afcd 4# most of the constructs we'll be testing for. (This comment is
5# probably obsolete on the avoidance side, though still currrent
6# on the peculiarity side.)
8d063cd8 7
a687059c 8$| = 1;
9
60e23f2f 10# Let tests know they're running in the perl core. Useful for modules
11# which live dual lives on CPAN.
12$ENV{PERL_CORE} = 1;
13
cc6ae9e5 14# remove empty elements due to insertion of empty symbols via "''p1'" syntax
15@ARGV = grep($_,@ARGV) if $^O eq 'VMS';
16
5d9a6404 17# Cheesy version of Getopt::Std. Maybe we should replace it with that.
b326da91 18@argv = ();
5d9a6404 19if ($#ARGV >= 0) {
20 foreach my $idx (0..$#ARGV) {
b326da91 21 push( @argv, $ARGV[$idx] ), next unless $ARGV[$idx] =~ /^-(\S+)$/;
5a6e071d 22 $core = 1 if $1 eq 'core';
5d9a6404 23 $verbose = 1 if $1 eq 'v';
e018f8be 24 $torture = 1 if $1 eq 'torture';
1de9afcd 25 $with_utf8 = 1 if $1 eq 'utf8';
26 $with_utf16 = 1 if $1 eq 'utf16';
b26492ee 27 $bytecompile = 1 if $1 eq 'bytecompile';
28 $compile = 1 if $1 eq 'compile';
29 $taintwarn = 1 if $1 eq 'taintwarn';
43651d81 30 $ENV{PERL_CORE_MINITEST} = 1 if $1 eq 'minitest';
485988ae 31 if ($1 =~ /^deparse(,.+)?$/) {
32 $deparse = 1;
33 $deparse_opts = $1;
34 }
5d9a6404 35 }
8d063cd8 36}
b326da91 37@ARGV = @argv;
8d063cd8 38
378cc40b 39chdir 't' if -f 't/TEST';
40
3e6e8be7 41die "You need to run \"make test\" first to set things up.\n"
196918b0 42 unless -e 'perl' or -e 'perl.exe' or -e 'perl.pm';
4633a7c4 43
7a315204 44if ($ENV{PERL_3LOG}) { # Tru64 third(1) tool, see perlhack
09187cb1 45 unless (-x 'perl.third') {
46 unless (-x '../perl.third') {
47 die "You need to run \"make perl.third first.\n";
48 }
49 else {
50 print "Symlinking ../perl.third as perl.third...\n";
51 die "Failed to symlink: $!\n"
52 unless symlink("../perl.third", "perl.third");
53 die "Symlinked but no executable perl.third: $!\n"
54 unless -x 'perl.third';
55 }
56 }
57}
58
3fb91a5e 59# check leakage for embedders
60$ENV{PERL_DESTRUCT_LEVEL} = 2 unless exists $ENV{PERL_DESTRUCT_LEVEL};
61
4633a7c4 62$ENV{EMXSHELL} = 'sh'; # For OS/2
748a9306 63
24c841ba 64# Roll your own File::Find!
65use TestInit;
66use File::Spec;
67my $curdir = File::Spec->curdir;
68my $updir = File::Spec->updir;
69
70sub _find_tests {
71 my($dir) = @_;
93e325a7 72 opendir DIR, $dir or die "Trouble opening $dir: $!";
a1886d87 73 foreach my $f (sort { $a cmp $b } readdir DIR) {
0b834283 74 next if $f eq $curdir or $f eq $updir or
75 $f =~ /^(?:CVS|RCS|SCCS|\.svn)$/;
24c841ba 76
cc6ae9e5 77 my $fullpath = File::Spec->catfile($dir, $f);
24c841ba 78
79 _find_tests($fullpath) if -d $fullpath;
cc6ae9e5 80 $fullpath = VMS::Filespec::unixify($fullpath) if $^O eq 'VMS';
24c841ba 81 push @ARGV, $fullpath if $f =~ /\.t$/;
82 }
83}
84
cc6ae9e5 85sub _quote_args {
86 my ($args) = @_;
87 my $argstring = '';
88
89 foreach (split(/\s+/,$args)) {
90 # In VMS protect with doublequotes because otherwise
91 # DCL will lowercase -- unless already doublequoted.
92 $_ = q(").$_.q(") if ($^O eq 'VMS') && !/^\"/ && length($_) > 0;
93 $argstring .= ' ' . $_;
94 }
95 return $argstring;
96}
97
6234cb77 98sub _populate_hash {
99 return map {$_, 1} split /\s+/, $_[0];
100}
101
24c841ba 102unless (@ARGV) {
9f3d340b 103 foreach my $dir (qw(base comp cmd run io op uni)) {
24c841ba 104 _find_tests($dir);
105 }
5a6e071d 106 _find_tests("lib") unless $core;
6234cb77 107 # Config.pm may be broken for make minitest. And this is only a refinement
108 # for skipping tests on non-default builds, so it is allowed to fail.
109 # What we want to to is make a list of extensions which we did not build.
110 my $configsh = File::Spec->catfile($updir, "config.sh");
111 my %skip;
112 if (-f $configsh) {
113 my (%extensions, %known_extensions);
114 open FH, $configsh or die "Can't open $configsh: $!";
115 while (<FH>) {
116 if (/^extensions=['"](.*)['"]$/) {
117 # Deliberate string interpolation to avoid triggering possible
118 # $1 resetting bugs.
119 %extensions = _populate_hash ("$1");
120 }
121 elsif (/^known_extensions=['"](.*)['"]$/) {
122 %known_extensions = _populate_hash ($1);
123 }
124 }
125 if (%extensions) {
126 if (%known_extensions) {
127 foreach (keys %known_extensions) {
128 $skip{$_}++ unless $extensions{$_};
129 }
130 } else {
131 warn "No known_extensions line found in $configsh";
132 }
133 } else {
134 warn "No extensions line found in $configsh";
135 }
136 }
cc6ae9e5 137 my $mani = File::Spec->catfile($updir, "MANIFEST");
7a315204 138 if (open(MANI, $mani)) {
80ffb5f9 139 while (<MANI>) { # similar code in t/harness
6234cb77 140 if (m!^(ext/(\S+)/+(?:[^/\s]+\.t|test\.pl)|lib/\S+?(?:\.t|test\.pl))\s!) {
5a6e071d 141 $t = $1;
6234cb77 142 $extension = $2;
5a6e071d 143 if (!$core || $t =~ m!^lib/[a-z]!)
144 {
6234cb77 145 if (defined $extension) {
146 $extension =~ s!/t$!!;
147 # XXX Do I want to warn that I'm skipping these?
148 next if $skip{$extension};
149 }
cc6ae9e5 150 $path = File::Spec->catfile($updir, $t);
73ddec28 151 push @ARGV, $path;
152 $name{$path} = $t;
5a6e071d 153 }
7a315204 154 }
155 }
35d88760 156 close MANI;
7a315204 157 } else {
158 warn "$0: cannot open $mani: $!\n";
159 }
e018f8be 160 unless ($core) {
d44161bf 161 _find_tests('pod');
e018f8be 162 _find_tests('x2p');
163 _find_tests('japh') if $torture;
164 }
8d063cd8 165}
166
7a315204 167# Tests known to cause infinite loops for the perlcc tests.
595ae481 168# %infinite = ( 'comp/require.t', 1, 'op/bop.t', 1, 'lib/hostname.t', 1 );
24c841ba 169%infinite = ();
6ee623d5 170
485988ae 171if ($deparse) {
f193aa2f 172 _testprogs('deparse', '', @ARGV);
173}
1df34986 174elsif( $compile ) {
175 _testprogs('compile', '', @ARGV);
176}
177elsif( $bytecompile ) {
178 _testprogs('bytecompile', '', @ARGV);
f193aa2f 179}
1de9afcd 180elsif ($with_utf16) {
181 for my $e (0, 1) {
182 for my $b (0, 1) {
183 print STDERR "# ENDIAN $e BOM $b\n";
184 my @UARGV;
185 for my $a (@ARGV) {
186 my $u = $a . "." . ($e ? "l" : "b") . "e" . ($b ? "b" : "");
187 my $f = $e ? "v" : "n";
188 push @UARGV, $u;
189 unlink($u);
190 if (open(A, $a)) {
191 if (open(U, ">$u")) {
90f6ca78 192 print U pack("$f", 0xFEFF) if $b;
1de9afcd 193 while (<A>) {
194 print U pack("$f*", unpack("C*", $_));
195 }
196 close(A);
197 }
198 close(B);
199 }
200 }
201 _testprogs('perl', '', @UARGV);
202 unlink(@UARGV);
203 }
204 }
205}
f193aa2f 206else {
207 _testprogs('compile', '', @ARGV) if -e "../testcompile";
208 _testprogs('perl', '', @ARGV);
485988ae 209}
6ee623d5 210
bb365837 211sub _testprogs {
212 $type = shift @_;
f193aa2f 213 $args = shift;
bb365837 214 @tests = @_;
6ee623d5 215
bb365837 216 print <<'EOT' if ($type eq 'compile');
7a315204 217------------------------------------------------------------------------------
6ee623d5 218TESTING COMPILER
7a315204 219------------------------------------------------------------------------------
bb365837 220EOT
221
485988ae 222 print <<'EOT' if ($type eq 'deparse');
7a315204 223------------------------------------------------------------------------------
485988ae 224TESTING DEPARSER
7a315204 225------------------------------------------------------------------------------
485988ae 226EOT
227
566ece03 228 print <<EOT if ($type eq 'bytecompile');
1df34986 229------------------------------------------------------------------------------
230TESTING BYTECODE COMPILER
231------------------------------------------------------------------------------
232EOT
233
595ae481 234 $ENV{PERLCC_TIMEOUT} = 120
9636a016 235 if ($type eq 'compile' && !$ENV{PERLCC_TIMEOUT});
ef712cf7 236
bb365837 237 $bad = 0;
238 $good = 0;
239 $total = @tests;
240 $files = 0;
241 $totmax = 0;
73ddec28 242
cc6ae9e5 243 foreach my $t (@tests) {
244 unless (exists $name{$t}) {
245 my $tname = File::Spec->catfile('t',$t);
246 $tname = VMS::Filespec::unixify($tname) if $^O eq 'VMS';
247 $name{$t} = $tname;
248 }
73ddec28 249 }
908801fe 250 my $maxlen = 0;
73ddec28 251 foreach (@name{@tests}) {
252 s/\.\w+\z/./;
253 my $len = length ;
254 $maxlen = $len if $len > $maxlen;
088b5126 255 }
908801fe 256 # + 3 : we want three dots between the test name and the "ok"
73ddec28 257 $dotdotdot = $maxlen + 3 ;
7a834142 258 my $valgrind = 0;
da51b73c 259 my $valgrind_log = 'current.valgrind';
bb365837 260 while ($test = shift @tests) {
261
262 if ( $infinite{$test} && $type eq 'compile' ) {
595ae481 263 print STDERR "$test creates infinite loop! Skipping.\n";
bb365837 264 next;
6ee623d5 265 }
bb365837 266 if ($test =~ /^$/) {
267 next;
6ee623d5 268 }
485988ae 269 if ($type eq 'deparse') {
270 if ($test eq "comp/redef.t") {
271 # Redefinition happens at compile time
272 next;
273 }
7a834142 274 elsif ($test =~ m{lib/Switch/t/}) {
485988ae 275 # B::Deparse doesn't support source filtering
276 next;
277 }
278 }
cc6ae9e5 279 $te = $name{$test} . '.' x ($dotdotdot - length($name{$test}));
280
281 if ($^O ne 'VMS') { # defer printing on VMS due to piping bug
282 print $te;
283 $te = '';
284 }
bb365837 285
7a315204 286 $test = $OVER{$test} if exists $OVER{$test};
287
2f6bec1d 288 open(SCRIPT,"<$test") or die "Can't run $test.\n";
289 $_ = <SCRIPT>;
290 close(SCRIPT) unless ($type eq 'deparse');
90f6ca78 291 if ($with_utf16) {
292 $_ =~ tr/\0//d;
293 }
5dc83c40 294 if (/#!.*\bperl.*\s-\w*([tT])/) {
6537fe72 295 $switch = qq{"-$1"};
2f6bec1d 296 }
297 else {
b26492ee 298 if ($taintwarn) {
299 # not all tests are expected to pass with this option
300 $switch = '"-t"';
301 }
302 else {
303 $switch = '';
304 }
2f6bec1d 305 }
6ee623d5 306
b326da91 307 my $test_executable; # for 'compile' tests
485988ae 308 my $file_opts = "";
309 if ($type eq 'deparse') {
310 # Look for #line directives which change the filename
311 while (<SCRIPT>) {
312 $file_opts .= ",-f$3$4"
313 if /^#\s*line\s+(\d+)\s+((\w+)|"([^"]+)")/;
314 }
315 close(SCRIPT);
316 }
7a315204 317
1de9afcd 318 my $utf8 = $with_utf8 ? '-I../lib -Mutf8' : '';
4343e7c3 319 my $testswitch = '-I. -MTestInit'; # -T will strict . from @INC
485988ae 320 if ($type eq 'deparse') {
321 my $deparse =
127212b2 322 "./perl $testswitch $switch -I../lib -MO=-qq,Deparse,-sv1.,".
485988ae 323 "-l$deparse_opts$file_opts ".
7a315204 324 "$test > $test.dp ".
325 "&& ./perl $testswitch $switch -I../lib $test.dp |";
485988ae 326 open(RESULTS, $deparse)
327 or print "can't deparse '$deparse': $!.\n";
328 }
1df34986 329 elsif ($type eq 'bytecompile') {
c7e45529 330 my ($pwd, $null);
331 if( $^O eq 'MSWin32') {
332 $pwd = `cd`;
333 $null = 'nul';
334 } else {
335 $pwd = `pwd`;
336 $null = '/dev/null';
337 }
338 chomp $pwd;
339 my $perl = $ENV{PERL} || "$pwd/perl";
340 my $bswitch = "-MO=Bytecode,-H,-TI,-s$pwd/$test,";
566ece03 341 $bswitch .= "-TF$test.plc,"
1df34986 342 if $test =~ m(chdir|pod/|CGI/t/carp|lib/DB);
343 $bswitch .= "-k,"
344 if $test =~ m(deparse|terse|ext/Storable/t/code);
1df34986 345 $bswitch .= "-b,"
346 if $test =~ m(op/getpid);
347 my $bytecompile =
348 "$perl $testswitch $switch -I../lib $bswitch".
c7e45529 349 "-o$test.plc $test 2>$null &&".
1de9afcd 350 "$perl $testswitch $switch -I../lib $utf8 $test.plc |";
1df34986 351 open(RESULTS,$bytecompile)
352 or print "can't byte-compile '$bytecompile': $!.\n";
353 }
485988ae 354 elsif ($type eq 'perl') {
a7da9a42 355 my $perl = $ENV{PERL} || './perl';
da51b73c 356 my $redir = $^O eq 'VMS' ? '2>&1' : '';
7a834142 357 if ($ENV{PERL_VALGRIND}) {
d44161bf 358 $perl = "valgrind --suppressions=perl.supp --leak-check=yes "
359 . "--leak-resolution=high --show-reachable=yes "
da51b73c 360 . "--num-callers=50 --logfile-fd=3 $perl";
361 $redir = "3>$valgrind_log";
7a834142 362 }
1de9afcd 363 my $run = "$perl" . _quote_args("$testswitch $switch $utf8") . " $test $redir|";
be24517c 364 open(RESULTS,$run) or print "can't run '$run': $!.\n";
d638aca2 365 }
366 else {
b326da91 367 my $compile;
368 my $pl2c = "$testswitch -I../lib ../utils/perlcc --testsuite " .
9d2bbe64 369 # -O9 for good measure, -fcog is broken ATM
370 "$switch -Wb=-O9,-fno-cog -L .. " .
1de9afcd 371 "-I \".. ../lib/CORE\" $args $utf8 $test -o ";
b326da91 372
373 if( $^O eq 'MSWin32' ) {
374 $test_executable = "$test.exe";
375 # hopefully unused name...
376 open HACK, "> xweghyz.pl";
377 print HACK <<EOT;
378#!./perl
379
380open HACK, '.\\perl $pl2c $test_executable |';
381# cl.exe prints the name of the .c file on stdout (\%^\$^#)
6d73d07f 382while(<HACK>) {m/^\\w+\\.[cC]\$/ && next;print}
b326da91 383open HACK, '$test_executable |';
384while(<HACK>) {print}
385EOT
386 close HACK;
387 $compile = 'xweghyz.pl |';
388 }
389 else {
390 $test_executable = "$test.plc";
391 $compile = "./perl $pl2c $test_executable && $test_executable |";
392 }
393 unlink $test_executable if -f $test_executable;
be24517c 394 open(RESULTS, $compile)
395 or print "can't compile '$compile': $!.\n";
6ee623d5 396 }
d638aca2 397
b326da91 398 $ok = 0;
399 $next = 0;
21c74f43 400 my $seen_leader = 0;
401 my $seen_ok = 0;
bb365837 402 while (<RESULTS>) {
cc6ae9e5 403 next if /^\s*$/; # skip blank lines
bb365837 404 if ($verbose) {
405 print $_;
406 }
21c74f43 407 unless (/^\#/) {
809908f7 408 if (/^1\.\.([0-9]+)( todo ([\d ]+))?/) {
bb365837 409 $max = $1;
809908f7 410 %todo = map { $_ => 1 } split / /, $3 if $3;
bb365837 411 $totmax += $max;
412 $files += 1;
21c74f43 413 unless ($seen_ok) {
414 $next = 1;
415 $ok = 1;
416 }
417 $seen_leader = 1;
bb365837 418 }
419 else {
21c74f43 420 if (/^(not )?ok (\d+)[^\#]*(\s*\#.*)?/) {
421 unless ($seen_leader) {
422 unless ($seen_ok) {
423 $next = 1;
424 $ok = 1;
425 }
37ce32a7 426 }
21c74f43 427 $seen_ok = 1;
428 if ($2 == $next) {
429 my($not, $num, $extra) = ($1, $2, $3);
6c0731c3 430 my($istodo) = $extra =~ /#\s*TODO/ if $extra;
21c74f43 431 $istodo = 1 if $todo{$num};
432
433 if( $not && !$istodo ) {
434 $ok = 0;
435 $next = $num;
436 last;
437 }
438 else {
439 $next = $next + 1;
440 }
37ce32a7 441 }
d667a7e6 442 }
443 elsif (/^Bail out!\s*(.*)/i) { # magic words
444 die "FAILED--Further testing stopped" . ($1 ? ": $1\n" : ".\n");
bb365837 445 }
446 else {
447 $ok = 0;
448 }
8d063cd8 449 }
450 }
451 }
bb365837 452 close RESULTS;
7a834142 453 if ($ENV{PERL_VALGRIND}) {
da51b73c 454 my @valgrind;
455 if (-e $valgrind_log) {
456 if (open(V, $valgrind_log)) {
457 @valgrind = <V>;
458 close V;
459 } else {
460 warn "$0: Failed to open '$valgrind_log': $!\n";
461 }
462 }
7a834142 463 if (@valgrind) {
d44161bf 464 my $leaks = 0;
465 my $errors = 0;
7a834142 466 for my $i (0..$#valgrind) {
467 local $_ = $valgrind[$i];
d44161bf 468 if (/^==\d+== ERROR SUMMARY: (\d+) errors? /) {
469 $errors += $1; # there may be multiple error summaries
470 } elsif (/^==\d+== LEAK SUMMARY:/) {
471 for my $off (1 .. 4) {
472 if ($valgrind[$i+$off] =~
473 /(?:lost|reachable):\s+\d+ bytes in (\d+) blocks/) {
474 $leaks += $1;
475 }
476 }
7a834142 477 }
478 }
d44161bf 479 if ($errors or $leaks) {
da51b73c 480 if (rename $valgrind_log, "$test.valgrind") {
d44161bf 481 $valgrind++;
482 } else {
483 warn "$0: Failed to create '$test.valgrind': $!\n";
7a834142 484 }
485 }
486 } else {
487 warn "No valgrind output?\n";
488 }
da51b73c 489 if (-e $valgrind_log) {
490 unlink $valgrind_log
491 or warn "$0: Failed to unlink '$valgrind_log': $!\n";
492 }
7a834142 493 }
485988ae 494 if ($type eq 'deparse') {
495 unlink "./$test.dp";
496 }
211f317f 497 if ($ENV{PERL_3LOG}) {
498 my $tpp = $test;
3716a21d 499 $tpp =~ s:^\.\./::;
9c54ecba 500 $tpp =~ s:/:_:g;
3716a21d 501 $tpp =~ s:\.t$:.3log:;
502 rename("perl.3log", $tpp) ||
503 die "rename: perl3.log to $tpp: $!\n";
211f317f 504 }
bb365837 505 $next = $next - 1;
b326da91 506 # test if the compiler compiled something
507 if( $type eq 'compile' && !-e "$test_executable" ) {
508 $ok = 0;
509 print "Test did not compile\n";
510 }
511 if ($ok && $next == $max ) {
bb365837 512 if ($max) {
cc6ae9e5 513 print "${te}ok\n";
bb365837 514 $good = $good + 1;
515 }
516 else {
cc6ae9e5 517 print "${te}skipping test on this platform\n";
bb365837 518 $files -= 1;
519 }
bcce72a7 520 }
bb365837 521 else {
522 $next += 1;
26affc6c 523 if ($next > $max) {
524 print "${te}FAILED at test $next\tpossibly due to extra output\n";
525 }
526 else {
527 print "${te}FAILED at test $next\n";
528 }
bb365837 529 $bad = $bad + 1;
530 $_ = $test;
531 if (/^base/) {
532 die "Failed a basic test--cannot continue.\n";
533 }
8d063cd8 534 }
535 }
8d063cd8 536
bb365837 537 if ($bad == 0) {
538 if ($ok) {
539 print "All tests successful.\n";
540 # XXX add mention of 'perlbug -ok' ?
541 }
542 else {
543 die "FAILED--no tests were run for some reason.\n";
544 }
8d063cd8 545 }
bb365837 546 else {
ba1398cf 547 $pct = $files ? sprintf("%.2f", ($files - $bad) / $files * 100) : "0.00";
bb365837 548 if ($bad == 1) {
e824fb2c 549 warn "Failed 1 test script out of $files, $pct% okay.\n";
bb365837 550 }
551 else {
e824fb2c 552 warn "Failed $bad test scripts out of $files, $pct% okay.\n";
bb365837 553 }
4e4732c1 554 warn <<'SHRDLU_1';
f7d228c6 555### Since not all tests were successful, you may want to run some of
556### them individually and examine any diagnostic messages they produce.
557### See the INSTALL document's section on "make test".
4e4732c1 558SHRDLU_1
559 warn <<'SHRDLU_2' if $good / $total > 0.8;
f7d228c6 560### You have a good chance to get more information by running
561### ./perl harness
562### in the 't' directory since most (>=80%) of the tests succeeded.
4e4732c1 563SHRDLU_2
564 if (eval {require Config; import Config; 1}) {
e6af294e 565 if ($Config{usedl} && (my $p = $Config{ldlibpthname})) {
4e4732c1 566 warn <<SHRDLU_3;
f7d228c6 567### You may have to set your dynamic library search path,
568### $p, to point to the build directory:
4e4732c1 569SHRDLU_3
570 if (exists $ENV{$p} && $ENV{$p} ne '') {
571 warn <<SHRDLU_4a;
f7d228c6 572### setenv $p `pwd`:\$$p; cd t; ./perl harness
573### $p=`pwd`:\$$p; export $p; cd t; ./perl harness
574### export $p=`pwd`:\$$p; cd t; ./perl harness
4e4732c1 575SHRDLU_4a
576 } else {
577 warn <<SHRDLU_4b;
f7d228c6 578### setenv $p `pwd`; cd t; ./perl harness
579### $p=`pwd`; export $p; cd t; ./perl harness
580### export $p=`pwd`; cd t; ./perl harness
4e4732c1 581SHRDLU_4b
582 }
583 warn <<SHRDLU_5;
f7d228c6 584### for csh-style shells, like tcsh; or for traditional/modern
585### Bourne-style shells, like bash, ksh, and zsh, respectively.
4e4732c1 586SHRDLU_5
587 }
afd33fa9 588 }
bb365837 589 }
590 ($user,$sys,$cuser,$csys) = times;
591 print sprintf("u=%g s=%g cu=%g cs=%g scripts=%d tests=%d\n",
592 $user,$sys,$cuser,$csys,$files,$totmax);
7a834142 593 if ($ENV{PERL_VALGRIND}) {
594 my $s = $valgrind == 1 ? '' : 's';
595 print "$valgrind valgrind report$s created.\n", ;
596 }
6ee623d5 597}
3e6e8be7 598exit ($bad != 0);