home *** CD-ROM | disk | FTP | other *** search
- From: lwall@netlabs.com (Larry Wall)
- Newsgroups: comp.sources.misc
- Subject: v18i044: perl - The perl programming language, Part26/36
- Message-ID: <1991Apr17.185738.2601@sparky.IMD.Sterling.COM>
- Date: 17 Apr 91 18:57:38 GMT
- Approved: kent@sparky.imd.sterling.com
- X-Checksum-Snefru: 229e1a20 f9e5048a 92059680 c6251a39
-
- Submitted-by: Larry Wall <lwall@netlabs.com>
- Posting-number: Volume 18, Issue 44
- Archive-name: perl/part26
-
- [There are 36 kits for perl version 4.0.]
-
- #! /bin/sh
-
- # Make a new directory for the perl sources, cd to it, and run kits 1
- # thru 36 through sh. When all 36 kits have been run, read README.
-
- echo "This is perl 4.0 kit 26 (of 36). If kit 26 is complete, the line"
- echo '"'"End of kit 26 (of 36)"'" will echo at the end.'
- echo ""
- export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
- mkdir eg lib x2p 2>/dev/null
- echo Extracting lib/perldb.pl
- sed >lib/perldb.pl <<'!STUFFY!FUNK!' -e 's/X//'
- Xpackage DB;
- X
- X$header = '$Header: perldb.pl,v 4.0 91/03/20 01:25:50 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 4.0 91/03/20 01:25:50 lwall
- X# 4.0 baseline.
- X#
- X# Revision 3.0.1.6 91/01/11 18:08:58 lwall
- X# patch42: @_ couldn't be accessed from debugger
- X#
- X# Revision 3.0.1.5 90/11/10 01:40:26 lwall
- X# patch38: the debugger wouldn't stop correctly or do action routines
- X#
- X# Revision 3.0.1.4 90/10/15 17:40:38 lwall
- X# patch29: added caller
- X# patch29: the debugger now understands packages and evals
- X# patch29: scripts now run at almost full speed under the debugger
- X# patch29: more variables are settable from debugger
- X#
- X# Revision 3.0.1.3 90/08/09 04:00:58 lwall
- X# patch19: debugger now allows continuation lines
- X# patch19: debugger can now dump lists of variables
- X# patch19: debugger can now add aliases easily from prompt
- X#
- X# Revision 3.0.1.2 90/03/12 16:39:39 lwall
- X# patch13: perl -d didn't format stack traces of *foo right
- X# patch13: perl -d wiped out scalar return values of subroutines
- X#
- X# Revision 3.0.1.1 89/10/26 23:14:02 lwall
- X# patch1: RCS expanded an unintended $Header in lib/perldb.pl
- X#
- 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") || open(IN, "<&STDIN"); # so we don't dingle stdin
- Xopen(OUT,">/dev/tty") || open(OUT, ">&STDOUT"); # so we don't dongle stdout
- Xselect(OUT);
- X$| = 1; # for DB'OUT
- Xselect(STDOUT);
- X$| = 1; # for real STDOUT
- X$sub = '';
- X
- X$header =~ s/.Header: ([^,]+),v(\s+\S+\s+\S+).*$/$1$2/;
- Xprint OUT "\nLoading DB routines from $header\n\nEnter h for help.\n\n";
- X
- Xsub DB {
- X &save;
- X ($package, $filename, $line) = caller;
- X $usercontext = '($@, $!, $[, $,, $/, $\) = @saved;' .
- X "package $package;"; # this won't let them modify, alas
- X local(*dbline) = "_<$filename";
- X $max = $#dbline;
- X if (($stop,$action) = split(/\0/,$dbline{$line})) {
- X if ($stop eq '1') {
- X $signal |= 1;
- X }
- X else {
- X $evalarg = "\$DB'signal |= do {$stop;}"; &eval;
- X $dbline{$line} =~ s/;9($|\0)/$1/;
- X }
- X }
- X if ($single || $trace || $signal) {
- X print OUT "$package'" unless $sub =~ /'/;
- X print OUT "$sub($filename:$line):\t",$dbline[$line];
- X for ($i = $line + 1; $i <= $max && $dbline[$i] == 0; ++$i) {
- X last if $dbline[$i] =~ /^\s*(}|#|\n)/;
- X print OUT "$sub($filename:$i):\t",$dbline[$i];
- X }
- X }
- X $evalarg = $action, &eval if $action;
- X if ($single || $signal) {
- X $evalarg = $pre, &eval if $pre;
- X print OUT $#stack . " levels deep in subroutine calls!\n"
- X if $single & 4;
- X $start = $line;
- X CMD:
- X while ((print OUT " DB<", $#hist+1, "> "), $cmd=&gets) {
- X {
- X $single = 0;
- X $signal = 0;
- X $cmd eq '' && exit 0;
- X chop($cmd);
- X $cmd =~ s/\\$// && do {
- X print OUT " cont: ";
- X $cmd .= &gets;
- X redo CMD;
- X };
- 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.
- Xr Return from 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.
- Xf filename Switch to filename.
- 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 [pkg [vars]] List some (default all) variables in package (default current).
- XX [vars] Same as \"V currentpackage [vars]\".
- 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 \"print DB'OUT expr\" in current package.
- X= [alias value] Define a command alias, or list current aliases.
- Xcommand Execute as a perl statement in current package.
- X
- X";
- X next CMD; };
- X $cmd =~ /^t$/ && do {
- X $trace = !$trace;
- X print OUT "Trace = ".($trace?"on":"off")."\n";
- X next CMD; };
- X $cmd =~ /^S$/ && do {
- X foreach $subname (sort(keys %sub)) {
- X print OUT $subname,"\n";
- X }
- X next CMD; };
- X $cmd =~ s/^X\b/V $package/;
- X $cmd =~ /^V$/ && do {
- X $cmd = 'V $package'; };
- X $cmd =~ /^V\b\s*(\S+)\s*(.*)/ && do {
- X $packname = $1;
- X @vars = split(' ',$2);
- X do 'dumpvar.pl' unless defined &main'dumpvar;
- X if (defined &main'dumpvar) {
- X &main'dumpvar($packname,@vars);
- X }
- X else {
- X print DB'OUT "dumpvar.pl not available.\n";
- X }
- X next CMD; };
- X $cmd =~ /^f\b\s*(.*)/ && do {
- X $file = $1;
- X if (!$file) {
- X print OUT "The old f command is now the r command.\n";
- X print OUT "The new f command switches filenames.\n";
- X next CMD;
- X }
- X if (!defined $_main{'_<' . $file}) {
- X if (($try) = grep(m#^_<.*$file#, keys %_main)) {
- X $file = substr($try,2);
- X print "\n$file:\n";
- X }
- X }
- X if (!defined $_main{'_<' . $file}) {
- X print OUT "There's no code here anything matching $file.\n";
- X next CMD;
- X }
- X elsif ($file ne $filename) {
- X *dbline = "_<$file";
- X $max = $#dbline;
- X $filename = $file;
- X $start = 1;
- X $cmd = "l";
- X } };
- X $cmd =~ /^l\b\s*(['A-Za-z_]['\w]*)/ && do {
- X $subname = $1;
- X $subname = "main'" . $subname unless $subname =~ /'/;
- X $subname = "main" . $subname if substr($subname,0,1) eq "'";
- X ($file,$subrange) = split(/:/,$sub{$subname});
- X if ($file ne $filename) {
- X *dbline = "_<$file";
- X $max = $#dbline;
- X $filename = $file;
- X }
- 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 CMD;
- X } };
- X $cmd =~ /^w\b\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\b\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\b\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", $dbline[$i];
- X last if $signal;
- X }
- X $start = $i; # remember in case they want more
- X $start = $max if $start > $max;
- X next CMD; };
- X $cmd =~ /^D$/ && do {
- X print OUT "Deleting all breakpoints...\n";
- X for ($i = 1; $i <= $max ; $i++) {
- X if (defined $dbline{$i}) {
- X $dbline{$i} =~ s/^[^\0]+//;
- X if ($dbline{$i} =~ s/^\0?$//) {
- X delete $dbline{$i};
- X }
- X }
- X }
- X next CMD; };
- X $cmd =~ /^L$/ && do {
- X for ($i = 1; $i <= $max; $i++) {
- X if (defined $dbline{$i}) {
- X print OUT "$i:\t", $dbline[$i];
- X ($stop,$action) = split(/\0/, $dbline{$i});
- X print OUT " break if (", $stop, ")\n"
- X if $stop;
- X print OUT " action: ", $action, "\n"
- X if $action;
- X last if $signal;
- X }
- X }
- X next CMD; };
- X $cmd =~ /^b\b\s*(['A-Za-z_]['\w]*)\s*(.*)/ && do {
- X $subname = $1;
- X $cond = $2 || '1';
- X $subname = "$package'" . $subname unless $subname =~ /'/;
- X $subname = "main" . $subname if substr($subname,0,1) eq "'";
- X ($filename,$i) = split(/[:-]/, $sub{$subname});
- X if ($i) {
- X *dbline = "_<$filename";
- X ++$i while $dbline[$i] == 0 && $i < $#dbline;
- X $dbline{$i} =~ s/^[^\0]*/$cond/;
- X } else {
- X print OUT "Subroutine $subname not found.\n";
- X }
- X next CMD; };
- X $cmd =~ /^b\b\s*(\d*)\s*(.*)/ && do {
- X $i = ($1?$1:$line);
- X $cond = $2 || '1';
- X if ($dbline[$i] == 0) {
- X print OUT "Line $i not breakable.\n";
- X } else {
- X $dbline{$i} =~ s/^[^\0]*/$cond/;
- X }
- X next CMD; };
- X $cmd =~ /^d\b\s*(\d+)?/ && do {
- X $i = ($1?$1:$line);
- X $dbline{$i} =~ s/^[^\0]*//;
- X delete $dbline{$i} if $dbline{$i} eq '';
- X next CMD; };
- X $cmd =~ /^A$/ && do {
- X for ($i = 1; $i <= $max ; $i++) {
- X if (defined $dbline{$i}) {
- X $dbline{$i} =~ s/\0[^\0]*//;
- X delete $dbline{$i} if $dbline{$i} eq '';
- X }
- X }
- X next CMD; };
- X $cmd =~ /^<\s*(.*)/ && do {
- X $pre = do action($1);
- X next CMD; };
- X $cmd =~ /^>\s*(.*)/ && do {
- X $post = do action($1);
- X next CMD; };
- X $cmd =~ /^a\b\s*(\d+)(\s+(.*))?/ && do {
- X $i = $1;
- X if ($dbline[$i] == 0) {
- X print OUT "Line $i may not have an action.\n";
- X } else {
- X $dbline{$i} =~ s/\0[^\0]*//;
- X $dbline{$i} .= "\0" . do action($3);
- X }
- X next CMD; };
- X $cmd =~ /^n$/ && do {
- X $single = 2;
- X $laststep = $cmd;
- X last CMD; };
- X $cmd =~ /^s$/ && do {
- X $single = 1;
- X $laststep = $cmd;
- X last CMD; };
- X $cmd =~ /^c\b\s*(\d*)\s*$/ && do {
- X $i = $1;
- X if ($i) {
- X if ($dbline[$i] == 0) {
- X print OUT "Line $i not breakable.\n";
- X next CMD;
- X }
- X $dbline{$i} =~ s/(\0|$)/;9$1/; # add one-time-only b.p.
- X }
- X for ($i=0; $i <= $#stack; ) {
- X $stack[$i++] &= ~1;
- X }
- X last CMD; };
- X $cmd =~ /^r$/ && do {
- X $stack[$#stack] |= 2;
- X last CMD; };
- X $cmd =~ /^T$/ && do {
- X local($p,$f,$l,$s,$h,$a,@a,@sub);
- X for ($i = 1; ($p,$f,$l,$s,$h,$w) = caller($i); $i++) {
- X @a = @args;
- X for (@a) {
- X if (/^StB\000/ && length($_) == length($_main{'_main'})) {
- X $_ = sprintf("%s",$_);
- X }
- X else {
- X s/'/\\'/g;
- X s/([^\0]*)/'$1'/ unless /^-?[\d.]+$/;
- X s/([\200-\377])/sprintf("M-%c",ord($1)&0177)/eg;
- X s/([\0-\37\177])/sprintf("^%c",ord($1)^64)/eg;
- X }
- X }
- X $w = $w ? '@ = ' : '$ = ';
- X $a = $h ? '(' . join(', ', @a) . ')' : '';
- X push(@sub, "$w&$s$a from file $f line $l\n");
- X last if $signal;
- X }
- X for ($i=0; $i <= $#sub; $i++) {
- X last if $signal;
- X print OUT $sub[$i];
- X }
- X next CMD; };
- 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 CMD;
- 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 ($dbline[$start] =~ m'."\n$pat\n".'i) {
- X print OUT "$start:\t", $dbline[$start], "\n";
- X last;
- X }
- X } ';
- X print OUT "/$pat/: not found\n" if ($start == $end);
- X next CMD; };
- 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 CMD;
- 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 ($dbline[$start] =~ m'."\n$pat\n".'i) {
- X print OUT "$start:\t", $dbline[$start], "\n";
- X last;
- X }
- X } ';
- X print OUT "?$pat?: not found\n" if ($start == $end);
- X next CMD; };
- 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 CMD; };
- 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 CMD;
- X }
- X $cmd = $hist[$i] . "\n";
- X print OUT $cmd;
- X redo CMD; };
- X $cmd =~ /^H\b\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 CMD; };
- X $cmd =~ s/^p( .*)?$/print DB'OUT$1/;
- X $cmd =~ /^=/ && do {
- X if (local($k,$v) = ($cmd =~ /^=\s*(\S+)\s+(.*)/)) {
- X $alias{$k}="s~$k~$v~";
- X print OUT "$k = $v\n";
- X } elsif ($cmd =~ /^=\s*$/) {
- X foreach $k (sort keys(%alias)) {
- X if (($v = $alias{$k}) =~ s~^s\~$k\~(.*)\~$~$1~) {
- X print OUT "$k = $v\n";
- X } else {
- X print OUT "$k\t$alias{$k}\n";
- X };
- X };
- X };
- X next CMD; };
- X }
- X $evalarg = $cmd; &eval;
- X print OUT "\n";
- X }
- X if ($post) {
- X $evalarg = $post; &eval;
- X }
- X }
- X ($@, $!, $[, $,, $/, $\) = @saved;
- X}
- X
- Xsub save {
- X @saved = ($@, $!, $[, $,, $/, $\);
- X $[ = 0; $, = ""; $/ = "\n"; $\ = "";
- X}
- X
- X# The following takes its argument via $evalarg to preserve current @_
- X
- Xsub eval {
- X eval "$usercontext $evalarg; &DB'save";
- X print OUT $@;
- X}
- X
- Xsub action {
- X local($action) = @_;
- X while ($action =~ s/\\$//) {
- X print OUT "+ ";
- X $action .= &gets;
- X }
- X $action;
- X}
- X
- Xsub gets {
- X local($.);
- X <IN>;
- 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 if (wantarray) {
- X @i = &$sub;
- X $single |= pop(@stack);
- X @i;
- X }
- X else {
- X $i = &$sub;
- X $single |= pop(@stack);
- X $i;
- X }
- X}
- X
- X$single = 1; # so it stops on first executable statement
- 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}
- 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 hash.c
- sed >hash.c <<'!STUFFY!FUNK!' -e 's/X//'
- X/* $Header: hash.c,v 4.0 91/03/20 01:22:26 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 4.0 91/03/20 01:22:26 lwall
- X * 4.0 baseline.
- X *
- X */
- X
- X#include "EXTERN.h"
- X#include "perl.h"
- X
- Xstatic char coeff[] = {
- X 61,59,53,47,43,41,37,31,29,23,17,13,11,7,3,1,
- X 61,59,53,47,43,41,37,31,29,23,17,13,11,7,3,1,
- X 61,59,53,47,43,41,37,31,29,23,17,13,11,7,3,1,
- X 61,59,53,47,43,41,37,31,29,23,17,13,11,7,3,1,
- X 61,59,53,47,43,41,37,31,29,23,17,13,11,7,3,1,
- X 61,59,53,47,43,41,37,31,29,23,17,13,11,7,3,1,
- X 61,59,53,47,43,41,37,31,29,23,17,13,11,7,3,1,
- X 61,59,53,47,43,41,37,31,29,23,17,13,11,7,3,1};
- X
- Xstatic void hfreeentries();
- X
- XSTR *
- Xhfetch(tb,key,klen,lval)
- Xregister HASH *tb;
- Xchar *key;
- Xunsigned int 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 &str_undef;
- X if (!tb->tbl_array) {
- X if (lval)
- X Newz(503,tb->tbl_array, tb->tbl_max + 1, HENT*);
- X else
- X return &str_undef;
- X }
- 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#ifdef HAS_GDBM
- X dcontent = gdbm_fetch(tb->tbl_dbm,dkey);
- X#else
- X dcontent = dbm_fetch(tb->tbl_dbm,dkey);
- X#endif
- 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 &str_undef;
- X}
- X
- Xbool
- Xhstore(tb,key,klen,val,hash)
- Xregister HASH *tb;
- Xchar *key;
- Xunsigned int 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 if (!tb->tbl_array)
- X Newz(505,tb->tbl_array, tb->tbl_max + 1, HENT*);
- 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 void hentdelayfree();
- X
- 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 hentdelayfree(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;
- Xunsigned int 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 || !tb->tbl_array)
- 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_mortal(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#ifdef HAS_GDBM
- X gdbm_delete(tb->tbl_dbm,dkey);
- X#else
- X dbm_delete(tb->tbl_dbm,dkey);
- X#endif
- 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 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
- Xhentdelayfree(hent)
- Xregister HENT *hent;
- X{
- X if (!hent)
- X return;
- X str_2mortal(hent->hent_val); /* free between statements */
- X Safefree(hent->hent_key);
- X Safefree(hent);
- X}
- X
- Xvoid
- Xhclear(tb,dodbm)
- Xregister HASH *tb;
- Xint dodbm;
- X{
- X if (!tb)
- X return;
- X hfreeentries(tb,dodbm);
- X tb->tbl_fill = 0;
- X#ifndef lint
- X if (tb->tbl_array)
- X (void)bzero((char*)tb->tbl_array, (tb->tbl_max + 1) * sizeof(HENT*));
- X#endif
- X}
- X
- Xstatic void
- Xhfreeentries(tb,dodbm)
- Xregister HASH *tb;
- Xint dodbm;
- X{
- X register HENT *hent;
- X register HENT *ohent = Null(HENT*);
- X#ifdef SOME_DBM
- X datum dkey;
- X datum nextdkey;
- X#ifdef HAS_GDBM
- X GDBM_FILE old_dbm;
- X#else
- X#ifdef HAS_NDBM
- X DBM *old_dbm;
- X#else
- X int old_dbm;
- X#endif
- X#endif
- X#endif
- X
- X if (!tb || !tb->tbl_array)
- X return;
- X#ifdef SOME_DBM
- X if ((old_dbm = tb->tbl_dbm) && dodbm) {
- X#ifdef HAS_GDBM
- X while (dkey = gdbm_firstkey(tb->tbl_dbm), dkey.dptr) {
- X#else
- X while (dkey = dbm_firstkey(tb->tbl_dbm), dkey.dptr) {
- X#endif
- X do {
- X#ifdef HAS_GDBM
- X nextdkey = gdbm_nextkey(tb->tbl_dbm, dkey);
- X#else
- X#ifdef HAS_NDBM
- X#ifdef _CX_UX
- X nextdkey = dbm_nextkey(tb->tbl_dbm, dkey);
- X#else
- X nextdkey = dbm_nextkey(tb->tbl_dbm);
- X#endif
- X#else
- X nextdkey = nextkey(dkey);
- X#endif
- X#endif
- X#ifdef HAS_GDBM
- X gdbm_delete(tb->tbl_dbm,dkey);
- X#else
- X dbm_delete(tb->tbl_dbm,dkey);
- X#endif
- X dkey = nextdkey;
- X } while (dkey.dptr); /* one way or another, this works */
- X }
- X }
- X tb->tbl_dbm = 0; /* now clear just cache */
- X#endif
- 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#ifdef SOME_DBM
- X tb->tbl_dbm = old_dbm;
- X#endif
- X}
- X
- Xvoid
- Xhfree(tb,dodbm)
- Xregister HASH *tb;
- Xint dodbm;
- X{
- X if (!tb)
- X return;
- X hfreeentries(tb,dodbm);
- 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 HAS_GDBM
- X key.dptr = entry->hent_key;
- X key.dsize = entry->hent_klen;
- X key = gdbm_nextkey(tb->tbl_dbm, key);
- X#else
- X#ifdef HAS_NDBM
- X#ifdef _CX_UX
- X key.dptr = entry->hent_key;
- X key.dsize = entry->hent_klen;
- 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#endif
- X }
- X else {
- X Newz(504,entry, 1, HENT);
- X tb->tbl_eiter = entry;
- X#ifdef HAS_GDBM
- X key = gdbm_firstkey(tb->tbl_dbm);
- X#else
- X key = dbm_firstkey(tb->tbl_dbm);
- X#endif
- 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 if (!tb->tbl_array)
- X Newz(506,tb->tbl_array, tb->tbl_max + 1, HENT*);
- 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#ifdef HAS_GDBM
- X content = gdbm_fetch(tb->tbl_dbm,key);
- X#else
- X content = dbm_fetch(tb->tbl_dbm,key);
- X#endif
- 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
- X#ifndef O_CREAT
- X# ifdef I_FCNTL
- X# include <fcntl.h>
- X# endif
- X# ifdef I_SYS_FILE
- X# include <sys/file.h>
- X# endif
- 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#ifdef HAS_ODBM
- 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#ifdef HAS_ODBM
- X if (tb->tbl_dbm) /* never really closed it */
- X return TRUE;
- X#endif
- X if (tb->tbl_dbm) {
- X hdbmclose(tb);
- X tb->tbl_dbm = 0;
- X }
- X hclear(tb, FALSE); /* clear cache */
- X#ifdef HAS_GDBM
- X if (mode >= 0)
- X tb->tbl_dbm = gdbm_open(fname, 0, GDBM_WRCREAT,mode, (void *) NULL);
- X if (!tb->tbl_dbm)
- X tb->tbl_dbm = gdbm_open(fname, 0, GDBM_WRITER, mode, (void *) NULL);
- X if (!tb->tbl_dbm)
- X tb->tbl_dbm = gdbm_open(fname, 0, GDBM_READER, mode, (void *) NULL);
- X#else
- X#ifdef HAS_NDBM
- X if (mode >= 0)
- X tb->tbl_dbm = dbm_open(fname, O_RDWR|O_CREAT, mode);
- X if (!tb->tbl_dbm)
- X tb->tbl_dbm = dbm_open(fname, O_RDWR, mode);
- X if (!tb->tbl_dbm)
- 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 (mode < 0 || 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#endif
- X if (!tb->tbl_array && tb->tbl_dbm != 0)
- X Newz(507,tb->tbl_array, tb->tbl_max + 1, HENT*);
- X return tb->tbl_dbm != 0;
- X}
- X
- Xvoid
- Xhdbmclose(tb)
- Xregister HASH *tb;
- X{
- X if (tb && tb->tbl_dbm) {
- X#ifdef HAS_GDBM
- X gdbm_close(tb->tbl_dbm);
- X tb->tbl_dbm = 0;
- X#else
- X#ifdef HAS_NDBM
- X dbm_close(tb->tbl_dbm);
- X tb->tbl_dbm = 0;
- X#else
- X /* dbmrefcnt--; */ /* doesn't work, rats */
- X#endif
- 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;
- Xunsigned int 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#ifdef HAS_GDBM
- X error = gdbm_store(tb->tbl_dbm, dkey, dcontent, GDBM_REPLACE);
- X#else
- X error = dbm_store(tb->tbl_dbm, dkey, dcontent, DBM_REPLACE);
- X#endif
- 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 HAS_NDBM
- X dbm_clearerr(tb->tbl_dbm);
- X#endif
- X }
- X return !error;
- X}
- X#endif /* SOME_DBM */
- !STUFFY!FUNK!
- echo Extracting x2p/find2perl.SH
- sed >x2p/find2perl.SH <<'!STUFFY!FUNK!' -e 's/X//'
- 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
- 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
- Xecho "Extracting find2perl (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 >find2perl <<!GROK!THIS!
- X#!$bin/perl
- X
- X\$bin = "$bin";
- X
- X!GROK!THIS!
- X
- X: In the following dollars and backticks do not need the extra backslash.
- X$spitshell >>find2perl <<'!NO!SUBS!'
- X
- Xwhile ($ARGV[0] =~ /^[^-!(]/) {
- X push(@roots, shift);
- X}
- X@roots = ('.') unless @roots;
- Xfor (@roots) { $_ = "e($_); }
- X$roots = join(',', @roots);
- X
- X$indent = 1;
- X
- Xwhile (@ARGV) {
- X $_ = shift;
- X s/^-// || /^[()!]/ || die "Unrecognized switch: $_\n";
- X if ($_ eq '(') {
- X $out .= &tab . "(\n";
- X $indent++;
- X next;
- X }
- X elsif ($_ eq ')') {
- X $indent--;
- X $out .= &tab . ")";
- X }
- X elsif ($_ eq '!') {
- X $out .= &tab . "!";
- X next;
- X }
- X elsif ($_ eq 'name') {
- X $out .= &tab;
- X $pat = &fileglob_to_re(shift);
- X $out .= '/' . $pat . "/";
- X }
- X elsif ($_ eq 'perm') {
- X $onum = shift;
- X die "Malformed -perm argument: $onum\n" unless $onum =~ /^-?[0-7]+$/;
- X if ($onum =~ s/^-//) {
- X $onum = '0' . sprintf("%o", oct($onum) & 017777); # s/b 07777 ?
- X $out .= &tab . "(\$mode & $onum) == $onum";
- X }
- X else {
- X $onum = '0' . $onum unless $onum =~ /^0/;
- X $out .= &tab . "(\$mode & 0777) == $onum";
- X }
- X }
- X elsif ($_ eq 'type') {
- X ($filetest = shift) =~ tr/s/S/;
- X $out .= &tab . "-$filetest _";
- X }
- X elsif ($_ eq 'print') {
- X $out .= &tab . 'print("$name\n")';
- X }
- X elsif ($_ eq 'print0') {
- X $out .= &tab . 'print("$name\0")';
- X }
- X elsif ($_ eq 'fstype') {
- X $out .= &tab;
- X $type = shift;
- X if ($type eq 'nfs')
- X { $out .= '$dev < 0'; }
- X else
- X { $out .= '$dev >= 0'; }
- X }
- X elsif ($_ eq 'user') {
- X $uname = shift;
- X $out .= &tab . "\$uid == \$uid{'$uname'}";
- X $inituser++;
- X }
- X elsif ($_ eq 'group') {
- X $gname = shift;
- X $out .= &tab . "\$gid == \$gid('$gname')";
- X $initgroup++;
- X }
- X elsif ($_ eq 'nouser') {
- X $out .= &tab . '!defined $uid{$uid}';
- X $inituser++;
- X }
- X elsif ($_ eq 'nogroup') {
- X $out .= &tab . '!defined $gid{$gid}';
- X $initgroup++;
- X }
- X elsif ($_ eq 'links') {
- X $out .= &tab . '$nlink ' . &n(shift);
- X }
- X elsif ($_ eq 'inum') {
- X $out .= &tab . '$ino ' . &n(shift);
- X }
- X elsif ($_ eq 'size') {
- X $out .= &tab . 'int((-s _ + 511) / 512) ' . &n(shift);
- X }
- X elsif ($_ eq 'atime') {
- X $out .= &tab . 'int(-A _) ' . &n(shift);
- X }
- X elsif ($_ eq 'mtime') {
- X $out .= &tab . 'int(-M _) ' . &n(shift);
- X }
- X elsif ($_ eq 'ctime') {
- X $out .= &tab . 'int(-C _) ' . &n(shift);
- X }
- X elsif ($_ eq 'exec') {
- X for (@cmd = (); @ARGV && $ARGV[0] ne ';'; push(@cmd,shift)) { }
- X shift;
- X for (@cmd) { s/'/\\'/g; }
- X $" = "','";
- X $out .= &tab . "&exec(0, '@cmd')";
- X $" = ' ';
- X $initexec++;
- X }
- X elsif ($_ eq 'ok') {
- X for (@cmd = (); @ARGV && $ARGV[0] ne ';'; push(@cmd,shift)) { }
- X shift;
- X for (@cmd) { s/'/\\'/g; }
- X $" = "','";
- X $out .= &tab . "&exec(1, '@cmd')";
- X $" = ' ';
- X $initexec++;
- X }
- X elsif ($_ eq 'prune') {
- X $out .= &tab . '($prune = 1)';
- X }
- X elsif ($_ eq 'xdev') {
- X $out .= &tab . '(($prune |= ($dev != $topdev)),1)';
- X }
- X elsif ($_ eq 'newer') {
- X $out .= &tab;
- X $file = shift;
- X $newername = 'AGE_OF' . $file;
- X $newername =~ s/[^\w]/_/g;
- X $newername = '$' . $newername;
- X $out .= "-M _ < $newername";
- X $initnewer .= "$newername = -M " . "e($file) . ";\n";
- X }
- X elsif ($_ eq 'eval') {
- X $prog = "e(shift);
- X $out .= &tab . "eval $prog";
- X }
- X elsif ($_ eq 'depth') {
- X $depth++;
- X next;
- X }
- X elsif ($_ eq 'ls') {
- X $out .= &tab . "&ls";
- X $initls++;
- X }
- X elsif ($_ eq 'tar') {
- X $out .= &tab;
- X die "-tar must have a filename argument\n" unless @ARGV;
- X $file = shift;
- X $fh = 'FH' . $file;
- X $fh =~ s/[^\w]/_/g;
- X $out .= "&tar($fh)";
- X $file = '>' . $file;
- X $initfile .= "open($fh, " . "e($file) .
- X qq{) || die "Can't open $fh: \$!\\n";\n};
- X $inittar++;
- X $flushall = "\n&tflushall;\n";
- X }
- X elsif (/^n?cpio$/) {
- X $depth++;
- X $out .= &tab;
- X die "-$_ must have a filename argument\n" unless @ARGV;
- X $file = shift;
- X $fh = 'FH' . $file;
- X $fh =~ s/[^\w]/_/g;
- X $out .= "&cpio('" . substr($_,0,1) . "', $fh)";
- X $file = '>' . $file;
- X $initfile .= "open($fh, " . "e($file) .
- X qq{) || die "Can't open $fh: \$!\\n";\n};
- X $initcpio++;
- X $flushall = "\n&flushall;\n";
- X }
- X else {
- X die "Unrecognized switch: -$_\n";
- X }
- X if (@ARGV) {
- X if ($ARGV[0] eq '-o') {
- X $statdone = 0 if $indent == 1 && $delayedstat;
- X $saw_or++;
- X $out .= "\n" . &tab . "||\n";
- X shift;
- X }
- X else {
- X $out .= " &&" unless $ARGV[0] eq ')';
- X $out .= "\n";
- X shift if $ARGV[0] eq '-a';
- X }
- X }
- X}
- X
- Xprint <<"END";
- X#!$bin/perl
- X
- XEND
- X
- Xif ($initls) {
- X print <<'END';
- X@rwx = ('---','--x','-w-','-wx','r--','r-x','rw-','rwx');
- X@moname = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec);
- X
- XEND
- X}
- X
- Xif ($inituser || $initls) {
- X print 'while (($name, $pw, $uid) = getpwent) {', "\n";
- X print ' $uid{$name} = $uid{$uid} = $uid;', "\n" if $inituser;
- X print ' $user{$uid} = $name unless $user{$uid};', "\n" if $initls;
- X print "}\n\n";
- X}
- X
- Xif ($initgroup || $initls) {
- X print 'while (($name, $pw, $gid) = getgrent) {', "\n";
- X print ' $gid{$name} = $gid{$gid} = $gid;', "\n" if $initgroup;
- X print ' $group{$gid} = $name unless $group{$gid};', "\n" if $initls;
- X print "}\n\n";
- X}
- X
- Xprint $initnewer, "\n" if $initnewer;
- X
- Xprint $initfile, "\n" if $initfile;
- X
- Xprint <<"END";
- X# Traverse desired filesystems
- X
- X&dodirs($roots);
- X$flushall
- Xexit;
- X
- Xsub wanted {
- X$out;
- X}
- X
- XEND
- X
- Xprint <<'END';
- Xsub dodirs {
- X chop($cwd = `pwd`);
- X foreach $topdir (@_) {
- X (($topdev,$topino,$topmode,$topnlink) = stat($topdir))
- X || (warn("Can't stat $topdir: $!\n"), next);
- X if (-d _) {
- X if (chdir($topdir)) {
- XEND
- Xif ($depth) {
- X print <<'END';
- X $topdir = '' if $topdir eq '/';
- X &dodir($topdir,$topnlink);
- X ($dir,$_) = ($topdir,'.');
- X $name = $topdir;
- X &wanted;
- XEND
- X}
- Xelse {
- X print <<'END';
- X ($dir,$_) = ($topdir,'.');
- X $name = $topdir;
- X &wanted;
- X $topdir = '' if $topdir eq '/';
- X &dodir($topdir,$topnlink);
- XEND
- X}
- Xprint <<'END';
- X }
- X else {
- X warn "Can't cd to $topdir: $!\n";
- X }
- X }
- X else {
- X unless (($dir,$_) = $topdir =~ m#^(.*/)(.*)$#) {
- X ($dir,$_) = ('.', $topdir);
- X }
- X chdir $dir && &wanted;
- X }
- X chdir $cwd;
- X }
- X}
- X
- Xsub dodir {
- X local($dir,$nlink) = @_;
- X local($dev,$ino,$mode,$subcount);
- X local($name);
- X
- X # Get the list of files in the current directory.
- X
- X opendir(DIR,'.') || warn "Can't open $dir: $!\n";
- X local(@filenames) = readdir(DIR);
- X closedir(DIR);
- X
- X if ($nlink == 2) { # This dir has no subdirectories.
- X for (@filenames) {
- X next if $_ eq '.';
- X next if $_ eq '..';
- X $name = "$dir/$_";
- X $nlink = 0;
- X &wanted;
- X }
- X }
- X else { # This dir has subdirectories.
- X $subcount = $nlink - 2;
- X for (@filenames) {
- X next if $_ eq '.';
- X next if $_ eq '..';
- X $nlink = $prune = 0;
- X $name = "$dir/$_";
- XEND
- Xprint <<'END' unless $depth;
- X &wanted;
- XEND
- Xprint <<'END';
- X if ($subcount > 0) { # Seen all the subdirs?
- X
- X # Get link count and check for directoriness.
- X
- X ($dev,$ino,$mode,$nlink) = lstat($_) unless $nlink;
- X
- X if (-d _) {
- X
- X # It really is a directory, so do it recursively.
- X
- X if (!$prune && chdir $_) {
- X &dodir($name,$nlink);
- X chdir '..';
- X }
- X --$subcount;
- X }
- X }
- XEND
- Xprint <<'END' if $depth;
- X &wanted;
- XEND
- Xprint <<'END';
- X }
- X }
- X}
- X
- XEND
- X
- Xif ($initexec) {
- X print <<'END';
- Xsub exec {
- X local($ok, @cmd) = @_;
- X foreach $word (@cmd) {
- X $word =~ s#{}#$name#g;
- X }
- X if ($ok) {
- X local($old) = select(STDOUT);
- X $| = 1;
- X print "@cmd";
- X select($old);
- X return 0 unless <STDIN> =~ /^y/;
- X }
- X chdir $cwd; # sigh
- X system @cmd;
- X chdir $dir;
- X return !$?;
- X}
- X
- XEND
- X}
- X
- Xif ($initls) {
- X print <<'END';
- Xsub ls {
- X ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$sizemm,
- X $atime,$mtime,$ctime,$blksize,$blocks) = lstat(_);
- X
- X $pname = $name;
- X
- X if (defined $blocks) {
- X $blocks = int(($blocks + 1) / 2);
- X }
- X else {
- X $blocks = int(($size + 1023) / 1024);
- X }
- X
- X if (-f _) { $perms = '-'; }
- X elsif (-d _) { $perms = 'd'; }
- X elsif (-c _) { $perms = 'c'; $sizemm = &sizemm; }
- X elsif (-b _) { $perms = 'b'; $sizemm = &sizemm; }
- X elsif (-p _) { $perms = 'p'; }
- X elsif (-S _) { $perms = 's'; }
- X else { $perms = 'l'; $pname .= ' -> ' . readlink($_); }
- X
- X $tmpmode = $mode;
- X $tmp = $rwx[$tmpmode & 7];
- X $tmpmode >>= 3;
- X $tmp = $rwx[$tmpmode & 7] . $tmp;
- X $tmpmode >>= 3;
- X $tmp = $rwx[$tmpmode & 7] . $tmp;
- X substr($tmp,2,1) =~ tr/-x/Ss/ if -u _;
- X substr($tmp,5,1) =~ tr/-x/Ss/ if -g _;
- X substr($tmp,8,1) =~ tr/-x/Tt/ if -k _;
- X $perms .= $tmp;
- X
- X $user = $user{$uid} || $uid;
- X $group = $group{$gid} || $gid;
- X
- X ($sec,$min,$hour,$mday,$mon,$year) = localtime($mtime);
- X $moname = $moname[$mon];
- X if (-M _ > 365.25 / 2) {
- X $timeyear = '19' . $year;
- X }
- X else {
- X $timeyear = sprintf("%02d:%02d", $hour, $min);
- X }
- X
- X printf "%5lu %4ld %-10s %2d %-8s %-8s %8s %s %2d %5s %s\n",
- X $ino,
- X $blocks,
- X $perms,
- X $nlink,
- X $user,
- X $group,
- X $sizemm,
- X $moname,
- X $mday,
- X $timeyear,
- X $pname;
- X 1;
- X}
- X
- Xsub sizemm {
- X sprintf("%3d, %3d", ($rdev >> 8) & 255, $rdev & 255);
- X}
- X
- XEND
- X}
- X
- Xif ($initcpio) {
- Xprint <<'END';
- Xsub cpio {
- X local($nc,$fh) = @_;
- X local($text);
- X
- X if ($name eq 'TRAILER!!!') {
- X $text = '';
- X $size = 0;
- X }
- X else {
- X ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
- X $atime,$mtime,$ctime,$blksize,$blocks) = lstat(_);
- X if (-f _) {
- X open(IN, $_) || do {
- X warn "Couldn't open $name: $!\n";
- X return;
- X };
- X }
- X else {
- X $text = readlink($_);
- X $size = 0 unless defined $text;
- X }
- X }
- X
- X ($nm = $name) =~ s#^\./##;
- X $nc{$fh} = $nc;
- X if ($nc eq 'n') {
- X $cpout{$fh} .=
- X sprintf("%06o%06o%06o%06o%06o%06o%06o%06o%011lo%06o%011lo%s\0",
- X 070707,
- X $dev & 0777777,
- X $ino & 0777777,
- X $mode & 0777777,
- X $uid & 0777777,
- X $gid & 0777777,
- X $nlink & 0777777,
- X $rdev & 0177777,
- X $mtime,
- X length($nm)+1,
- X $size,
- X $nm);
- X }
- X else {
- X $cpout{$fh} .= "\0" if length($cpout{$fh}) & 1;
- X $cpout{$fh} .= pack("SSSSSSSSLSLa*",
- X 070707, $dev, $ino, $mode, $uid, $gid, $nlink, $rdev, $mtime,
- X length($nm)+1, $size, $nm . (length($nm) & 1 ? "\0" : "\0\0"));
- X }
- X if ($text ne '') {
- X $cpout{$fh} .= $text;
- X }
- X elsif ($size) {
- X &flush($fh) while ($l = length($cpout{$fh})) >= 5120;
- X while (sysread(IN, $cpout{$fh}, 5120 - $l, $l)) {
- X &flush($fh);
- X $l = length($cpout{$fh});
- X }
- X }
- X close IN;
- X}
- X
- Xsub flush {
- X local($fh) = @_;
- X
- X while (length($cpout{$fh}) >= 5120) {
- X syswrite($fh,$cpout{$fh},5120);
- X ++$blocks{$fh};
- X substr($cpout{$fh}, 0, 5120) = '';
- X }
- X}
- X
- Xsub flushall {
- X $name = 'TRAILER!!!';
- X foreach $fh (keys %cpout) {
- X &cpio($nc{$fh},$fh);
- X $cpout{$fh} .= "0" x (5120 - length($cpout{$fh}));
- X &flush($fh);
- X print $blocks{$fh} * 10, " blocks\n";
- X }
- X}
- X
- XEND
- X}
- X
- Xif ($inittar) {
- Xprint <<'END';
- Xsub tar {
- X local($fh) = @_;
- X local($linkname,$header,$l,$slop);
- X local($linkflag) = "\0";
- X
- X ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
- X $atime,$mtime,$ctime,$blksize,$blocks) = lstat(_);
- X $nm = $name;
- X if ($nlink > 1) {
- X if ($linkname = $linkseen{$fh,$dev,$ino}) {
- X $linkflag = 1;
- X }
- X else {
- X $linkseen{$fh,$dev,$ino} = $nm;
- X }
- X }
- X if (-f _) {
- X open(IN, $_) || do {
- X warn "Couldn't open $name: $!\n";
- X return;
- X };
- X $size = 0 if $linkflag ne "\0";
- X }
- X else {
- X $linkname = readlink($_);
- X $linkflag = 2 if defined $linkname;
- X $nm .= '/' if -d _;
- X $size = 0;
- X }
- X
- X $header = pack("a100a8a8a8a12a12a8a1a100",
- X $nm,
- X sprintf("%6o ", $mode & 0777),
- X sprintf("%6o ", $uid & 0777777),
- X sprintf("%6o ", $gid & 0777777),
- X sprintf("%11o ", $size),
- X sprintf("%11o ", $mtime),
- X " ",
- X $linkflag,
- X $linkname);
- X $l = length($header) % 512;
- X substr($header, 148, 6) = sprintf("%6o", unpack("%16C*", $header));
- X substr($header, 154, 1) = "\0"; # blech
- X $tarout{$fh} .= $header;
- X $tarout{$fh} .= "\0" x (512 - $l) if $l;
- X if ($size) {
- X &tflush($fh) while ($l = length($tarout{$fh})) >= 10240;
- X while (sysread(IN, $tarout{$fh}, 10240 - $l, $l)) {
- X $slop = length($tarout{$fh}) % 512;
- X $tarout{$fh} .= "\0" x (512 - $slop) if $slop;
- X &tflush($fh);
- X $l = length($tarout{$fh});
- X }
- X }
- X close IN;
- X}
- X
- Xsub tflush {
- X local($fh) = @_;
- X
- X while (length($tarout{$fh}) >= 10240) {
- X syswrite($fh,$tarout{$fh},10240);
- X ++$blocks{$fh};
- X substr($tarout{$fh}, 0, 10240) = '';
- X }
- X}
- X
- Xsub tflushall {
- X local($len);
- X
- X foreach $fh (keys %tarout) {
- X $len = 10240 - length($tarout{$fh});
- X $len += 10240 if $len < 1024;
- X $tarout{$fh} .= "\0" x $len;
- X &tflush($fh);
- X }
- X}
- X
- XEND
- X}
- X
- Xexit;
- X
- X############################################################################
- X
- Xsub tab {
- X local($tabstring);
- X
- X $tabstring = "\t" x ($indent / 2) . ' ' x ($indent % 2 * 4);
- X if (!$statdone) {
- X if ($_ =~ /^(name|print)/) {
- X $delayedstat++;
- X }
- X else {
- X if ($saw_or) {
- X $tabstring .= <<'ENDOFSTAT' . $tabstring;
- X($nlink || (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_))) &&
- XENDOFSTAT
- X }
- X else {
- X $tabstring .= <<'ENDOFSTAT' . $tabstring;
- X(($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
- XENDOFSTAT
- X }
- X $statdone = 1;
- X }
- X }
- X $tabstring =~ s/^\s+/ / if $out =~ /!$/;
- X $tabstring;
- X}
- X
- Xsub fileglob_to_re {
- X local($tmp) = @_;
- X
- X $tmp =~ s/([.^\$()])/\\$1/g;
- X $tmp =~ s/([?*])/.$1/g;
- X "^$tmp$";
- X}
- X
- Xsub n {
- X local($n) = @_;
- X
- X $n =~ s/^-/< / || $n =~ s/^\+/> / || $n =~ s/^/== /;
- X $n =~ s/ 0*(\d)/ $1/;
- X $n;
- X}
- X
- Xsub quote {
- X local($string) = @_;
- X $string =~ s/'/\\'/;
- X "'$string'";
- X}
- X!NO!SUBS!
- Xchmod 755 find2perl
- X$eunicefix find2perl
- !STUFFY!FUNK!
- echo Extracting eg/muck
- sed >eg/muck <<'!STUFFY!FUNK!' -e 's/X//'
- X#!../perl
- X
- X$M = '-M';
- X$M = '-m' if -d '/usr/uts' && -f '/etc/master';
- X
- Xdo 'getopt.pl';
- Xdo Getopt('f');
- X
- Xif ($opt_f) {
- X $makefile = $opt_f;
- X}
- Xelsif (-f 'makefile') {
- X $makefile = 'makefile';
- X}
- Xelsif (-f 'Makefile') {
- X $makefile = 'Makefile';
- X}
- Xelse {
- X die "No makefile\n";
- X}
- X
- X$MF = 'mf00';
- X
- Xwhile(($key,$val) = each(ENV)) {
- X $mac{$key} = $val;
- X}
- X
- Xdo scan($makefile);
- X
- X$co = $action{'.c.o'};
- X$co = ' ' unless $co;
- X
- X$missing = "Missing dependencies:\n";
- Xforeach $key (sort keys(o)) {
- X if ($oc{$key}) {
- X $src = $oc{$key};
- X $action = $action{$key};
- X }
- X else {
- X $action = '';
- X }
- X if (!$action) {
- X if ($co && ($c = $key) =~ s/\.o$/.c/ && -f $c) {
- X $src = $c;
- X $action = $co;
- X }
- X else {
- X print "No source found for $key $c\n";
- X next;
- X }
- X }
- X $I = '';
- X $D = '';
- X $I .= $1 while $action =~ s/(-I\S+\s*)//;
- X $D .= $1 . ' ' while $action =~ s/(-D\w+)//;
- X if ($opt_v) {
- X $cmd = "Checking $key: cc $M $D $I $src";
- X $cmd =~ s/\s\s+/ /g;
- X print stderr $cmd,"\n";
- X }
- X open(CPP,"cc $M $D $I $src|") || die "Can't run C preprocessor: $!";
- X while (<CPP>) {
- X ($name,$dep) = split;
- X $dep =~ s|^\./||;
- X (print $missing,"$key: $dep\n"),($missing='')
- X unless ($dep{"$key: $dep"} += 2) > 2;
- X }
- X}
- X
- X$extra = "\nExtraneous dependencies:\n";
- Xforeach $key (sort keys(dep)) {
- X if ($key =~ /\.o: .*\.h$/ && $dep{$key} == 1) {
- X print $extra,$key,"\n";
- X $extra = '';
- X }
- X}
- X
- Xsub scan {
- X local($makefile) = @_;
- X local($MF) = $MF;
- X print stderr "Analyzing $makefile.\n" if $opt_v;
- X $MF++;
- X open($MF,$makefile) || die "Can't open $makefile: $!";
- X while (<$MF>) {
- X chop;
- X chop($_ = $_ . <$MF>) while s/\\$//;
- X next if /^#/;
- X next if /^$/;
- X s/\$\((\w+):([^=)]*)=([^)]*)\)/do subst("$1","$2","$3")/eg;
- X s/\$\((\w+)\)/$mac{$1}/eg;
- X $mac{$1} = $2, next if /^(\w+)\s*=\s*(.*)/;
- X if (/^include\s+(.*)/) {
- X do scan($1);
- X print stderr "Continuing $makefile.\n" if $opt_v;
- X next;
- X }
- X if (/^([^:]+):\s*(.*)/) {
- X $left = $1;
- X $right = $2;
- X if ($right =~ /^([^;]*);(.*)/) {
- X $right = $1;
- X $action = $2;
- X }
- X else {
- X $action = '';
- X }
- X while (<$MF>) {
- X last unless /^\t/;
- X chop;
- X chop($_ = $_ . <$MF>) while s/\\$//;
- X next if /^#/;
- X last if /^$/;
- X s/\$\((\w+):([^=)]*)=([^)]*)\)/do subst("$1","$2","$3")/eg;
- X s/\$\((\w+)\)/$mac{$1}/eg;
- X $action .= $_;
- X }
- X foreach $targ (split(' ',$left)) {
- X $targ =~ s|^\./||;
- X foreach $src (split(' ',$right)) {
- X $src =~ s|^\./||;
- X $deplist{$targ} .= ' ' . $src;
- X $dep{"$targ: $src"} = 1;
- X $o{$src} = 1 if $src =~ /\.o$/;
- X $oc{$targ} = $src if $targ =~ /\.o$/ && $src =~ /\.[yc]$/;
- X }
- X $action{$targ} .= $action;
- X }
- X redo if $_;
- X }
- X }
- X close($MF);
- X}
- X
- Xsub subst {
- X local($foo,$from,$to) = @_;
- X $foo = $mac{$foo};
- X $from =~ s/\./[.]/;
- X y/a/a/;
- X $foo =~ s/\b$from\b/$to/g;
- X $foo;
- X}
- !STUFFY!FUNK!
- echo " "
- echo "End of kit 26 (of 36)"
- cat /dev/null >kit26isdone
- 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 25 26 27 28 29 30 31 32 33 34 35 36; 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."
- for combo in *:AA; do
- if test -f "$combo"; then
- realfile=`basename $combo :AA`
- cat $realfile:[A-Z][A-Z] >$realfile
- rm -rf $realfile:[A-Z][A-Z]
- fi
- done
- rm -rf kit*isdone
- chmod 755 Configure
- ;;
- *) echo "You have run$run."
- echo "You still need to run$todo."
- ;;
- esac
- : Someone might mail this, so...
- exit
-
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-