(linenum→info "unix/slp.c:2238")

coreutils/6.9/tests/mk-script

    1: #! /usr/bin/perl -w
    2: # -*- perl -*-
    3: # Make test scripts.
    4: 
    5: # Copyright (C) 1998, 2000, 2001, 2002, 2003, 2005 Free Software
    6: # Foundation, Inc.
    7: 
    8: # This program is free software; you can redistribute it and/or modify
    9: # it under the terms of the GNU General Public License as published by
   10: # the Free Software Foundation; either version 2 of the License, or
   11: # (at your option) any later version.
   12: 
   13: # This program is distributed in the hope that it will be useful,
   14: # but WITHOUT ANY WARRANTY; without even the implied warranty of
   15: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16: # GNU General Public License for more details.
   17: 
   18: # You should have received a copy of the GNU General Public License
   19: # along with this program; if not, write to the Free Software
   20: # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
   21: # 02110-1301, USA.
   22: 
   23: my $In = '.I';
   24: my $Out = '.O';
   25: my $Exp = '.X';
   26: my $Err = '.E';
   27: 
   28: require 5.002;
   29: use strict;
   30: use POSIX qw (assert);
   31: 
   32: (my $ME = $0) =~ s|.*/||;
   33: 
   34: BEGIN { push @INC, '.' if '.' ne '.'; }
   35: use Test;
   36: 
   37: my $srcdir = shift;
   38: 
   39: sub validate
   40: {
   41:   my %seen;
   42:   my %seen_8dot3;
   43: 
   44:   my $bad_test_name;
   45:   my $test_vector;
   46:   foreach $test_vector (Test::test_vector ())
   47:     {
   48:       my ($test_name, $flags, $in_spec, $expected, $e_ret_code, $rest) =
   49:         @$test_vector;
   50:       die "$0: wrong number of elements in test $test_name\n"
   51:         if (!defined $e_ret_code || defined $rest);
   52:       assert (!ref $test_name);
   53:       assert (!ref $flags);
   54:       assert (!ref $e_ret_code);
   55: 
   56:       die "$0: duplicate test name \`$test_name'\n"
   57:         if (defined $seen{$test_name});
   58:       $seen{$test_name} = 1;
   59: 
   60:       if (0)
   61:         {
   62:           my $t8 = lc substr $test_name, 0, 8;
   63:           if ($seen_8dot3{$t8})
   64:             {
   65:               warn "$ME: 8.3 test name conflict: "
   66:                 . "$test_name, $seen_8dot3{$t8}\n";
   67:               $bad_test_name = 1;
   68:             }
   69:           $seen_8dot3{$t8} = $test_name;
   70:         }
   71:     }
   72: 
   73:   $bad_test_name
   74:     and exit 1;
   75: }
   76: 
   77: # Given a spec for the input file(s) or expected output file of a single
   78: # test, create a file for any string.  A file is created for each literal
   79: # string -- not for named files.  Whether a perl `string' is treated as
   80: # a string to be put in a file for a test or the name of an existing file
   81: # depends on how many references have to be traversed to get from
   82: # the top level variable to the actual string literal.
   83: # If $SPEC is a literal Perl string (not a reference), then treat $SPEC
   84: # as the contents of a file.
   85: # If $SPEC is a hash reference, then there are no inputs.
   86: # If $SPEC is an array reference, consider each element of the array.
   87: # If the element is a string reference, treat the string as the name of
   88: # an existing file.  Otherwise, the element must be a string and is treated
   89: # just like a scalar $SPEC.  When a file is created, its name is derived
   90: # from the name TEST_NAME of the corresponding test and the TYPE of file.
   91: # E.g., the inputs for test `3a' would be named t3a.in1 and t3a.in2, and
   92: # the expected output for test `7c' would be named t7c.exp.
   93: #
   94: # Also, return two lists of file names:
   95: # - maintainer-generated files -- names of files created by this function
   96: # - files named explicitly in Test.pm
   97: 
   98: sub spec_to_list ($$$)
   99: {
  100:   my ($spec, $test_name, $type) = @_;
  101: 
  102:   assert ($type eq $In || $type eq $Exp);
  103: 
  104:   my @explicit_file;
  105:   my @maint_gen_file;
  106:   my @content_string;
  107: 
  108:   # If SPEC is a hash reference, return empty lists.
  109:   if (ref $spec eq 'HASH')
  110:     {
  111:       assert ($type eq $In);
  112:       return {
  113:         EXPLICIT => \@explicit_file,
  114:         MAINT_GEN => \@maint_gen_file
  115:         };
  116:     }
  117: 
  118:   if (ref $spec)
  119:     {
  120:       assert (ref $spec eq 'ARRAY' || ref $spec eq 'HASH');
  121:       my $file_spec;
  122:       foreach $file_spec (@$spec)
  123:         {
  124:           # A file spec may be a string or a reference.
  125:           # If it's a string, that string is to be the contents of a
  126:           # generated (by this script) file with name derived from the
  127:           # name of this test.
  128:           # If it's a reference, then it must be the name of an existing
  129:           # file.
  130:           if (ref $file_spec)
  131:             {
  132:               my $r = ref $file_spec;
  133:               die "bad test: $test_name is $r\n"
  134:                 if ref $file_spec ne 'SCALAR';
  135:               my $existing_file = $$file_spec;
  136:               # FIXME: make sure $existing_file exists somewhere.
  137:               push (@explicit_file, $existing_file);
  138:             }
  139:           else
  140:             {
  141:               push (@content_string, $file_spec);
  142:             }
  143:         }
  144:     }
  145:   else
  146:     {
  147:       push (@content_string, $spec);
  148:     }
  149: 
  150:   my $i = 1;
  151:   my $file_contents;
  152:   foreach $file_contents (@content_string)
  153:     {
  154:       my $suffix = (@content_string > 1 ? $i : '');
  155:       my $maint_gen_file = "$test_name$type$suffix";
  156:       push (@maint_gen_file, $maint_gen_file);
  157:       open (F, ">$srcdir/$maint_gen_file") || die "$0: $maint_gen_file: $!\n";
  158:       print F $file_contents;
  159:       close (F) || die "$0: $maint_gen_file: $!\n";
  160:       ++$i;
  161:     }
  162: 
  163:   my $n_fail = 0;
  164:   foreach $i (@explicit_file, @maint_gen_file)
  165:     {
  166:       my $max_len = 14;
  167:       if (length ($i) > $max_len)
  168:         {
  169:           warn "$0: $i: generated test file name would be longer than"
  170:             . " $max_len characters\n";
  171:           ++$n_fail;
  172:         }
  173:     }
  174:   exit (1) if $n_fail;
  175: 
  176:   my %h = (
  177:     EXPLICIT => \@explicit_file,
  178:     MAINT_GEN => \@maint_gen_file
  179:   );
  180: 
  181:   return \%h;
  182: }
  183: 
  184: sub wrap
  185: {
  186:   my ($preferred_line_len, @tok) = @_;
  187:   assert ($preferred_line_len > 0);
  188:   my @lines;
  189:   my $line = '';
  190:   my $word;
  191:   foreach $word (@tok)
  192:     {
  193:       if ($line && length ($line) + 1 + length ($word) > $preferred_line_len)
  194:         {
  195:           push (@lines, $line);
  196:           $line = $word;
  197:           next;
  198:         }
  199:       my $sp = ($line ? ' ' : '');
  200:       $line .= "$sp$word";
  201:     }
  202:   push (@lines, $line);
  203:   return @lines;
  204: }
  205: 
  206: # ~~~~~~~ main ~~~~~~~~
  207: {
  208:   $| = 1;
  209: 
  210:   die "Usage: $0: srcdir program-name\n" if @ARGV != 1;
  211: 
  212:   my $xx = $ARGV[0];
  213: 
  214:   if ($xx eq '--list')
  215:     {
  216:       validate ();
  217:       # Output three lists of files:
  218:       # EXPLICIT -- file names specified in Test.pm
  219:       # MAINT_GEN -- maintainer-generated files
  220:       # RUN_GEN -- files created when running the tests
  221:       my $test_vector;
  222:       my @exp;
  223:       my @maint;
  224:       my @run;
  225:       foreach $test_vector (Test::test_vector ())
  226:         {
  227:           my ($test_name, $flags, $in_spec, $exp_spec, $e_ret_code)
  228:             = @$test_vector;
  229: 
  230:           push (@run, ("$test_name$Out", "$test_name$Err"));
  231: 
  232:           my $in = spec_to_list ($in_spec, $test_name, $In);
  233:           push (@exp, @{$in->{EXPLICIT}});
  234:           push (@maint, @{$in->{MAINT_GEN}});
  235: 
  236:           my $e = spec_to_list ($exp_spec, $test_name, $Exp);
  237:           push (@exp, @{$e->{EXPLICIT}});
  238:           push (@maint, @{$e->{MAINT_GEN}});
  239:         }
  240: 
  241:       # The list of explicitly mentioned files may contain duplicates.
  242:       # Eliminated any duplicates.
  243:       my %e = map {$_ => 1} @exp;
  244:       @exp = sort keys %e;
  245: 
  246:       my $len = 77;
  247:       print join (" \\\n", wrap ($len, 'explicit =', @exp)), "\n";
  248:       print join (" \\\n", wrap ($len, 'maint_gen =', @maint)), "\n";
  249:       print join (" \\\n", wrap ($len, 'run_gen =', @run)), "\n";
  250: 
  251:       exit 0;
  252:     }
  253: 
  254:   print <<EOF1;
  255: #! /bin/sh
  256: # This script was generated automatically by $ME.
  257: case \$# in
  258:   0\) xx='$xx';;
  259:   *\) xx="\$1";;
  260: esac
  261: test "\$VERBOSE" && echo=echo || echo=:
  262: \$echo testing program: \$xx
  263: errors=0
  264: test "\$srcdir" || srcdir=.
  265: test "\$VERBOSE" && \$xx --version 2> /dev/null
  266: 
  267: # Make sure we get English translations.
  268: LANGUAGE=C
  269: export LANGUAGE
  270: LC_ALL=C
  271: export LC_ALL
  272: LANG=C
  273: export LANG
  274: 
  275: EOF1
  276: 
  277:   validate ();
  278: 
  279:   my $n_tests = 0;
  280:   my $test_vector;
  281:   foreach $test_vector (Test::test_vector ())
  282:     {
  283:       my ($test_name, $flags, $in_spec, $exp_spec, $e_ret_code)
  284:         = @$test_vector;
  285: 
  286:       my $in = spec_to_list ($in_spec, $test_name, $In);
  287: 
  288:       my @srcdir_rel_in_file;
  289:       my $f;
  290:       foreach $f (@{$in->{EXPLICIT}}, @{$in->{MAINT_GEN}})
  291:         {
  292:           push (@srcdir_rel_in_file, "\$srcdir/$f");
  293:         }
  294: 
  295:       my $exp = spec_to_list ($exp_spec, $test_name, $Exp);
  296:       my @all = (@{$exp->{EXPLICIT}}, @{$exp->{MAINT_GEN}});
  297:       assert (@all == 1);
  298:       my $exp_name = "\$srcdir/$all[0]";
  299:       my $out = "$test_name$Out";
  300:       my $err_output = "$test_name$Err";
  301: 
  302:       my %valid_via = map {$_ => 1} qw (REDIR FILE PIPE);
  303:       my %via_msg_string = (REDIR => '<', FILE => 'F', PIPE => '|');
  304: 
  305:       # Inhibit warnings about `used only once'.
  306:       die if 0 && $Test::input_via{$test_name} && $Test::input_via_default;
  307:       die if 0 && $Test::env{$test_name} && $Test::env_default;
  308: 
  309:       my $vias = $Test::input_via{$test_name} || $Test::input_via_default
  310:         || {FILE => 0};
  311: 
  312:       my $n_vias = keys %$vias;
  313:       my $via;
  314:       foreach $via (sort keys %$vias)
  315:         {
  316:           my $cmd;
  317:           my $val = $vias->{$via};
  318:           my $via_msg = ($n_vias == 1 ? '' : $via_msg_string{$via});
  319:           my $file_args = join (' ', @srcdir_rel_in_file);
  320: 
  321:           my $env = $Test::env{$test_name} || $Test::env_default || [''];
  322:           @$env == 1
  323:             or die "$ME: unexpected environment: @$env\n";
  324:           $env = $env->[0];
  325:           my $env_prefix = ($env ? "$env " : '');
  326: 
  327:           if ($via eq 'FILE')
  328:             {
  329:               $cmd = "$env_prefix\$xx $flags $file_args > $out 2> $err_output";
  330:             }
  331:           elsif ($via eq 'PIPE')
  332:             {
  333:               $via_msg = "|$val" if $val;
  334:               $val ||= 'cat';
  335:               $cmd = "$val $file_args | $env_prefix\$xx $flags"
  336:                 . " > $out 2> $err_output";
  337:             }
  338:           else
  339:             {
  340:               assert (@srcdir_rel_in_file == 1);
  341:               $cmd = "$env_prefix\$xx $flags"
  342:                 . " < $file_args > $out 2> $err_output";
  343:             }
  344: 
  345:           my $e = $env;
  346:           my $sep = ($via_msg && $e ? ':' : '');
  347:           my $msg = "$e$sep$via_msg";
  348:           $msg = "($msg)" if $msg;
  349:           my $t_name = "$test_name$msg";
  350:           ++$n_tests;
  351:           print <<EOF;
  352: $cmd
  353: code=\$?
  354: if test \$code != $e_ret_code; then
  355:   \$echo "Test $t_name failed: \$xx return code \$code differs from expected value $e_ret_code" 1>&2
  356:   errors=`expr \$errors + 1`
  357: else
  358:   cmp $out $exp_name > /dev/null 2>&1
  359:   case \$? in
  360:     0) if test "\$VERBOSE"; then \$echo "passed $t_name"; fi;;
  361:     1) \$echo "Test $t_name failed: files $out and $exp_name differ" 1>&2
  362:        (diff -c $out $exp_name) 2> /dev/null
  363:        errors=`expr \$errors + 1`;;
  364:     2) \$echo "Test $t_name may have failed." 1>&2
  365:        \$echo The command \"cmp $out $exp_name\" failed. 1>&2
  366:        errors=`expr \$errors + 1`;;
  367:   esac
  368: fi
  369: test -s $err_output || rm -f $err_output
  370: EOF
  371:         }
  372:     }
  373:   print <<EOF3
  374: if test \$errors = 0; then
  375:   \$echo Passed all $n_tests tests. 1>&2
  376: else
  377:   \$echo Failed \$errors tests. 1>&2
  378: fi
  379: test \$errors = 0 || errors=1
  380: exit \$errors
  381: EOF3
  382: }
Syntax (Markdown)