home *** CD-ROM | disk | FTP | other *** search
- Subject: v20i101: Perl, a language with features of C/sed/awk/sehll/etc, Part18/24
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Larry Wall <lwall@jpl-devvax.jpl.nasa.gov>
- Posting-number: Volume 20, Issue 101
- Archive-name: perl3.0/part18
-
- #! /bin/sh
-
- # Make a new directory for the perl sources, cd to it, and run kits 1
- # thru 24 through sh. When all 24 kits have been run, read README.
-
- echo "This is perl 3.0 kit 18 (of 24). If kit 18 is complete, the line"
- echo '"'"End of kit 18 (of 24)"'" will echo at the end.'
- echo ""
- export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
- mkdir lib t x2p 2>/dev/null
- echo Extracting x2p/s2p.SH
- sed >x2p/s2p.SH <<'!STUFFY!FUNK!' -e 's/X//'
- X: This forces SH files to create target in same directory as SH file.
- X: This is so that make depend always knows where to find SH derivatives.
- Xcase "$0" in
- X*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
- Xesac
- Xcase $CONFIG in
- X'')
- X if test ! -f config.sh; then
- X ln ../config.sh . || \
- X ln ../../config.sh . || \
- X ln ../../../config.sh . || \
- X (echo "Can't find config.sh."; exit 1)
- X fi
- X . config.sh
- X ;;
- Xesac
- Xecho "Extracting s2p (with variable substitutions)"
- X: This section of the file will have variable substitutions done on it.
- X: Move anything that needs config subs from !NO!SUBS! section to !GROK!THIS!.
- X: Protect any dollar signs and backticks that you do not want interpreted
- X: by putting a backslash in front. You may delete these comments.
- X$spitshell >s2p <<!GROK!THIS!
- X#!$bin/perl
- X
- X\$bin = '$bin';
- X!GROK!THIS!
- X
- X: In the following dollars and backticks do not need the extra backslash.
- X$spitshell >>s2p <<'!NO!SUBS!'
- X
- X# $Header: s2p.SH,v 3.0 89/10/18 15:35:02 lwall Locked $
- X#
- X# $Log: s2p.SH,v $
- X# Revision 3.0 89/10/18 15:35:02 lwall
- X# 3.0 baseline
- X#
- X# Revision 2.0.1.1 88/07/11 23:26:23 root
- X# patch2: s2p didn't put a proper prologue on output script
- X#
- X# Revision 2.0 88/06/05 00:15:55 root
- X# Baseline version 2.0.
- X#
- X#
- X
- X$indent = 4;
- X$shiftwidth = 4;
- X$l = '{'; $r = '}';
- X$tempvar = '1';
- X
- Xwhile ($ARGV[0] =~ '^-') {
- X $_ = shift;
- X last if /^--/;
- X if (/^-D/) {
- X $debug++;
- X open(body,'>-');
- X next;
- X }
- X if (/^-n/) {
- X $assumen++;
- X next;
- X }
- X if (/^-p/) {
- X $assumep++;
- X next;
- X }
- X die "I don't recognize this switch: $_\n";
- X}
- X
- Xunless ($debug) {
- X open(body,">/tmp/sperl$$") || do Die("Can't open temp file");
- X}
- X
- Xif (!$assumen && !$assumep) {
- X print body
- X'while ($ARGV[0] =~ /^-/) {
- X $_ = shift;
- X last if /^--/;
- X if (/^-n/) {
- X $nflag++;
- X next;
- X }
- X die "I don\'t recognize this switch: $_\\n";
- X}
- X
- X';
- X}
- X
- Xprint body '
- X#ifdef PRINTIT
- X#ifdef ASSUMEP
- X$printit++;
- X#else
- X$printit++ unless $nflag;
- X#endif
- X#endif
- Xline: while (<>) {
- X';
- X
- Xline: while (<>) {
- X s/[ \t]*(.*)\n$/$1/;
- X if (/^:/) {
- X s/^:[ \t]*//;
- X $label = do make_label($_);
- X if ($. == 1) {
- X $toplabel = $label;
- X }
- X $_ = "$label:";
- X if ($lastlinewaslabel++) {$_ .= "\t;";}
- X if ($indent >= 2) {
- X $indent -= 2;
- X $indmod = 2;
- X }
- X next;
- X } else {
- X $lastlinewaslabel = '';
- X }
- X $addr1 = '';
- X $addr2 = '';
- X if (s/^([0-9]+)//) {
- X $addr1 = "$1";
- X }
- X elsif (s/^\$//) {
- X $addr1 = 'eof()';
- X }
- X elsif (s|^/||) {
- X $addr1 = do fetchpat('/');
- X }
- X if (s/^,//) {
- X if (s/^([0-9]+)//) {
- X $addr2 = "$1";
- X } elsif (s/^\$//) {
- X $addr2 = "eof()";
- X } elsif (s|^/||) {
- X $addr2 = do fetchpat('/');
- X } else {
- X do Die("Invalid second address at line $.\n");
- X }
- X $addr1 .= " .. $addr2";
- X }
- X # a { to keep vi happy
- X s/^[ \t]+//;
- X if ($_ eq '}') {
- X $indent -= 4;
- X next;
- X }
- X if (s/^!//) {
- X $if = 'unless';
- X $else = "$r else $l\n";
- X } else {
- X $if = 'if';
- X $else = '';
- X }
- X if (s/^{//) { # a } to keep vi happy
- X $indmod = 4;
- X $redo = $_;
- X $_ = '';
- X $rmaybe = '';
- X } else {
- X $rmaybe = "\n$r";
- X if ($addr2 || $addr1) {
- X $space = ' ' x $shiftwidth;
- X } else {
- X $space = '';
- X }
- X $_ = do transmogrify();
- X }
- X
- X if ($addr1) {
- X if ($_ !~ /[\n{}]/ && $rmaybe && !$change &&
- X $_ !~ / if / && $_ !~ / unless /) {
- X s/;$/ $if $addr1;/;
- X $_ = substr($_,$shiftwidth,1000);
- X } else {
- X $command = $_;
- X $_ = "$if ($addr1) $l\n$change$command$rmaybe";
- X }
- X $change = '';
- X next line;
- X }
- X} continue {
- X @lines = split(/\n/,$_);
- X while ($#lines >= 0) {
- X $_ = shift(lines);
- X unless (s/^ *<<--//) {
- X print body "\t" x ($indent / 8), ' ' x ($indent % 8);
- X }
- X print body $_, "\n";
- X }
- X $indent += $indmod;
- X $indmod = 0;
- X if ($redo) {
- X $_ = $redo;
- X $redo = '';
- X redo line;
- X }
- X}
- X
- Xprint body "}\n";
- Xif ($appendseen || $tseen || !$assumen) {
- X $printit++ if $dseen || (!$assumen && !$assumep);
- X print body '
- Xcontinue {
- X#ifdef PRINTIT
- X#ifdef DSEEN
- X#ifdef ASSUMEP
- X print if $printit++;
- X#else
- X if ($printit) { print;} else { $printit++ unless $nflag; }
- X#endif
- X#else
- X print if $printit;
- X#endif
- X#else
- X print;
- X#endif
- X#ifdef TSEEN
- X $tflag = \'\';
- X#endif
- X#ifdef APPENDSEEN
- X if ($atext) { print $atext; $atext = \'\'; }
- X#endif
- X}
- X';
- X}
- X
- Xclose body;
- X
- Xunless ($debug) {
- X open(head,">/tmp/sperl2$$.c") || do Die("Can't open temp file 2");
- X print head "#define PRINTIT\n" if ($printit);
- X print head "#define APPENDSEEN\n" if ($appendseen);
- X print head "#define TSEEN\n" if ($tseen);
- X print head "#define DSEEN\n" if ($dseen);
- X print head "#define ASSUMEN\n" if ($assumen);
- X print head "#define ASSUMEP\n" if ($assumep);
- X if ($opens) {print head "$opens\n";}
- X open(body,"/tmp/sperl$$") || do Die("Can't reopen temp file");
- X while (<body>) {
- X print head $_;
- X }
- X close head;
- X
- X print "#!$bin/perl
- Xeval \"exec $bin/perl -S \$0 \$*\"
- X if \$running_under_some_shell;
- X
- X";
- X open(body,"cc -E /tmp/sperl2$$.c |") ||
- X do Die("Can't reopen temp file");
- X while (<body>) {
- X /^# [0-9]/ && next;
- X /^[ \t]*$/ && next;
- X s/^<><>//;
- X print;
- X }
- X}
- X
- Xunlink "/tmp/sperl$$", "/tmp/sperl2$$";
- X
- Xsub Die {
- X unlink "/tmp/sperl$$", "/tmp/sperl2$$";
- X die $_[0];
- X}
- Xsub make_filehandle {
- X $fname = $_ = $_[0];
- X s/[^a-zA-Z]/_/g;
- X s/^_*//;
- X if (/^([a-z])([a-z]*)$/) {
- X $first = $1;
- X $rest = $2;
- X $first =~ y/a-z/A-Z/;
- X $_ = $first . $rest;
- X }
- X if (!$seen{$_}) {
- X $opens .= "open($_,'>$fname') || die \"Can't create $fname\";\n";
- X }
- X $seen{$_} = $_;
- X}
- X
- Xsub make_label {
- X $label = $_[0];
- X $label =~ s/[^a-zA-Z0-9]/_/g;
- X if ($label =~ /^[0-9_]/) { $label = 'L' . $label; }
- X $label = substr($label,0,8);
- X if ($label =~ /^([a-z])([a-z]*)$/) { # could be reserved word
- X $first = $1;
- X $rest = $2;
- X $first =~ y/a-z/A-Z/; # so capitalize it
- X $label = $first . $rest;
- X }
- X $label;
- X}
- X
- Xsub transmogrify {
- X { # case
- X if (/^d/) {
- X $dseen++;
- X $_ = '
- X<<--#ifdef PRINTIT
- X$printit = \'\';
- X<<--#endif
- Xnext line;';
- X next;
- X }
- X
- X if (/^n/) {
- X $_ =
- X'<<--#ifdef PRINTIT
- X<<--#ifdef DSEEN
- X<<--#ifdef ASSUMEP
- Xprint if $printit++;
- X<<--#else
- Xif ($printit) { print;} else { $printit++ unless $nflag; }
- X<<--#endif
- X<<--#else
- Xprint if $printit;
- X<<--#endif
- X<<--#else
- Xprint;
- X<<--#endif
- X<<--#ifdef APPENDSEEN
- Xif ($atext) {print $atext; $atext = \'\';}
- X<<--#endif
- X$_ = <>;
- X<<--#ifdef TSEEN
- X$tflag = \'\';
- X<<--#endif';
- X next;
- X }
- X
- X if (/^a/) {
- X $appendseen++;
- X $command = $space . '$atext .=' . "\n<<--'";
- X $lastline = 0;
- X while (<>) {
- X s/^[ \t]*//;
- X s/^[\\]//;
- X unless (s|\\$||) { $lastline = 1;}
- X s/'/\\'/g;
- X s/^([ \t]*\n)/<><>$1/;
- X $command .= $_;
- X $command .= '<<--';
- X last if $lastline;
- X }
- X $_ = $command . "';";
- X last;
- X }
- X
- X if (/^[ic]/) {
- X if (/^c/) { $change = 1; }
- X $addr1 = '$iter = (' . $addr1 . ')';
- X $command = $space . 'if ($iter == 1) { print' . "\n<<--'";
- X $lastline = 0;
- X while (<>) {
- X s/^[ \t]*//;
- X s/^[\\]//;
- X unless (s/\\$//) { $lastline = 1;}
- X s/'/\\'/g;
- X s/^([ \t]*\n)/<><>$1/;
- X $command .= $_;
- X $command .= '<<--';
- X last if $lastline;
- X }
- X $_ = $command . "';}";
- X if ($change) {
- X $dseen++;
- X $change = "$_\n";
- X $_ = "
- X<<--#ifdef PRINTIT
- X$space\$printit = '';
- X<<--#endif
- X${space}next line;";
- X }
- X last;
- X }
- X
- X if (/^s/) {
- X $delim = substr($_,1,1);
- X $len = length($_);
- X $repl = $end = 0;
- X $inbracket = 0;
- X for ($i = 2; $i < $len; $i++) {
- X $c = substr($_,$i,1);
- X if ($c eq $delim) {
- X if ($inbracket) {
- X $_ = substr($_,0,$i) . '\\' . substr($_,$i,10000);
- X $i++;
- X $len++;
- X }
- X else {
- X if ($repl) {
- X $end = $i;
- X last;
- X } else {
- X $repl = $i;
- X }
- X }
- X }
- X elsif ($c eq '\\') {
- X $i++;
- X if ($i >= $len) {
- X $_ .= 'n';
- X $_ .= <>;
- X $len = length($_);
- X $_ = substr($_,0,--$len);
- X }
- X elsif (!$repl && substr($_,$i,1) =~ /^[(){}\w]$/) {
- X $i--;
- X $len--;
- X $_ = substr($_,0,$i) . substr($_,$i+1,10000);
- X }
- X }
- X elsif ($c eq '[' && !$repl) {
- X $i++ if substr($_,$i,1) eq '^';
- X $i++ if substr($_,$i,1) eq ']';
- X $inbracket = 1;
- X }
- X elsif ($c eq ']') {
- X $inbracket = 0;
- X }
- X elsif (!$repl && index("()",$c) >= 0) {
- X $_ = substr($_,0,$i) . '\\' . substr($_,$i,10000);
- X $i++;
- X $len++;
- X }
- X }
- X do Die("Malformed substitution at line $.\n") unless $end;
- X $pat = substr($_, 0, $repl + 1);
- X $repl = substr($_, $repl + 1, $end - $repl - 1);
- X $end = substr($_, $end + 1, 1000);
- X $dol = '$';
- X $repl =~ s/\$/\\$/;
- X $repl =~ s'&'$&'g;
- X $repl =~ s/[\\]([0-9])/$dol$1/g;
- X $subst = "$pat$repl$delim";
- X $cmd = '';
- X while ($end) {
- X if ($end =~ s/^g//) { $subst .= 'g'; next; }
- X if ($end =~ s/^p//) { $cmd .= ' && (print)'; next; }
- X if ($end =~ s/^w[ \t]*//) {
- X $fh = do make_filehandle($end);
- X $cmd .= " && (print $fh \$_)";
- X $end = '';
- X next;
- X }
- X do Die("Unrecognized substitution command ($end) at line $.\n");
- X }
- X $_ =
- X"<<--#ifdef TSEEN
- X$subst && \$tflag++$cmd;
- X<<--#else
- X$subst$cmd;
- X<<--#endif";
- X next;
- X }
- X
- X if (/^p/) {
- X $_ = 'print;';
- X next;
- X }
- X
- X if (/^w/) {
- X s/^w[ \t]*//;
- X $fh = do make_filehandle($_);
- X $_ = "print $fh \$_;";
- X next;
- X }
- X
- X if (/^r/) {
- X $appendseen++;
- X s/^r[ \t]*//;
- X $file = $_;
- X $_ = "\$atext .= `cat $file 2>/dev/null`;";
- X next;
- X }
- X
- X if (/^P/) {
- X $_ = 'print $1 if /(^.*\n)/;';
- X next;
- X }
- X
- X if (/^D/) {
- X $_ =
- X's/^.*\n//;
- Xredo line if $_;
- Xnext line;';
- X next;
- X }
- X
- X if (/^N/) {
- X $_ = '
- X$_ .= <>;
- X<<--#ifdef TSEEN
- X$tflag = \'\';
- X<<--#endif';
- X next;
- X }
- X
- X if (/^h/) {
- X $_ = '$hold = $_;';
- X next;
- X }
- X
- X if (/^H/) {
- X $_ = '$hold .= $_ ? $_ : "\n";';
- X next;
- X }
- X
- X if (/^g/) {
- X $_ = '$_ = $hold;';
- X next;
- X }
- X
- X if (/^G/) {
- X $_ = '$_ .= $hold ? $hold : "\n";';
- X next;
- X }
- X
- X if (/^x/) {
- X $_ = '($_, $hold) = ($hold, $_);';
- X next;
- X }
- X
- X if (/^b$/) {
- X $_ = 'next line;';
- X next;
- X }
- X
- X if (/^b/) {
- X s/^b[ \t]*//;
- X $lab = do make_label($_);
- X if ($lab eq $toplabel) {
- X $_ = 'redo line;';
- X } else {
- X $_ = "goto $lab;";
- X }
- X next;
- X }
- X
- X if (/^t$/) {
- X $_ = 'next line if $tflag;';
- X $tseen++;
- X next;
- X }
- X
- X if (/^t/) {
- X s/^t[ \t]*//;
- X $lab = do make_label($_);
- X if ($lab eq $toplabel) {
- X $_ = 'if ($tflag) {$tflag = \'\'; redo line;}';
- X } else {
- X $_ = "if (\$tflag) {\$tflag = ''; goto $lab;}";
- X }
- X $tseen++;
- X next;
- X }
- X
- X if (/^=/) {
- X $_ = 'print "$.\n";';
- X next;
- X }
- X
- X if (/^q/) {
- X $_ =
- X'close(ARGV);
- X@ARGV = ();
- Xnext line;';
- X next;
- X }
- X } continue {
- X if ($space) {
- X s/^/$space/;
- X s/(\n)(.)/$1$space$2/g;
- X }
- X last;
- X }
- X $_;
- X}
- X
- Xsub fetchpat {
- X local($outer) = @_;
- X local($addr) = $outer;
- X local($inbracket);
- X local($prefix,$delim,$ch);
- X
- X delim: while (s:^([^\](|)[\\/]*)([](|)[\\/])::) {
- X $prefix = $1;
- X $delim = $2;
- X print "$prefix\t$delim\t$_\n";
- X if ($delim eq '\\') {
- X s/(.)//;
- X $ch = $1;
- X $delim = '' if $ch =~ /^[(){}\w]$/;
- X $delim .= $1;
- X }
- X elsif ($delim eq '[') {
- X $inbracket = 1;
- X s/^\^// && ($delim .= '^');
- X s/^]// && ($delim .= ']');
- X print "$prefix\t$delim\t$_\n";
- X }
- X elsif ($delim eq ']') {
- X $inbracket = 0;
- X }
- X elsif ($inbracket || $delim ne $outer) {
- X print "Adding\n";
- X $delim = '\\' . $delim;
- X }
- X $addr .= $prefix;
- X $addr .= $delim;
- X if ($delim eq $outer && !$inbracket) {
- X last delim;
- X }
- X }
- X $addr;
- X}
- X
- X!NO!SUBS!
- Xchmod 755 s2p
- X$eunicefix s2p
- !STUFFY!FUNK!
- echo Extracting hash.c
- sed >hash.c <<'!STUFFY!FUNK!' -e 's/X//'
- X/* $Header: hash.c,v 3.0 89/10/18 15:18:32 lwall Locked $
- X *
- X * Copyright (c) 1989, Larry Wall
- X *
- X * You may distribute under the terms of the GNU General Public License
- X * as specified in the README file that comes with the perl 3.0 kit.
- X *
- X * $Log: hash.c,v $
- X * Revision 3.0 89/10/18 15:18:32 lwall
- X * 3.0 baseline
- X *
- X */
- X
- X#include "EXTERN.h"
- X#include "perl.h"
- X#include <errno.h>
- X
- Xextern int errno;
- X
- XSTR *
- Xhfetch(tb,key,klen,lval)
- Xregister HASH *tb;
- Xchar *key;
- Xint klen;
- Xint lval;
- X{
- X register char *s;
- X register int i;
- X register int hash;
- X register HENT *entry;
- X register int maxi;
- X STR *str;
- X#ifdef SOME_DBM
- X datum dkey,dcontent;
- X#endif
- X
- X if (!tb)
- X return Nullstr;
- X
- X /* The hash function we use on symbols has to be equal to the first
- X * character when taken modulo 128, so that str_reset() can be implemented
- X * efficiently. We throw in the second character and the last character
- X * (times 128) so that long chains of identifiers starting with the
- X * same letter don't have to be strEQ'ed within hfetch(), since it
- X * compares hash values before trying strEQ().
- X */
- X if (!tb->tbl_coeffsize)
- X hash = *key + 128 * key[1] + 128 * key[klen-1]; /* assuming klen > 0 */
- X else { /* use normal coefficients */
- X if (klen < tb->tbl_coeffsize)
- X maxi = klen;
- X else
- X maxi = tb->tbl_coeffsize;
- X for (s=key, i=0, hash = 0;
- X i < maxi;
- X s++, i++, hash *= 5) {
- X hash += *s * coeff[i];
- X }
- X }
- X
- X entry = tb->tbl_array[hash & tb->tbl_max];
- X for (; entry; entry = entry->hent_next) {
- X if (entry->hent_hash != hash) /* strings can't be equal */
- X continue;
- X if (entry->hent_klen != klen)
- X continue;
- X if (bcmp(entry->hent_key,key,klen)) /* is this it? */
- X continue;
- X return entry->hent_val;
- X }
- X#ifdef SOME_DBM
- X if (tb->tbl_dbm) {
- X dkey.dptr = key;
- X dkey.dsize = klen;
- X dcontent = dbm_fetch(tb->tbl_dbm,dkey);
- X if (dcontent.dptr) { /* found one */
- X str = Str_new(60,dcontent.dsize);
- X str_nset(str,dcontent.dptr,dcontent.dsize);
- X hstore(tb,key,klen,str,hash); /* cache it */
- X return str;
- X }
- X }
- X#endif
- X if (lval) { /* gonna assign to this, so it better be there */
- X str = Str_new(61,0);
- X hstore(tb,key,klen,str,hash);
- X return str;
- X }
- X return Nullstr;
- X}
- X
- Xbool
- Xhstore(tb,key,klen,val,hash)
- Xregister HASH *tb;
- Xchar *key;
- Xint klen;
- XSTR *val;
- Xregister int hash;
- X{
- X register char *s;
- X register int i;
- X register HENT *entry;
- X register HENT **oentry;
- X register int maxi;
- X
- X if (!tb)
- X return FALSE;
- X
- X if (hash)
- X ;
- X else if (!tb->tbl_coeffsize)
- X hash = *key + 128 * key[1] + 128 * key[klen-1];
- X else { /* use normal coefficients */
- X if (klen < tb->tbl_coeffsize)
- X maxi = klen;
- X else
- X maxi = tb->tbl_coeffsize;
- X for (s=key, i=0, hash = 0;
- X i < maxi;
- X s++, i++, hash *= 5) {
- X hash += *s * coeff[i];
- X }
- X }
- X
- X oentry = &(tb->tbl_array[hash & tb->tbl_max]);
- X i = 1;
- X
- X for (entry = *oentry; entry; i=0, entry = entry->hent_next) {
- X if (entry->hent_hash != hash) /* strings can't be equal */
- X continue;
- X if (entry->hent_klen != klen)
- X continue;
- X if (bcmp(entry->hent_key,key,klen)) /* is this it? */
- X continue;
- X Safefree(entry->hent_val);
- X entry->hent_val = val;
- X return TRUE;
- X }
- X New(501,entry, 1, HENT);
- X
- X entry->hent_klen = klen;
- X entry->hent_key = nsavestr(key,klen);
- X entry->hent_val = val;
- X entry->hent_hash = hash;
- X entry->hent_next = *oentry;
- X *oentry = entry;
- X
- X /* hdbmstore not necessary here because it's called from stabset() */
- X
- X if (i) { /* initial entry? */
- X tb->tbl_fill++;
- X#ifdef SOME_DBM
- X if (tb->tbl_dbm && tb->tbl_max >= DBM_CACHE_MAX)
- X return FALSE;
- X#endif
- X if (tb->tbl_fill > tb->tbl_dosplit)
- X hsplit(tb);
- X }
- X#ifdef SOME_DBM
- X else if (tb->tbl_dbm) { /* is this just a cache for dbm file? */
- X entry = tb->tbl_array[hash & tb->tbl_max];
- X oentry = &entry->hent_next;
- X entry = *oentry;
- X while (entry) { /* trim chain down to 1 entry */
- X *oentry = entry->hent_next;
- X hentfree(entry); /* no doubt they'll want this next. */
- X entry = *oentry;
- X }
- X }
- X#endif
- X
- X return FALSE;
- X}
- X
- XSTR *
- Xhdelete(tb,key,klen)
- Xregister HASH *tb;
- Xchar *key;
- Xint klen;
- X{
- X register char *s;
- X register int i;
- X register int hash;
- X register HENT *entry;
- X register HENT **oentry;
- X STR *str;
- X int maxi;
- X#ifdef SOME_DBM
- X datum dkey;
- X#endif
- X
- X if (!tb)
- X return Nullstr;
- X if (!tb->tbl_coeffsize)
- X hash = *key + 128 * key[1] + 128 * key[klen-1];
- X else { /* use normal coefficients */
- X if (klen < tb->tbl_coeffsize)
- X maxi = klen;
- X else
- X maxi = tb->tbl_coeffsize;
- X for (s=key, i=0, hash = 0;
- X i < maxi;
- X s++, i++, hash *= 5) {
- X hash += *s * coeff[i];
- X }
- X }
- X
- X oentry = &(tb->tbl_array[hash & tb->tbl_max]);
- X entry = *oentry;
- X i = 1;
- X for (; entry; i=0, oentry = &entry->hent_next, entry = *oentry) {
- X if (entry->hent_hash != hash) /* strings can't be equal */
- X continue;
- X if (entry->hent_klen != klen)
- X continue;
- X if (bcmp(entry->hent_key,key,klen)) /* is this it? */
- X continue;
- X *oentry = entry->hent_next;
- X str = str_static(entry->hent_val);
- X hentfree(entry);
- X if (i)
- X tb->tbl_fill--;
- X#ifdef SOME_DBM
- X do_dbm_delete:
- X if (tb->tbl_dbm) {
- X dkey.dptr = key;
- X dkey.dsize = klen;
- X dbm_delete(tb->tbl_dbm,dkey);
- X }
- X#endif
- X return str;
- X }
- X#ifdef SOME_DBM
- X str = Nullstr;
- X goto do_dbm_delete;
- X#else
- X return Nullstr;
- X#endif
- X}
- X
- Xhsplit(tb)
- XHASH *tb;
- X{
- X int oldsize = tb->tbl_max + 1;
- X register int newsize = oldsize * 2;
- X register int i;
- X register HENT **a;
- X register HENT **b;
- X register HENT *entry;
- X register HENT **oentry;
- X
- X a = tb->tbl_array;
- X Renew(a, newsize, HENT*);
- X Zero(&a[oldsize], oldsize, HENT*); /* zero 2nd half*/
- X tb->tbl_max = --newsize;
- X tb->tbl_dosplit = tb->tbl_max * FILLPCT / 100;
- X tb->tbl_array = a;
- X
- X for (i=0; i<oldsize; i++,a++) {
- X if (!*a) /* non-existent */
- X continue;
- X b = a+oldsize;
- X for (oentry = a, entry = *a; entry; entry = *oentry) {
- X if ((entry->hent_hash & newsize) != i) {
- X *oentry = entry->hent_next;
- X entry->hent_next = *b;
- X if (!*b)
- X tb->tbl_fill++;
- X *b = entry;
- X continue;
- X }
- X else
- X oentry = &entry->hent_next;
- X }
- X if (!*a) /* everything moved */
- X tb->tbl_fill--;
- X }
- X}
- X
- XHASH *
- Xhnew(lookat)
- Xunsigned int lookat;
- X{
- X register HASH *tb;
- X
- X Newz(502,tb, 1, HASH);
- X if (lookat) {
- X tb->tbl_coeffsize = lookat;
- X tb->tbl_max = 7; /* it's a normal associative array */
- X tb->tbl_dosplit = tb->tbl_max * FILLPCT / 100;
- X }
- X else {
- X tb->tbl_max = 127; /* it's a symbol table */
- X tb->tbl_dosplit = 128; /* so never split */
- X }
- X Newz(503,tb->tbl_array, tb->tbl_max + 1, HENT*);
- X tb->tbl_fill = 0;
- X#ifdef SOME_DBM
- X tb->tbl_dbm = 0;
- X#endif
- X (void)hiterinit(tb); /* so each() will start off right */
- X return tb;
- X}
- X
- Xvoid
- Xhentfree(hent)
- Xregister HENT *hent;
- X{
- X if (!hent)
- X return;
- X str_free(hent->hent_val);
- X Safefree(hent->hent_key);
- X Safefree(hent);
- X}
- X
- Xvoid
- Xhclear(tb)
- Xregister HASH *tb;
- X{
- X register HENT *hent;
- X register HENT *ohent = Null(HENT*);
- X
- X if (!tb)
- X return;
- X (void)hiterinit(tb);
- X while (hent = hiternext(tb)) { /* concise but not very efficient */
- X hentfree(ohent);
- X ohent = hent;
- X }
- X hentfree(ohent);
- X tb->tbl_fill = 0;
- X#ifndef lint
- X (void)bzero((char*)tb->tbl_array, (tb->tbl_max + 1) * sizeof(HENT*));
- X#endif
- X}
- X
- Xvoid
- Xhfree(tb)
- Xregister HASH *tb;
- X{
- X register HENT *hent;
- X register HENT *ohent = Null(HENT*);
- X
- X if (!tb)
- X return;
- X (void)hiterinit(tb);
- X while (hent = hiternext(tb)) {
- X hentfree(ohent);
- X ohent = hent;
- X }
- X hentfree(ohent);
- X Safefree(tb->tbl_array);
- X Safefree(tb);
- X}
- X
- Xint
- Xhiterinit(tb)
- Xregister HASH *tb;
- X{
- X tb->tbl_riter = -1;
- X tb->tbl_eiter = Null(HENT*);
- X return tb->tbl_fill;
- X}
- X
- XHENT *
- Xhiternext(tb)
- Xregister HASH *tb;
- X{
- X register HENT *entry;
- X#ifdef SOME_DBM
- X datum key;
- X#endif
- X
- X entry = tb->tbl_eiter;
- X#ifdef SOME_DBM
- X if (tb->tbl_dbm) {
- X if (entry) {
- X#ifdef NDBM
- X#ifdef _CX_UX
- X key = dbm_nextkey(tb->tbl_dbm, key);
- X#else
- X key = dbm_nextkey(tb->tbl_dbm);
- X#endif /* _CX_UX */
- X#else
- X key.dptr = entry->hent_key;
- X key.dsize = entry->hent_klen;
- X key = nextkey(key);
- X#endif
- X }
- X else {
- X Newz(504,entry, 1, HENT);
- X tb->tbl_eiter = entry;
- X key = dbm_firstkey(tb->tbl_dbm);
- X }
- X entry->hent_key = key.dptr;
- X entry->hent_klen = key.dsize;
- X if (!key.dptr) {
- X if (entry->hent_val)
- X str_free(entry->hent_val);
- X Safefree(entry);
- X tb->tbl_eiter = Null(HENT*);
- X return Null(HENT*);
- X }
- X return entry;
- X }
- X#endif
- X do {
- X if (entry)
- X entry = entry->hent_next;
- X if (!entry) {
- X tb->tbl_riter++;
- X if (tb->tbl_riter > tb->tbl_max) {
- X tb->tbl_riter = -1;
- X break;
- X }
- X entry = tb->tbl_array[tb->tbl_riter];
- X }
- X } while (!entry);
- X
- X tb->tbl_eiter = entry;
- X return entry;
- X}
- X
- Xchar *
- Xhiterkey(entry,retlen)
- Xregister HENT *entry;
- Xint *retlen;
- X{
- X *retlen = entry->hent_klen;
- X return entry->hent_key;
- X}
- X
- XSTR *
- Xhiterval(tb,entry)
- Xregister HASH *tb;
- Xregister HENT *entry;
- X{
- X#ifdef SOME_DBM
- X datum key, content;
- X
- X if (tb->tbl_dbm) {
- X key.dptr = entry->hent_key;
- X key.dsize = entry->hent_klen;
- X content = dbm_fetch(tb->tbl_dbm,key);
- X if (!entry->hent_val)
- X entry->hent_val = Str_new(62,0);
- X str_nset(entry->hent_val,content.dptr,content.dsize);
- X }
- X#endif
- X return entry->hent_val;
- X}
- X
- X#ifdef SOME_DBM
- X#if defined(FCNTL) && ! defined(O_CREAT)
- X#include <fcntl.h>
- X#endif
- X
- X#ifndef O_RDONLY
- X#define O_RDONLY 0
- X#endif
- X#ifndef O_RDWR
- X#define O_RDWR 2
- X#endif
- X#ifndef O_CREAT
- X#define O_CREAT 01000
- X#endif
- X
- X#ifndef NDBM
- Xstatic int dbmrefcnt = 0;
- X#endif
- X
- Xbool
- Xhdbmopen(tb,fname,mode)
- Xregister HASH *tb;
- Xchar *fname;
- Xint mode;
- X{
- X if (!tb)
- X return FALSE;
- X#ifndef NDBM
- X if (tb->tbl_dbm) /* never really closed it */
- X return TRUE;
- X#endif
- X if (tb->tbl_dbm)
- X hdbmclose(tb);
- X hclear(tb);
- X#ifdef NDBM
- X tb->tbl_dbm = dbm_open(fname, O_RDWR|O_CREAT, mode);
- X if (!tb->tbl_dbm) /* oops, just try reading it */
- X tb->tbl_dbm = dbm_open(fname, O_RDONLY, mode);
- X#else
- X if (dbmrefcnt++)
- X fatal("Old dbm can only open one database");
- X sprintf(buf,"%s.dir",fname);
- X if (stat(buf, &statbuf) < 0) {
- X if (close(creat(buf,mode)) < 0)
- X return FALSE;
- X sprintf(buf,"%s.pag",fname);
- X if (close(creat(buf,mode)) < 0)
- X return FALSE;
- X }
- X tb->tbl_dbm = dbminit(fname) >= 0;
- X#endif
- X return tb->tbl_dbm != 0;
- X}
- X
- Xvoid
- Xhdbmclose(tb)
- Xregister HASH *tb;
- X{
- X if (tb && tb->tbl_dbm) {
- X#ifdef NDBM
- X dbm_close(tb->tbl_dbm);
- X tb->tbl_dbm = 0;
- X#else
- X /* dbmrefcnt--; */ /* doesn't work, rats */
- X#endif
- X }
- X else if (dowarn)
- X warn("Close on unopened dbm file");
- X}
- X
- Xbool
- Xhdbmstore(tb,key,klen,str)
- Xregister HASH *tb;
- Xchar *key;
- Xint klen;
- Xregister STR *str;
- X{
- X datum dkey, dcontent;
- X int error;
- X
- X if (!tb || !tb->tbl_dbm)
- X return FALSE;
- X dkey.dptr = key;
- X dkey.dsize = klen;
- X dcontent.dptr = str_get(str);
- X dcontent.dsize = str->str_cur;
- X error = dbm_store(tb->tbl_dbm, dkey, dcontent, DBM_REPLACE);
- X if (error) {
- X if (errno == EPERM)
- X fatal("No write permission to dbm file");
- X warn("dbm store returned %d, errno %d, key \"%s\"",error,errno,key);
- X#ifdef NDBM
- X dbm_clearerr(tb->tbl_dbm);
- X#endif
- X }
- X return !error;
- X}
- X#endif /* SOME_DBM */
- !STUFFY!FUNK!
- echo Extracting lib/perldb.pl
- sed >lib/perldb.pl <<'!STUFFY!FUNK!' -e 's/X//'
- Xpackage DB;
- X
- X$header = '$Header: perldb.pl,v 3.0 89/10/18 15:19:46 lwall Locked $';
- X#
- X# This file is automatically included if you do perl -d.
- X# It's probably not useful to include this yourself.
- X#
- X# Perl supplies the values for @line and %sub. It effectively inserts
- X# a do DB'DB(<linenum>); in front of every place that can
- X# have a breakpoint. It also inserts a do 'perldb.pl' before the first line.
- X#
- X# $Log: perldb.pl,v $
- X# Revision 3.0 89/10/18 15:19:46 lwall
- X# 3.0 baseline
- X#
- X# Revision 2.0 88/06/05 00:09:45 root
- X# Baseline version 2.0.
- X#
- X#
- X
- Xopen(IN,"/dev/tty"); # so we don't dingle stdin
- Xopen(OUT,">/dev/tty"); # so we don't dongle stdout
- Xselect(OUT);
- X$| = 1; # for DB'OUT
- Xselect(STDOUT);
- X$| = 1; # for real STDOUT
- X
- X$header =~ s/\$Header: perldb.pl,v 3.0 89/10/18 15:19:46 lwall Locked $/$1$2/;
- Xprint OUT "\nLoading DB from $header\n\n";
- X
- Xsub DB {
- X local($. ,$@, $!, $[, $,, $/, $\);
- X $[ = 0; $, = ""; $/ = "\n"; $\ = "";
- X ($line) = @_;
- X if ($stop[$line]) {
- X if ($stop eq '1') {
- X $signal |= 1;
- X }
- X else {
- X package main;
- X $DB'signal |= eval $DB'stop[$DB'line]; print DB'OUT $@;
- X $DB'stop[$DB'line] =~ s/;9$//;
- X }
- X }
- X if ($single || $trace || $signal) {
- X print OUT "$sub($line):\t",$line[$line];
- X for ($i = $line + 1; $i <= $max && $line[$i] == 0; ++$i) {
- X last if $line[$i] =~ /^\s*(}|#|\n)/;
- X print OUT "$sub($i):\t",$line[$i];
- X }
- X }
- X if ($action[$line]) {
- X package main;
- X eval $DB'action[$DB'line]; print DB'OUT $@;
- X }
- X if ($single || $signal) {
- X if ($pre) {
- X package main;
- X eval $DB'pre; print DB'OUT $@;
- X }
- X print OUT $#stack . " levels deep in subroutine calls!\n"
- X if $single & 4;
- X $start = $line;
- X while ((print OUT " DB<", $#hist+1, "> "), $cmd=<IN>) {
- X $single = 0;
- X $signal = 0;
- X $cmd eq '' && exit 0;
- X chop($cmd);
- X $cmd =~ /^q$/ && exit 0;
- X $cmd =~ /^$/ && ($cmd = $laststep);
- X push(@hist,$cmd) if length($cmd) > 1;
- X ($i) = split(/\s+/,$cmd);
- X eval "\$cmd =~ $alias{$i}", print OUT $@ if $alias{$i};
- X $cmd =~ /^h$/ && do {
- X print OUT "
- XT Stack trace.
- Xs Single step.
- Xn Next, steps over subroutine calls.
- Xf Finish current subroutine.
- Xc [line] Continue; optionally inserts a one-time-only breakpoint
- X at the specified line.
- X<CR> Repeat last n or s.
- Xl min+incr List incr+1 lines starting at min.
- Xl min-max List lines.
- Xl line List line;
- Xl List next window.
- X- List previous window.
- Xw line List window around line.
- Xl subname List subroutine.
- X/pattern/ Search forwards for pattern; final / is optional.
- X?pattern? Search backwards for pattern.
- XL List breakpoints and actions.
- XS List subroutine names.
- Xt Toggle trace mode.
- Xb [line] [condition]
- X Set breakpoint; line defaults to the current execution line;
- X condition breaks if it evaluates to true, defaults to \'1\'.
- Xb subname [condition]
- X Set breakpoint at first line of subroutine.
- Xd [line] Delete breakpoint.
- XD Delete all breakpoints.
- Xa [line] command
- X Set an action to be done before the line is executed.
- X Sequence is: check for breakpoint, print line if necessary,
- X do action, prompt user if breakpoint or step, evaluate line.
- XA Delete all actions.
- XV package List all variables and values in package (default main).
- X< command Define command before prompt.
- X> command Define command after prompt.
- X! number Redo command (default previous command).
- X! -number Redo number\'th to last command.
- XH -number Display last number commands (default all).
- Xq or ^D Quit.
- Xp expr Same as \"package main; print DB'OUT expr\".
- Xcommand Execute as a perl statement.
- X
- X";
- X next; };
- X $cmd =~ /^t$/ && do {
- X $trace = !$trace;
- X print OUT "Trace = ".($trace?"on":"off")."\n";
- X next; };
- X $cmd =~ /^S$/ && do {
- X foreach $subname (sort(keys %sub)) {
- X if ($subname =~ /^main'(.*)/) {
- X print OUT $1,"\n";
- X }
- X else {
- X print OUT $subname,"\n";
- X }
- X }
- X next; };
- X $cmd =~ /^V$/ && do {
- X $cmd = 'V main'; };
- X $cmd =~ /^V\s*(['A-Za-z_]['\w]*)$/ && do {
- X $packname = $1;
- X do 'dumpvar.pl' unless defined &main'dumpvar;
- X if (defined &main'dumpvar) {
- X &main'dumpvar($packname);
- X }
- X else {
- X print DB'OUT "dumpvar.pl not available.\n";
- X }
- X next; };
- X $cmd =~ /^l\s*(['A-Za-z_]['\w]*)/ && do {
- X $subname = $1;
- X $subname = "main'" . $subname unless $subname =~ /'/;
- X $subrange = $sub{$subname};
- X if ($subrange) {
- X if (eval($subrange) < -$window) {
- X $subrange =~ s/-.*/+/;
- X }
- X $cmd = "l $subrange";
- X } else {
- X print OUT "Subroutine $1 not found.\n";
- X next;
- X } };
- X $cmd =~ /^w\s*(\d*)$/ && do {
- X $incr = $window - 1;
- X $start = $1 if $1;
- X $start -= $preview;
- X $cmd = 'l ' . $start . '-' . ($start + $incr); };
- X $cmd =~ /^-$/ && do {
- X $incr = $window - 1;
- X $cmd = 'l ' . ($start-$window*2) . '+'; };
- X $cmd =~ /^l$/ && do {
- X $incr = $window - 1;
- X $cmd = 'l ' . $start . '-' . ($start + $incr); };
- X $cmd =~ /^l\s*(\d*)\+(\d*)$/ && do {
- X $start = $1 if $1;
- X $incr = $2;
- X $incr = $window - 1 unless $incr;
- X $cmd = 'l ' . $start . '-' . ($start + $incr); };
- X $cmd =~ /^l\s*(([\d\$\.]+)([-,]([\d\$\.]+))?)?/ && do {
- X $end = (!$2) ? $max : ($4 ? $4 : $2);
- X $end = $max if $end > $max;
- X $i = $2;
- X $i = $line if $i eq '.';
- X $i = 1 if $i < 1;
- X for (; $i <= $end; $i++) {
- X print OUT "$i:\t", $line[$i];
- X last if $signal;
- X }
- X $start = $i; # remember in case they want more
- X $start = $max if $start > $max;
- X next; };
- X $cmd =~ /^D$/ && do {
- X print OUT "Deleting all breakpoints...\n";
- X for ($i = 1; $i <= $max ; $i++) {
- X $stop[$i] = 0;
- X }
- X next; };
- X $cmd =~ /^L$/ && do {
- X for ($i = 1; $i <= $max; $i++) {
- X if ($stop[$i] || $action[$i]) {
- X print OUT "$i:\t", $line[$i];
- X print OUT " break if (", $stop[$i], ")\n"
- X if $stop[$i];
- X print OUT " action: ", $action[$i], "\n"
- X if $action[$i];
- X last if $signal;
- X }
- X }
- X next; };
- X $cmd =~ /^b\s*(['A-Za-z_]['\w]*)\s*(.*)/ && do {
- X $subname = $1;
- X $subname = "main'" . $subname unless $subname =~ /'/;
- X ($i) = split(/-/, $sub{$subname});
- X if ($i) {
- X ++$i while $line[$i] == 0 && $i < $#line;
- X $stop[$i] = $2 ? $2 : 1;
- X } else {
- X print OUT "Subroutine $1 not found.\n";
- X }
- X next; };
- X $cmd =~ /^b\s*(\d*)\s*(.*)/ && do {
- X $i = ($1?$1:$line);
- X if ($line[$i] == 0) {
- X print OUT "Line $i not breakable.\n";
- X } else {
- X $stop[$i] = $2 ? $2 : 1;
- X }
- X next; };
- X $cmd =~ /^d\s*(\d+)?/ && do {
- X $i = ($1?$1:$line);
- X $stop[$i] = '';
- X next; };
- X $cmd =~ /^A$/ && do {
- X for ($i = 1; $i <= $max ; $i++) {
- X $action[$i] = '';
- X }
- X next; };
- X $cmd =~ /^<\s*(.*)/ && do {
- X $pre = do action($1);
- X next; };
- X $cmd =~ /^>\s*(.*)/ && do {
- X $post = do action($1);
- X next; };
- X $cmd =~ /^a\s*(\d+)(\s+(.*))?/ && do {
- X $i = $1;
- X if ($line[$i] == 0) {
- X print OUT "Line $i may not have an action.\n";
- X } else {
- X $action[$i] = do action($3);
- X }
- X next; };
- X $cmd =~ /^n$/ && do {
- X $single = 2;
- X $laststep = $cmd;
- X last; };
- X $cmd =~ /^s$/ && do {
- X $single = 1;
- X $laststep = $cmd;
- X last; };
- X $cmd =~ /^c\s*(\d*)\s*$/ && do {
- X $i = $1;
- X if ($i) {
- X if ($line[$i] == 0) {
- X print OUT "Line $i not breakable.\n";
- X next;
- X }
- X $stop[$i] .= ";9"; # add one-time-only b.p.
- X }
- X for ($i=0; $i <= $#stack; ) {
- X $stack[$i++] &= ~1;
- X }
- X last; };
- X $cmd =~ /^f$/ && do {
- X $stack[$#stack] |= 2;
- X last; };
- X $cmd =~ /^T$/ && do {
- X for ($i=0; $i <= $#sub; ) {
- X print OUT $sub[$i++], "\n";
- X last if $signal;
- X }
- X next; };
- X $cmd =~ /^\/(.*)$/ && do {
- X $inpat = $1;
- X $inpat =~ s:([^\\])/$:$1:;
- X if ($inpat ne "") {
- X eval '$inpat =~ m'."\n$inpat\n";
- X if ($@ ne "") {
- X print OUT "$@";
- X next;
- X }
- X $pat = $inpat;
- X }
- X $end = $start;
- X eval '
- X for (;;) {
- X ++$start;
- X $start = 1 if ($start > $max);
- X last if ($start == $end);
- X if ($line[$start] =~ m'."\n$pat\n".'i) {
- X print OUT "$start:\t", $line[$start], "\n";
- X last;
- X }
- X } ';
- X print OUT "/$pat/: not found\n" if ($start == $end);
- X next; };
- X $cmd =~ /^\?(.*)$/ && do {
- X $inpat = $1;
- X $inpat =~ s:([^\\])\?$:$1:;
- X if ($inpat ne "") {
- X eval '$inpat =~ m'."\n$inpat\n";
- X if ($@ ne "") {
- X print OUT "$@";
- X next;
- X }
- X $pat = $inpat;
- X }
- X $end = $start;
- X eval '
- X for (;;) {
- X --$start;
- X $start = $max if ($start <= 0);
- X last if ($start == $end);
- X if ($line[$start] =~ m'."\n$pat\n".'i) {
- X print OUT "$start:\t", $line[$start], "\n";
- X last;
- X }
- X } ';
- X print OUT "?$pat?: not found\n" if ($start == $end);
- X next; };
- X $cmd =~ /^!+\s*(-)?(\d+)?$/ && do {
- X pop(@hist) if length($cmd) > 1;
- X $i = ($1?($#hist-($2?$2:1)):($2?$2:$#hist));
- X $cmd = $hist[$i] . "\n";
- X print OUT $cmd;
- X redo; };
- X $cmd =~ /^!(.+)$/ && do {
- X $pat = "^$1";
- X pop(@hist) if length($cmd) > 1;
- X for ($i = $#hist; $i; --$i) {
- X last if $hist[$i] =~ $pat;
- X }
- X if (!$i) {
- X print OUT "No such command!\n\n";
- X next;
- X }
- X $cmd = $hist[$i] . "\n";
- X print OUT $cmd;
- X redo; };
- X $cmd =~ /^H\s*(-(\d+))?/ && do {
- X $end = $2?($#hist-$2):0;
- X $hist = 0 if $hist < 0;
- X for ($i=$#hist; $i>$end; $i--) {
- X print OUT "$i: ",$hist[$i],"\n"
- X unless $hist[$i] =~ /^.?$/;
- X };
- X next; };
- X $cmd =~ s/^p( .*)?$/print DB'OUT$1/;
- X {
- X package main;
- X eval $DB'cmd;
- X }
- X print OUT $@,"\n";
- X }
- X if ($post) {
- X package main;
- X eval $DB'post; print DB'OUT $@;
- X }
- X }
- X}
- X
- Xsub action {
- X local($action) = @_;
- X while ($action =~ s/\\$//) {
- X print OUT "+ ";
- X $action .= <IN>;
- X }
- X $action;
- X}
- X
- Xsub catch {
- X $signal = 1;
- X}
- X
- Xsub sub {
- X push(@stack, $single);
- X $single &= 1;
- X $single |= 4 if $#stack == $deep;
- X local(@args) = @_;
- X for (@args) {
- X if (/^Stab/ && length($_) == length($_main{'_main'})) {
- X $_ = sprintf("%s",$_);
- X print "ARG: $_\n";
- X }
- X else {
- X s/'/\\'/g;
- X s/(.*)/'$1'/ unless /^-?[\d.]+$/;
- X }
- X }
- X push(@sub, $sub . '(' . join(', ', @args) . ') from ' . $line);
- X if (wantarray) {
- X @i = &$sub;
- X }
- X else {
- X $i = &$sub;
- X @i = $i;
- X }
- X --$#sub;
- X $single |= pop(@stack);
- X @i;
- X}
- X
- X$single = 1; # so it stops on first executable statement
- X$max = $#line;
- X@hist = ('?');
- X$SIG{'INT'} = "DB'catch";
- X$deep = 100; # warning if stack gets this deep
- X$window = 10;
- X$preview = 3;
- X
- X@stack = (0);
- X@args = @ARGV;
- Xfor (@args) {
- X s/'/\\'/g;
- X s/(.*)/'$1'/ unless /^-?[\d.]+$/;
- X}
- Xpush(@sub, 'main(' . join(', ', @args) . ")" );
- X$sub = 'main';
- X
- Xif (-f '.perldb') {
- X do './.perldb';
- X}
- Xelsif (-f "$ENV{'LOGDIR'}/.perldb") {
- X do "$ENV{'LOGDIR'}/.perldb";
- X}
- Xelsif (-f "$ENV{'HOME'}/.perldb") {
- X do "$ENV{'HOME'}/.perldb";
- X}
- X
- X1;
- !STUFFY!FUNK!
- echo Extracting PACKINGLIST
- sed >PACKINGLIST <<'!STUFFY!FUNK!' -e 's/X//'
- XAfter all the perl kits are run you should have the following files:
- X
- XFilename Kit Description
- X-------- --- -----------
- XChanges 20 Differences between 2.0 level 18 and 3.0 level 0
- XConfigure 2 Run this first
- XCopying 10 The GNU General Public License
- XEXTERN.h 24 Included before foreign .h files
- XINTERN.h 24 Included before domestic .h files
- XMANIFEST 20 This list of files
- XMakefile.SH 19 Precursor to Makefile
- XPACKINGLIST 18 Which files came from which kits
- XREADME 1 The Instructions
- XWishlist 24 Some things that may or may not happen
- Xarg.h 11 Public declarations for the above
- Xarray.c 21 Numerically subscripted arrays
- Xarray.h 24 Public declarations for the above
- Xclient 24 A client to test sockets
- Xcmd.c 15 Command interpreter
- Xcmd.h 21 Public declarations for the above
- Xconfig.H 15 Sample config.h
- Xconfig.h.SH 14 Produces config.h
- Xcons.c 10 Routines to construct cmd nodes of a parse tree
- Xconsarg.c 14 Routines to construct arg nodes of a parse tree
- Xdoarg.c 11 Scalar expression evaluation
- Xdoio.c 7 I/O operations
- Xdolist.c 16 Array expression evaluation
- Xdump.c 20 Debugging output
- Xeg/ADB 24 An adb wrapper to put in your crash dir
- Xeg/README 1 Intro to example perl scripts
- Xeg/changes 23 A program to list recently changed files
- Xeg/down 24 A program to do things to subdirectories
- Xeg/dus 24 A program to do du -s on non-mounted dirs
- Xeg/findcp 17 A find wrapper that implements a -cp switch
- Xeg/findtar 24 A find wrapper that pumps out a tar file
- Xeg/g/gcp 22 A program to do a global rcp
- Xeg/g/gcp.man 23 Manual page for gcp
- Xeg/g/ged 24 A program to do a global edit
- Xeg/g/ghosts 22 A sample /etc/ghosts file
- Xeg/g/gsh 22 A program to do a global rsh
- Xeg/g/gsh.man 21 Manual page for gsh
- Xeg/muck 22 A program to find missing make dependencies
- Xeg/muck.man 24 Manual page for muck
- Xeg/myrup 23 A program to find lightly loaded machines
- Xeg/nih 24 Script to insert #! workaround
- Xeg/rename 24 A program to rename files
- Xeg/rmfrom 24 A program to feed doomed filenames to
- Xeg/scan/scan_df 23 Scan for filesystem anomalies
- Xeg/scan/scan_last 23 Scan for login anomalies
- Xeg/scan/scan_messages 21 Scan for console message anomalies
- Xeg/scan/scan_passwd 6 Scan for passwd file anomalies
- Xeg/scan/scan_ps 24 Scan for process anomalies
- Xeg/scan/scan_sudo 23 Scan for sudo anomalies
- Xeg/scan/scan_suid 22 Scan for setuid anomalies
- Xeg/scan/scanner 23 An anomaly reporter
- Xeg/shmkill 23 A program to remove unused shared memory
- Xeg/van/empty 24 A program to empty the trashcan
- Xeg/van/unvanish 23 A program to undo what vanish does
- Xeg/van/vanexp 24 A program to expire vanished files
- Xeg/van/vanish 23 A program to put files in a trashcan
- Xeg/who 24 A sample who program
- Xeval.c 3 The expression evaluator
- Xevalargs.xc 19 The arg evaluator of eval.c
- Xform.c 20 Format processing
- Xform.h 24 Public declarations for the above
- Xgettest 24 A little script to test the get* routines
- Xhandy.h 22 Handy definitions
- Xhash.c 18 Associative arrays
- Xhash.h 23 Public declarations for the above
- Xioctl.pl 21 Sample ioctl.pl
- Xlib/abbrev.pl 24 An abbreviation table builder
- Xlib/complete.pl 23 A command completion subroutine
- Xlib/dumpvar.pl 24 A variable dumper
- Xlib/getopt.pl 23 Perl library supporting option parsing
- Xlib/getopts.pl 24 Perl library supporting option parsing
- Xlib/importenv.pl 24 Perl routine to get environment into variables
- Xlib/look.pl 23 A "look" equivalent
- Xlib/perldb.pl 18 Perl debugging routines
- Xlib/stat.pl 24 Perl library supporting stat function
- Xlib/termcap.pl 22 Perl library supporting termcap usage
- Xlib/validate.pl 21 Perl library supporting wholesale file mode validation
- Xmakedepend.SH 21 Precursor to makedepend
- Xmakedir.SH 23 Precursor to makedir
- Xmakelib.SH 21 A thing to turn C .h file into perl .h files
- Xmalloc.c 19 A version of malloc you might not want
- Xpatchlevel.h 10 The current patch level of perl
- Xperl.h 8 Global declarations
- Xperl.man.1 1 The manual page(s), first fourth
- Xperl.man.2 9 The manual page(s), second fourth
- Xperl.man.3 8 The manual page(s), third fourth
- Xperl.man.4 6 The manual page(s), fourth fourth
- Xperl.y 12 Yacc grammar for perl
- Xperlsh 24 A poor man's perl shell
- Xperly.c 17 main()
- Xregcomp.c 12 Regular expression compiler
- Xregcomp.h 7 Private declarations for above
- Xregexec.c 13 Regular expression evaluator
- Xregexp.h 23 Public declarations for the above
- Xserver 24 A server to test sockets
- Xspat.h 23 Search pattern declarations
- Xstab.c 9 Symbol table stuff
- Xstab.h 20 Public declarations for the above
- Xstr.c 13 String handling package
- Xstr.h 14 Public declarations for the above
- Xt/README 1 Instructions for regression tests
- Xt/TEST 23 The regression tester
- Xt/base.cond 24 See if conditionals work
- Xt/base.if 24 See if if works
- Xt/base.lex 23 See if lexical items work
- Xt/base.pat 24 See if pattern matching works
- Xt/base.term 24 See if various terms work
- Xt/cmd.elsif 24 See if else-if works
- Xt/cmd.for 23 See if for loops work
- Xt/cmd.mod 24 See if statement modifiers work
- Xt/cmd.subval 22 See if subroutine values work
- Xt/cmd.switch 12 See if switch optimizations work
- Xt/cmd.while 22 See if while loops work
- Xt/comp.cmdopt 22 See if command optimization works
- Xt/comp.cpp 24 See if C preprocessor works
- Xt/comp.decl 24 See if declarations work
- Xt/comp.multiline 24 See if multiline strings work
- Xt/comp.package 24 See if packages work
- Xt/comp.script 24 See if script invokation works
- Xt/comp.term 23 See if more terms work
- Xt/io.argv 23 See if ARGV stuff works
- Xt/io.dup 24 See if >& works right
- Xt/io.fs 22 See if directory manipulations work
- Xt/io.inplace 24 See if inplace editing works
- Xt/io.pipe 24 See if secure pipes work
- Xt/io.print 24 See if print commands work
- Xt/io.tell 23 See if file seeking works
- Xt/op.append 24 See if . works
- Xt/op.array 22 See if array operations work
- Xt/op.auto 18 See if autoincrement et all work
- Xt/op.chop 24 See if chop works
- Xt/op.cond 24 See if conditional expressions work
- Xt/op.dbm 22 See if dbm binding works
- Xt/op.delete 24 See if delete works
- Xt/op.do 23 See if subroutines work
- Xt/op.each 23 See if associative iterators work
- Xt/op.eval 23 See if eval operator works
- Xt/op.exec 24 See if exec and system work
- Xt/op.exp 1 See if math functions work
- Xt/op.flip 24 See if range operator works
- Xt/op.fork 24 See if fork works
- Xt/op.glob 24 See if <*> works
- Xt/op.goto 24 See if goto works
- Xt/op.index 24 See if index works
- Xt/op.int 24 See if int works
- Xt/op.join 24 See if join works
- Xt/op.list 10 See if array lists work
- Xt/op.local 24 See if local works
- Xt/op.magic 23 See if magic variables work
- Xt/op.mkdir 24 See if mkdir works
- Xt/op.oct 24 See if oct and hex work
- Xt/op.ord 24 See if ord works
- Xt/op.pack 24 See if pack and unpack work
- Xt/op.pat 22 See if esoteric patterns work
- Xt/op.push 15 See if push and pop work
- Xt/op.range 24 See if .. works
- Xt/op.read 24 See if read() works
- Xt/op.regexp 24 See if regular expressions work
- Xt/op.repeat 23 See if x operator works
- Xt/op.sleep 8 See if sleep works
- Xt/op.sort 24 See if sort works
- Xt/op.split 13 See if split works
- Xt/op.sprintf 24 See if sprintf works
- Xt/op.stat 21 See if stat works
- Xt/op.study 23 See if study works
- Xt/op.subst 21 See if substitutions work
- Xt/op.substr 23 See if substr works
- Xt/op.time 23 See if time functions work
- Xt/op.undef 23 See if undef works
- Xt/op.unshift 24 See if unshift works
- Xt/op.vec 24 See if vectors work
- Xt/op.write 23 See if write works
- Xt/re_tests 22 Input file for op.regexp
- Xtoke.c 5 The tokener
- Xutil.c 17 Utility routines
- Xutil.h 24 Public declarations for the above
- Xx2p/EXTERN.h 24 Same as above
- Xx2p/INTERN.h 24 Same as above
- Xx2p/Makefile.SH 22 Precursor to Makefile
- Xx2p/a2p.h 20 Global declarations
- Xx2p/a2p.man 20 Manual page for awk to perl translator
- Xx2p/a2p.y 19 A yacc grammer for awk
- Xx2p/a2py.c 16 Awk compiler, sort of
- Xx2p/handy.h 24 Handy definitions
- Xx2p/hash.c 21 Associative arrays again
- Xx2p/hash.h 23 Public declarations for the above
- Xx2p/s2p.SH 18 Sed to perl translator
- Xx2p/s2p.man 22 Manual page for sed to perl translator
- Xx2p/str.c 19 String handling package
- Xx2p/str.h 23 Public declarations for the above
- Xx2p/util.c 15 Utility routines
- Xx2p/util.h 24 Public declarations for the above
- Xx2p/walk.c 4 Parse tree walker
- !STUFFY!FUNK!
- echo Extracting t/op.auto
- sed >t/op.auto <<'!STUFFY!FUNK!' -e 's/X//'
- X#!./perl
- X
- X# $Header: op.auto,v 3.0 89/10/18 15:27:00 lwall Locked $
- X
- Xprint "1..34\n";
- X
- X$x = 10000;
- Xif (0 + ++$x - 1 == 10000) { print "ok 1\n";} else {print "not ok 1\n";}
- Xif (0 + $x-- - 1 == 10000) { print "ok 2\n";} else {print "not ok 2\n";}
- Xif (1 * $x == 10000) { print "ok 3\n";} else {print "not ok 3\n";}
- Xif (0 + $x-- - 0 == 10000) { print "ok 4\n";} else {print "not ok 4\n";}
- Xif (1 + $x == 10000) { print "ok 5\n";} else {print "not ok 5\n";}
- Xif (1 + $x++ == 10000) { print "ok 6\n";} else {print "not ok 6\n";}
- Xif (0 + $x == 10000) { print "ok 7\n";} else {print "not ok 7\n";}
- Xif (0 + --$x + 1 == 10000) { print "ok 8\n";} else {print "not ok 8\n";}
- Xif (0 + ++$x + 0 == 10000) { print "ok 9\n";} else {print "not ok 9\n";}
- Xif ($x == 10000) { print "ok 10\n";} else {print "not ok 10\n";}
- X
- X$x[0] = 10000;
- Xif (0 + ++$x[0] - 1 == 10000) { print "ok 11\n";} else {print "not ok 11\n";}
- Xif (0 + $x[0]-- - 1 == 10000) { print "ok 12\n";} else {print "not ok 12\n";}
- Xif (1 * $x[0] == 10000) { print "ok 13\n";} else {print "not ok 13\n";}
- Xif (0 + $x[0]-- - 0 == 10000) { print "ok 14\n";} else {print "not ok 14\n";}
- Xif (1 + $x[0] == 10000) { print "ok 15\n";} else {print "not ok 15\n";}
- Xif (1 + $x[0]++ == 10000) { print "ok 16\n";} else {print "not ok 16\n";}
- Xif (0 + $x[0] == 10000) { print "ok 17\n";} else {print "not ok 17\n";}
- Xif (0 + --$x[0] + 1 == 10000) { print "ok 18\n";} else {print "not ok 18\n";}
- Xif (0 + ++$x[0] + 0 == 10000) { print "ok 19\n";} else {print "not ok 19\n";}
- Xif ($x[0] == 10000) { print "ok 20\n";} else {print "not ok 20\n";}
- X
- X$x{0} = 10000;
- Xif (0 + ++$x{0} - 1 == 10000) { print "ok 21\n";} else {print "not ok 21\n";}
- Xif (0 + $x{0}-- - 1 == 10000) { print "ok 22\n";} else {print "not ok 22\n";}
- Xif (1 * $x{0} == 10000) { print "ok 23\n";} else {print "not ok 23\n";}
- Xif (0 + $x{0}-- - 0 == 10000) { print "ok 24\n";} else {print "not ok 24\n";}
- Xif (1 + $x{0} == 10000) { print "ok 25\n";} else {print "not ok 25\n";}
- Xif (1 + $x{0}++ == 10000) { print "ok 26\n";} else {print "not ok 26\n";}
- Xif (0 + $x{0} == 10000) { print "ok 27\n";} else {print "not ok 27\n";}
- Xif (0 + --$x{0} + 1 == 10000) { print "ok 28\n";} else {print "not ok 28\n";}
- Xif (0 + ++$x{0} + 0 == 10000) { print "ok 29\n";} else {print "not ok 29\n";}
- Xif ($x{0} == 10000) { print "ok 30\n";} else {print "not ok 30\n";}
- X
- X# test magical autoincrement
- X
- Xif (++($foo = '99') eq '100') {print "ok 31\n";} else {print "not ok 31\n";}
- Xif (++($foo = 'a0') eq 'a1') {print "ok 32\n";} else {print "not ok 32\n";}
- Xif (++($foo = 'Az') eq 'Ba') {print "ok 33\n";} else {print "not ok 33\n";}
- Xif (++($foo = 'zz') eq 'aaa') {print "ok 34\n";} else {print "not ok 34\n";}
- !STUFFY!FUNK!
- echo ""
- echo "End of kit 18 (of 24)"
- cat /dev/null >kit18isdone
- run=''
- config=''
- for iskit in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24; do
- if test -f kit${iskit}isdone; then
- run="$run $iskit"
- else
- todo="$todo $iskit"
- fi
- done
- case $todo in
- '')
- echo "You have run all your kits. Please read README and then type Configure."
- chmod 755 Configure
- ;;
- *) echo "You have run$run."
- echo "You still need to run$todo."
- ;;
- esac
- : Someone might mail this, so...
- exit
-
-