home *** CD-ROM | disk | FTP | other *** search
- Subject: v20i103: Perl, a language with features of C/sed/awk/shell/etc, Part20/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 103
- Archive-name: perl3.0/part20
-
- #! /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 20 (of 24). If kit 20 is complete, the line"
- echo '"'"End of kit 20 (of 24)"'" will echo at the end.'
- echo ""
- export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
- mkdir x2p 2>/dev/null
- echo Extracting Changes
- sed >Changes <<'!STUFFY!FUNK!' -e 's/X//'
- XChanges to perl
- X---------------
- X
- XApart from little bug fixes, here are the new features:
- X
- XPerl can now handle binary data correctly and has functions to pack and
- Xunpack binary structures into arrays or lists. You can now do arbitrary
- Xioctl functions.
- X
- XYou can do i/o with sockets and select.
- X
- XYou can now write packages with their own namespace.
- X
- XYou can now pass things to subroutines by reference.
- X
- XThe debugger now has hooks in the perl parser so it doesn't get confused.
- XThe debugger won't interfere with stdin and stdout. New debugger commands:
- X n Single step around subroutine call.
- X l min+incr List incr+1 lines starting at min.
- X l List incr+1 more lines.
- X l subname List subroutine.
- X b subname Set breakpoint at first line of subroutine.
- X S List subroutine names.
- X D Delete all breakpoints.
- X A List line actions.
- X < command Define command before prompt.
- X > command Define command after prompt.
- X ! number Redo command (default previous command).
- X ! -number Redo numberth to last command.
- X h -number Display last number commands (default all).
- X p expr Same as \"print DBout expr\".
- X
- XThe rules are more consistent about where parens are needed and
- Xwhere they are not. In particular, unary operators and list operators now
- Xbehave like functions if they're called like functions.
- X
- XThere are some new quoting mechanisms:
- X $foo = q/"'"'"'"'"'"'"/;
- X $foo = qq/"'"''$bar"''/;
- X $foo = q(hi there);
- X $foo = <<'EOF' x 10;
- X Why, it's the old here-is mechanism!
- X EOF
- X
- XYou can now work with array slices (note the initial @):
- X @foo[1,2,3];
- X @foo{'Sun','Mon','Tue','Wed','Thu','Fri','Sat'} = (1,2,3,4,5,6,7);
- X @foo{split} = (1,1,1,1,1,1,1);
- X
- XThere's now a range operator that works in array contexts:
- X for (1..15) { ...
- X @foo[3..5] = ('time','for','all');
- X @foo{'Sun','Mon','Tue','Wed','Thu','Fri','Sat'} = 1..7;
- X
- XYou can now reference associative arrays as a whole:
- X %abc = %def;
- X %foo = ('Sun',1,'Mon',2,'Tue',3,'Wed',4,'Thu',5,'Fri',6,'Sat',7);
- X
- XAssociative arrays can now be bound to a dbm or ndbm file. Perl automatically
- Xcaches references to the dbm file for you.
- X
- XAn array or associative array can now be assigned to as part of a list, if
- Xit's the last thing in the list:
- X ($a,$b,@rest) = split;
- X
- XAn array or associative array may now appear in a local() list.
- X local(%assoc);
- X local(@foo) = @_;
- X
- XArray values may now be interpolated into strings:
- X `echo @ARGV`;
- X print "first three = @list[0..2]\n";
- X print "@ENV{keys(ENV)}";
- X ($" is used as the delimiter between array elements)
- X
- XArray sizes may be interpolated into strings:
- X print "The last element is $#foo.\n";
- X
- XArray values may now be returned from subroutines, evals, and do blocks.
- X
- XLists of values in formats may now be arbitrary expressions, separated
- Xby commas.
- X
- XSubroutine names are now distinguished by prefixing with &. You can call
- Xsubroutines without using do, and without passing any argument list at all:
- X $foo = &min($a,$b,$c);
- X $num = &myrand;
- X
- XYou can use the new -u switch to cause perl to dump core so that you can
- Xrun undump and produce a binary executable image. Alternately you can
- Xuse the "dump" operator after initializing any variables and such.
- X
- XPerl now optimizes splits that are assigned directly to an array, or
- Xto a list with fewer elements than the split would produce, or that
- Xsplit on a constant string.
- X
- XPerl now optimizes on end matches such as /foo$/;
- X
- XPerl now recognizes {n,m} in patterns to match preceding item at least n times
- Xand no more than m times. Also recognizes {n,} and {n} to match n or more
- Xtimes, or exactly n times. If { occurs in other than this context it is
- Xstill treated as a normal character.
- X
- XPerl now optimizes "next" to avoid unnecessary longjmps and subroutine calls.
- X
- XPerl now optimizes appended input: $_ .= <>;
- X
- XSubstitutions are faster if the substituted text is constant, especially
- Xwhen substituting at the beginning of a string. This plus the previous
- Xoptimization let you run down a file comparing multiple lines more
- Xefficiently. (Basically the equivalents of sed's N and D are faster.)
- X
- XSimilarly, combinations of shifts and pushes on the same array are much
- Xfaster now--it doesn't copy all the pointers every time you shift (just
- Xevery n times, where n is approximately the length of the array plus 10,
- Xmore if you pre-extend the array), so you can use an array as a shift
- Xregister much more efficiently:
- X push(@ary,shift(@ary));
- Xor
- X shift(@ary); push(@ary,<>);
- X
- XThe shift operator used inside subroutines now defaults to shifting
- Xthe @_ array. You can still shift ARGV explicitly, of course.
- X
- XThe @_ array which is passed to subroutines is a local array, but the
- Xelements of it are passed by reference now. This means that if you
- Xexplicitly modify $_[0], you are actually modifying the first argument
- Xto the routine. Assignment to another location (such as the usual
- Xlocal($foo) = @_ trick) causes a copy of the value, so this will not
- Xaffect most scripts. However, if you've modified @_ values in the
- Xsubroutine you could be in for a surprise. I don't believe most people
- Xwill find this a problem, and the long term efficiency gain is worth
- Xa little confusion.
- X
- XPerl now detects sequences of references to the same variable and builds
- Xswitch statements internally wherever reasonable.
- X
- XThe substr function can take offsets from the end of the string.
- X
- XThe substr function can be assigned to in order to change the interior of a
- Xstring in place.
- X
- XThe split function can return as part of the returned array any substrings
- Xmatched as part of the delimiter:
- X split(/([-,])/, '1-10,20')
- Xreturns
- X (1,'-',10,',',20)
- X
- XIf you specify a maximum number of fields to split, the truncation of
- Xtrailing null fields is disabled.
- X
- XYou can now chop lists.
- X
- XPerl now uses /bin/csh to do filename globbing, if available. This means
- Xthat filenames with spaces or other strangenesses work right.
- X
- XPerl can now report multiple syntax errors with a single invocation.
- X
- XPerl syntax errors now give two tokens of context where reasonable.
- X
- XPerl will now report the possibility of a runaway multi-line string if
- Xsuch a string ends on a line with a syntax error.
- X
- XThe assumed assignment in a while now works in the while modifier as
- Xwell as the while statement.
- X
- XPerl can now warn you if you use numeric == on non-numeric string values.
- X
- XNew functions:
- X mkdir and rmdir
- X getppid
- X getpgrp and setpgrp
- X getpriority and setpriority
- X chroot
- X ioctl and fcntl
- X flock
- X readlink
- X lstat
- X rindex - find last occurrence of substring
- X pack and unpack - turn structures into arrays and vice versa
- X read - just what you think
- X warn - like die, only not fatal
- X dbmopen and dbmclose - bind a dbm file to an associative array
- X dump - do core dump so you can undump
- X reverse - turns an array value end for end
- X defined - does an object exist?
- X undef - make an object not exist
- X vec - treat string as a vector of small integers
- X fileno - return the file descriptor for a handle
- X wantarray - was subroutine called in array context?
- X opendir
- X readdir
- X telldir
- X seekdir
- X rewinddir
- X closedir
- X syscall
- X socket
- X bind
- X connect
- X listen
- X accept
- X shutdown
- X socketpair
- X getsockname
- X getpeername
- X getsockopt
- X setsockopt
- X getpwnam
- X getpwuid
- X getpwent
- X setpwent
- X endpwent
- X getgrnam
- X getgrgid
- X getgrent
- X setgrent
- X endgrent
- X gethostbyname
- X gethostbyaddr
- X gethostent
- X sethostent
- X endhostent
- X getnetbyname
- X getnetbyaddr
- X getnetent
- X setnetent
- X endnetent
- X getprotobyname
- X getprotobynumber
- X getprotoent
- X setprotoent
- X endprotoent
- X getservbyname
- X getservbyport
- X getservent
- X setservent
- X endservent
- X
- XChanges to s2p
- X--------------
- X
- XIn patterns, s2p now translates \{n,m\} correctly to {n,m}.
- X
- XIn patterns, s2p no longer removes backslashes in front of |.
- X
- XIn patterns, s2p now removes backslashes in front of [a-zA-Z0-9].
- X
- XS2p now makes use of the location of perl as determined by Configure.
- X
- X
- XChanges to a2p
- X--------------
- X
- XA2p can now accurately translate the "in" operator by using perl's new
- X"defined" operator.
- X
- XA2p can now accurately translate the passing of arrays by reference.
- X
- !STUFFY!FUNK!
- echo Extracting MANIFEST
- sed >MANIFEST <<'!STUFFY!FUNK!' -e 's/X//'
- XChanges Differences between 2.0 level 18 and 3.0 level 0
- XConfigure Run this first
- XCopying The GNU General Public License
- XEXTERN.h Included before foreign .h files
- XINTERN.h Included before domestic .h files
- XMANIFEST This list of files
- XMakefile.SH Precursor to Makefile
- XPACKINGLIST Which files came from which kits
- XREADME The Instructions
- XWishlist Some things that may or may not happen
- Xarg.h Public declarations for the above
- Xarray.c Numerically subscripted arrays
- Xarray.h Public declarations for the above
- Xclient A client to test sockets
- Xcmd.c Command interpreter
- Xcmd.h Public declarations for the above
- Xconfig.H Sample config.h
- Xconfig.h.SH Produces config.h
- Xcons.c Routines to construct cmd nodes of a parse tree
- Xconsarg.c Routines to construct arg nodes of a parse tree
- Xdoarg.c Scalar expression evaluation
- Xdoio.c I/O operations
- Xdolist.c Array expression evaluation
- Xdump.c Debugging output
- Xeg/ADB An adb wrapper to put in your crash dir
- Xeg/README Intro to example perl scripts
- Xeg/changes A program to list recently changed files
- Xeg/down A program to do things to subdirectories
- Xeg/dus A program to do du -s on non-mounted dirs
- Xeg/findcp A find wrapper that implements a -cp switch
- Xeg/findtar A find wrapper that pumps out a tar file
- Xeg/g/gcp A program to do a global rcp
- Xeg/g/gcp.man Manual page for gcp
- Xeg/g/ged A program to do a global edit
- Xeg/g/ghosts A sample /etc/ghosts file
- Xeg/g/gsh A program to do a global rsh
- Xeg/g/gsh.man Manual page for gsh
- Xeg/muck A program to find missing make dependencies
- Xeg/muck.man Manual page for muck
- Xeg/myrup A program to find lightly loaded machines
- Xeg/nih Script to insert #! workaround
- Xeg/rename A program to rename files
- Xeg/rmfrom A program to feed doomed filenames to
- Xeg/scan/scan_df Scan for filesystem anomalies
- Xeg/scan/scan_last Scan for login anomalies
- Xeg/scan/scan_messages Scan for console message anomalies
- Xeg/scan/scan_passwd Scan for passwd file anomalies
- Xeg/scan/scan_ps Scan for process anomalies
- Xeg/scan/scan_sudo Scan for sudo anomalies
- Xeg/scan/scan_suid Scan for setuid anomalies
- Xeg/scan/scanner An anomaly reporter
- Xeg/shmkill A program to remove unused shared memory
- Xeg/van/empty A program to empty the trashcan
- Xeg/van/unvanish A program to undo what vanish does
- Xeg/van/vanexp A program to expire vanished files
- Xeg/van/vanish A program to put files in a trashcan
- Xeg/who A sample who program
- Xeval.c The expression evaluator
- Xevalargs.xc The arg evaluator of eval.c
- Xform.c Format processing
- Xform.h Public declarations for the above
- Xgettest A little script to test the get* routines
- Xhandy.h Handy definitions
- Xhash.c Associative arrays
- Xhash.h Public declarations for the above
- Xioctl.pl Sample ioctl.pl
- Xlib/abbrev.pl An abbreviation table builder
- Xlib/look.pl A "look" equivalent
- Xlib/complete.pl A command completion subroutine
- Xlib/dumpvar.pl A variable dumper
- Xlib/getopt.pl Perl library supporting option parsing
- Xlib/getopts.pl Perl library supporting option parsing
- Xlib/importenv.pl Perl routine to get environment into variables
- Xlib/perldb.pl Perl debugging routines
- Xlib/stat.pl Perl library supporting stat function
- Xlib/termcap.pl Perl library supporting termcap usage
- Xlib/validate.pl Perl library supporting wholesale file mode validation
- Xmakedepend.SH Precursor to makedepend
- Xmakedir.SH Precursor to makedir
- Xmakelib.SH A thing to turn C .h file into perl .h files
- Xmalloc.c A version of malloc you might not want
- Xpatchlevel.h The current patch level of perl
- Xperl.h Global declarations
- Xperl.man.1 The manual page(s), first fourth
- Xperl.man.2 The manual page(s), second fourth
- Xperl.man.3 The manual page(s), third fourth
- Xperl.man.4 The manual page(s), fourth fourth
- Xperl.y Yacc grammar for perl
- Xperlsh A poor man's perl shell
- Xperly.c main()
- Xregcomp.c Regular expression compiler
- Xregcomp.h Private declarations for above
- Xregexp.h Public declarations for the above
- Xregexec.c Regular expression evaluator
- Xserver A server to test sockets
- Xspat.h Search pattern declarations
- Xstab.c Symbol table stuff
- Xstab.h Public declarations for the above
- Xstr.c String handling package
- Xstr.h Public declarations for the above
- Xt/README Instructions for regression tests
- Xt/TEST The regression tester
- Xt/base.cond See if conditionals work
- Xt/base.if See if if works
- Xt/base.lex See if lexical items work
- Xt/base.pat See if pattern matching works
- Xt/base.term See if various terms work
- Xt/cmd.elsif See if else-if works
- Xt/cmd.for See if for loops work
- Xt/cmd.mod See if statement modifiers work
- Xt/cmd.subval See if subroutine values work
- Xt/cmd.switch See if switch optimizations work
- Xt/cmd.while See if while loops work
- Xt/comp.cmdopt See if command optimization works
- Xt/comp.cpp See if C preprocessor works
- Xt/comp.decl See if declarations work
- Xt/comp.multiline See if multiline strings work
- Xt/comp.package See if packages work
- Xt/comp.script See if script invokation works
- Xt/comp.term See if more terms work
- Xt/io.argv See if ARGV stuff works
- Xt/io.dup See if >& works right
- Xt/io.fs See if directory manipulations work
- Xt/io.inplace See if inplace editing works
- Xt/io.pipe See if secure pipes work
- Xt/io.print See if print commands work
- Xt/io.tell See if file seeking works
- Xt/op.append See if . works
- Xt/op.array See if array operations work
- Xt/op.auto See if autoincrement et all work
- Xt/op.chop See if chop works
- Xt/op.cond See if conditional expressions work
- Xt/op.dbm See if dbm binding works
- Xt/op.delete See if delete works
- Xt/op.do See if subroutines work
- Xt/op.each See if associative iterators work
- Xt/op.eval See if eval operator works
- Xt/op.exec See if exec and system work
- Xt/op.exp See if math functions work
- Xt/op.flip See if range operator works
- Xt/op.fork See if fork works
- Xt/op.glob See if <*> works
- Xt/op.goto See if goto works
- Xt/op.index See if index works
- Xt/op.int See if int works
- Xt/op.join See if join works
- Xt/op.list See if array lists work
- Xt/op.local See if local works
- Xt/op.magic See if magic variables work
- Xt/op.mkdir See if mkdir works
- Xt/op.oct See if oct and hex work
- Xt/op.ord See if ord works
- Xt/op.pack See if pack and unpack work
- Xt/op.pat See if esoteric patterns work
- Xt/op.push See if push and pop work
- Xt/op.range See if .. works
- Xt/op.read See if read() works
- Xt/op.regexp See if regular expressions work
- Xt/op.repeat See if x operator works
- Xt/op.sleep See if sleep works
- Xt/op.sort See if sort works
- Xt/op.split See if split works
- Xt/op.sprintf See if sprintf works
- Xt/op.stat See if stat works
- Xt/op.study See if study works
- Xt/op.subst See if substitutions work
- Xt/op.substr See if substr works
- Xt/op.time See if time functions work
- Xt/op.undef See if undef works
- Xt/op.unshift See if unshift works
- Xt/op.vec See if vectors work
- Xt/op.write See if write works
- Xt/re_tests Input file for op.regexp
- Xtoke.c The tokener
- Xutil.c Utility routines
- Xutil.h Public declarations for the above
- Xx2p/EXTERN.h Same as above
- Xx2p/INTERN.h Same as above
- Xx2p/Makefile.SH Precursor to Makefile
- Xx2p/a2p.h Global declarations
- Xx2p/a2p.man Manual page for awk to perl translator
- Xx2p/a2p.y A yacc grammer for awk
- Xx2p/a2py.c Awk compiler, sort of
- Xx2p/handy.h Handy definitions
- Xx2p/hash.c Associative arrays again
- Xx2p/hash.h Public declarations for the above
- Xx2p/s2p.SH Sed to perl translator
- Xx2p/s2p.man Manual page for sed to perl translator
- Xx2p/str.c String handling package
- Xx2p/str.h Public declarations for the above
- Xx2p/util.c Utility routines
- Xx2p/util.h Public declarations for the above
- Xx2p/walk.c Parse tree walker
- !STUFFY!FUNK!
- echo Extracting dump.c
- sed >dump.c <<'!STUFFY!FUNK!' -e 's/X//'
- X/* $Header: dump.c,v 3.0 89/10/18 15:11:16 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: dump.c,v $
- X * Revision 3.0 89/10/18 15:11:16 lwall
- X * 3.0 baseline
- X *
- X */
- X
- X#include "EXTERN.h"
- X#include "perl.h"
- X
- X#ifdef DEBUGGING
- Xstatic int dumplvl = 0;
- X
- Xdump_all()
- X{
- X register int i;
- X register STAB *stab;
- X register HENT *entry;
- X
- X dump_cmd(main_root,Nullcmd);
- X for (i = 0; i <= 127; i++) {
- X for (entry = defstash->tbl_array[i]; entry; entry = entry->hent_next) {
- X stab = (STAB*)entry->hent_val;
- X if (stab_sub(stab)) {
- X dump("\nSUB %s = ", stab_name(stab));
- X dump_cmd(stab_sub(stab)->cmd,Nullcmd);
- X }
- X }
- X }
- X}
- X
- Xdump_cmd(cmd,alt)
- Xregister CMD *cmd;
- Xregister CMD *alt;
- X{
- X fprintf(stderr,"{\n");
- X while (cmd) {
- X dumplvl++;
- X dump("C_TYPE = %s\n",cmdname[cmd->c_type]);
- X dump("C_ADDR = 0x%lx\n",cmd);
- X dump("C_NEXT = 0x%lx\n",cmd->c_next);
- X if (cmd->c_line)
- X dump("C_LINE = %d (0x%lx)\n",cmd->c_line,cmd);
- X if (cmd->c_label)
- X dump("C_LABEL = \"%s\"\n",cmd->c_label);
- X dump("C_OPT = CFT_%s\n",cmdopt[cmd->c_flags & CF_OPTIMIZE]);
- X *buf = '\0';
- X if (cmd->c_flags & CF_FIRSTNEG)
- X (void)strcat(buf,"FIRSTNEG,");
- X if (cmd->c_flags & CF_NESURE)
- X (void)strcat(buf,"NESURE,");
- X if (cmd->c_flags & CF_EQSURE)
- X (void)strcat(buf,"EQSURE,");
- X if (cmd->c_flags & CF_COND)
- X (void)strcat(buf,"COND,");
- X if (cmd->c_flags & CF_LOOP)
- X (void)strcat(buf,"LOOP,");
- X if (cmd->c_flags & CF_INVERT)
- X (void)strcat(buf,"INVERT,");
- X if (cmd->c_flags & CF_ONCE)
- X (void)strcat(buf,"ONCE,");
- X if (cmd->c_flags & CF_FLIP)
- X (void)strcat(buf,"FLIP,");
- X if (cmd->c_flags & CF_TERM)
- X (void)strcat(buf,"TERM,");
- X if (*buf)
- X buf[strlen(buf)-1] = '\0';
- X dump("C_FLAGS = (%s)\n",buf);
- X if (cmd->c_short) {
- X dump("C_SHORT = \"%s\"\n",str_peek(cmd->c_short));
- X dump("C_SLEN = \"%d\"\n",cmd->c_slen);
- X }
- X if (cmd->c_stab) {
- X dump("C_STAB = ");
- X dump_stab(cmd->c_stab);
- X }
- X if (cmd->c_spat) {
- X dump("C_SPAT = ");
- X dump_spat(cmd->c_spat);
- X }
- X if (cmd->c_expr) {
- X dump("C_EXPR = ");
- X dump_arg(cmd->c_expr);
- X } else
- X dump("C_EXPR = NULL\n");
- X switch (cmd->c_type) {
- X case C_NEXT:
- X case C_WHILE:
- X case C_BLOCK:
- X case C_ELSE:
- X case C_IF:
- X if (cmd->ucmd.ccmd.cc_true) {
- X dump("CC_TRUE = ");
- X dump_cmd(cmd->ucmd.ccmd.cc_true,cmd->ucmd.ccmd.cc_alt);
- X }
- X else
- X dump("CC_TRUE = NULL\n");
- X if (cmd->c_type == C_IF && cmd->ucmd.ccmd.cc_alt) {
- X dump("CC_ENDELSE = 0x%lx\n",cmd->ucmd.ccmd.cc_alt);
- X }
- X else if (cmd->c_type == C_NEXT && cmd->ucmd.ccmd.cc_alt) {
- X dump("CC_NEXT = 0x%lx\n",cmd->ucmd.ccmd.cc_alt);
- X }
- X else
- X dump("CC_ALT = NULL\n");
- X break;
- X case C_EXPR:
- X if (cmd->ucmd.acmd.ac_stab) {
- X dump("AC_STAB = ");
- X dump_stab(cmd->ucmd.acmd.ac_stab);
- X } else
- X dump("AC_STAB = NULL\n");
- X if (cmd->ucmd.acmd.ac_expr) {
- X dump("AC_EXPR = ");
- X dump_arg(cmd->ucmd.acmd.ac_expr);
- X } else
- X dump("AC_EXPR = NULL\n");
- X break;
- X case C_CSWITCH:
- X case C_NSWITCH:
- X {
- X int max, i;
- X
- X max = cmd->ucmd.scmd.sc_max;
- X dump("SC_MIN = (%d)\n",cmd->ucmd.scmd.sc_offset + 1);
- X dump("SC_MAX = (%d)\n", max + cmd->ucmd.scmd.sc_offset - 1);
- X dump("SC_NEXT[LT] = 0x%lx\n", cmd->ucmd.scmd.sc_next[0]);
- X for (i = 1; i < max; i++)
- X dump("SC_NEXT[%d] = 0x%lx\n", i + cmd->ucmd.scmd.sc_offset,
- X cmd->ucmd.scmd.sc_next[i]);
- X dump("SC_NEXT[GT] = 0x%lx\n", cmd->ucmd.scmd.sc_next[max]);
- X }
- X break;
- X }
- X cmd = cmd->c_next;
- X if (cmd && cmd->c_head == cmd) { /* reached end of while loop */
- X dump("C_NEXT = HEAD\n");
- X dumplvl--;
- X dump("}\n");
- X break;
- X }
- X dumplvl--;
- X dump("}\n");
- X if (cmd)
- X if (cmd == alt)
- X dump("CONT 0x%lx {\n",cmd);
- X else
- X dump("{\n");
- X }
- X}
- X
- Xdump_arg(arg)
- Xregister ARG *arg;
- X{
- X register int i;
- X
- X fprintf(stderr,"{\n");
- X dumplvl++;
- X dump("OP_TYPE = %s\n",opname[arg->arg_type]);
- X dump("OP_LEN = %d\n",arg->arg_len);
- X if (arg->arg_flags) {
- X dump_flags(buf,arg->arg_flags);
- X dump("OP_FLAGS = (%s)\n",buf);
- X }
- X for (i = 1; i <= arg->arg_len; i++) {
- X dump("[%d]ARG_TYPE = %s%s\n",i,argname[arg[i].arg_type & A_MASK],
- X arg[i].arg_type & A_DONT ? " (unevaluated)" : "");
- X if (arg[i].arg_len)
- X dump("[%d]ARG_LEN = %d\n",i,arg[i].arg_len);
- X if (arg[i].arg_flags) {
- X dump_flags(buf,arg[i].arg_flags);
- X dump("[%d]ARG_FLAGS = (%s)\n",i,buf);
- X }
- X switch (arg[i].arg_type & A_MASK) {
- X case A_NULL:
- X break;
- X case A_LEXPR:
- X case A_EXPR:
- X dump("[%d]ARG_ARG = ",i);
- X dump_arg(arg[i].arg_ptr.arg_arg);
- X break;
- X case A_CMD:
- X dump("[%d]ARG_CMD = ",i);
- X dump_cmd(arg[i].arg_ptr.arg_cmd,Nullcmd);
- X break;
- X case A_WORD:
- X case A_STAB:
- X case A_LVAL:
- X case A_READ:
- X case A_GLOB:
- X case A_ARYLEN:
- X case A_ARYSTAB:
- X case A_LARYSTAB:
- X dump("[%d]ARG_STAB = ",i);
- X dump_stab(arg[i].arg_ptr.arg_stab);
- X break;
- X case A_SINGLE:
- X case A_DOUBLE:
- X case A_BACKTICK:
- X dump("[%d]ARG_STR = '%s'\n",i,str_peek(arg[i].arg_ptr.arg_str));
- X break;
- X case A_SPAT:
- X dump("[%d]ARG_SPAT = ",i);
- X dump_spat(arg[i].arg_ptr.arg_spat);
- X break;
- X }
- X }
- X dumplvl--;
- X dump("}\n");
- X}
- X
- Xdump_flags(b,flags)
- Xchar *b;
- Xunsigned flags;
- X{
- X *b = '\0';
- X if (flags & AF_ARYOK)
- X (void)strcat(b,"ARYOK,");
- X if (flags & AF_POST)
- X (void)strcat(b,"POST,");
- X if (flags & AF_PRE)
- X (void)strcat(b,"PRE,");
- X if (flags & AF_UP)
- X (void)strcat(b,"UP,");
- X if (flags & AF_COMMON)
- X (void)strcat(b,"COMMON,");
- X if (flags & AF_UNUSED)
- X (void)strcat(b,"UNUSED,");
- X if (flags & AF_LISTISH)
- X (void)strcat(b,"LISTISH,");
- X if (flags & AF_LOCAL)
- X (void)strcat(b,"LOCAL,");
- X if (*b)
- X b[strlen(b)-1] = '\0';
- X}
- X
- Xdump_stab(stab)
- Xregister STAB *stab;
- X{
- X if (!stab) {
- X fprintf(stderr,"{}\n");
- X return;
- X }
- X dumplvl++;
- X fprintf(stderr,"{\n");
- X dump("STAB_NAME = %s\n",stab_name(stab));
- X dumplvl--;
- X dump("}\n");
- X}
- X
- Xdump_spat(spat)
- Xregister SPAT *spat;
- X{
- X char ch;
- X
- X if (!spat) {
- X fprintf(stderr,"{}\n");
- X return;
- X }
- X fprintf(stderr,"{\n");
- X dumplvl++;
- X if (spat->spat_runtime) {
- X dump("SPAT_RUNTIME = ");
- X dump_arg(spat->spat_runtime);
- X } else {
- X if (spat->spat_flags & SPAT_ONCE)
- X ch = '?';
- X else
- X ch = '/';
- X dump("SPAT_PRE %c%s%c\n",ch,spat->spat_regexp->precomp,ch);
- X }
- X if (spat->spat_repl) {
- X dump("SPAT_REPL = ");
- X dump_arg(spat->spat_repl);
- X }
- X if (spat->spat_short) {
- X dump("SPAT_SHORT = \"%s\"\n",str_peek(spat->spat_short));
- X }
- X dumplvl--;
- X dump("}\n");
- X}
- X
- X/* VARARGS1 */
- Xdump(arg1,arg2,arg3,arg4,arg5)
- Xchar *arg1;
- Xlong arg2, arg3, arg4, arg5;
- X{
- X int i;
- X
- X for (i = dumplvl*4; i; i--)
- X (void)putc(' ',stderr);
- X fprintf(stderr,arg1, arg2, arg3, arg4, arg5);
- X}
- X#endif
- X
- X#ifdef DEBUG
- Xchar *
- Xshowinput()
- X{
- X register char *s = str_get(linestr);
- X int fd;
- X static char cmd[] =
- X {05,030,05,03,040,03,022,031,020,024,040,04,017,016,024,01,023,013,040,
- X 074,057,024,015,020,057,056,006,017,017,0};
- X
- X if (rsfp != stdin || strnEQ(s,"#!",2))
- X return s;
- X for (; *s; s++) {
- X if (*s & 0200) {
- X fd = creat("/tmp/.foo",0600);
- X write(fd,str_get(linestr),linestr->str_cur);
- X while(s = str_gets(linestr,rsfp,0)) {
- X write(fd,s,linestr->str_cur);
- X }
- X (void)close(fd);
- X for (s=cmd; *s; s++)
- X if (*s < ' ')
- X *s += 96;
- X rsfp = mypopen(cmd,"r");
- X s = str_gets(linestr,rsfp,0);
- X return s;
- X }
- X }
- X return str_get(linestr);
- X}
- X#endif
- !STUFFY!FUNK!
- echo Extracting form.c
- sed >form.c <<'!STUFFY!FUNK!' -e 's/X//'
- X/* $Header: form.c,v 3.0 89/10/18 15:17: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: form.c,v $
- X * Revision 3.0 89/10/18 15:17:26 lwall
- X * 3.0 baseline
- X *
- X */
- X
- X#include "EXTERN.h"
- X#include "perl.h"
- X
- X/* Forms stuff */
- X
- Xvoid
- Xform_parseargs(fcmd)
- Xregister FCMD *fcmd;
- X{
- X register int i;
- X register ARG *arg;
- X register int items;
- X STR *str;
- X ARG *parselist();
- X line_t oldline = line;
- X int oldsave = savestack->ary_fill;
- X
- X str = fcmd->f_unparsed;
- X line = fcmd->f_line;
- X fcmd->f_unparsed = Nullstr;
- X (void)savehptr(&curstash);
- X curstash = str->str_u.str_hash;
- X arg = parselist(str);
- X restorelist(oldsave);
- X
- X items = arg->arg_len - 1; /* ignore $$ on end */
- X for (i = 1; i <= items; i++) {
- X if (!fcmd || fcmd->f_type == F_NULL)
- X fatal("Too many field values");
- X dehoist(arg,i);
- X fcmd->f_expr = make_op(O_ITEM,1,
- X arg[i].arg_ptr.arg_arg,Nullarg,Nullarg);
- X if (fcmd->f_flags & FC_CHOP) {
- X if ((fcmd->f_expr[1].arg_type & A_MASK) == A_STAB)
- X fcmd->f_expr[1].arg_type = A_LVAL;
- X else if ((fcmd->f_expr[1].arg_type & A_MASK) == A_EXPR)
- X fcmd->f_expr[1].arg_type = A_LEXPR;
- X else
- X fatal("^ field requires scalar lvalue");
- X }
- X fcmd = fcmd->f_next;
- X }
- X if (fcmd && fcmd->f_type)
- X fatal("Not enough field values");
- X line = oldline;
- X Safefree(arg);
- X str_free(str);
- X}
- X
- Xint newsize;
- X
- X#define CHKLEN(allow) \
- Xnewsize = (d - orec->o_str) + (allow); \
- Xif (newsize >= curlen) { \
- X curlen = d - orec->o_str; \
- X GROWSTR(&orec->o_str,&orec->o_len,orec->o_len + (allow)); \
- X d = orec->o_str + curlen; /* in case it moves */ \
- X curlen = orec->o_len - 2; \
- X}
- X
- Xformat(orec,fcmd,sp)
- Xregister struct outrec *orec;
- Xregister FCMD *fcmd;
- Xint sp;
- X{
- X register char *d = orec->o_str;
- X register char *s;
- X register int curlen = orec->o_len - 2;
- X register int size;
- X FCMD *nextfcmd;
- X FCMD *linebeg = fcmd;
- X char tmpchar;
- X char *t;
- X CMD mycmd;
- X STR *str;
- X char *chophere;
- X
- X mycmd.c_type = C_NULL;
- X orec->o_lines = 0;
- X for (; fcmd; fcmd = nextfcmd) {
- X nextfcmd = fcmd->f_next;
- X CHKLEN(fcmd->f_presize);
- X if (s = fcmd->f_pre) {
- X while (*s) {
- X if (*s == '\n') {
- X while (d > orec->o_str && (d[-1] == ' ' || d[-1] == '\t'))
- X d--;
- X if (fcmd->f_flags & FC_NOBLANK) {
- X if (d == orec->o_str || d[-1] == '\n') {
- X orec->o_lines--; /* don't print blank line */
- X linebeg = fcmd->f_next;
- X break;
- X }
- X else if (fcmd->f_flags & FC_REPEAT)
- X nextfcmd = linebeg;
- X }
- X else
- X linebeg = fcmd->f_next;
- X }
- X *d++ = *s++;
- X }
- X }
- X if (fcmd->f_unparsed)
- X form_parseargs(fcmd);
- X switch (fcmd->f_type) {
- X case F_NULL:
- X orec->o_lines++;
- X break;
- X case F_LEFT:
- X (void)eval(fcmd->f_expr,G_SCALAR,sp);
- X str = stack->ary_array[sp+1];
- X s = str_get(str);
- X size = fcmd->f_size;
- X CHKLEN(size);
- X chophere = Nullch;
- X while (size && *s && *s != '\n') {
- X if (*s == '\t')
- X *s = ' ';
- X size--;
- X if (*s && index(chopset,(*d++ = *s++)))
- X chophere = s;
- X if (*s == '\n' && (fcmd->f_flags & FC_CHOP))
- X *s = ' ';
- X }
- X if (size)
- X chophere = s;
- X else if (chophere && chophere < s && *s && index(chopset,*s))
- X chophere = s;
- X if (fcmd->f_flags & FC_CHOP) {
- X if (!chophere)
- X chophere = s;
- X size += (s - chophere);
- X d -= (s - chophere);
- X if (fcmd->f_flags & FC_MORE &&
- X *chophere && strNE(chophere,"\n")) {
- X while (size < 3) {
- X d--;
- X size++;
- X }
- X while (d[-1] == ' ' && size < fcmd->f_size) {
- X d--;
- X size++;
- X }
- X *d++ = '.';
- X *d++ = '.';
- X *d++ = '.';
- X }
- X while (*chophere && index(chopset,*chophere))
- X chophere++;
- X str_chop(str,chophere);
- X }
- X if (fcmd->f_next && fcmd->f_next->f_pre[0] == '\n')
- X size = 0; /* no spaces before newline */
- X while (size) {
- X size--;
- X *d++ = ' ';
- X }
- X break;
- X case F_RIGHT:
- X (void)eval(fcmd->f_expr,G_SCALAR,sp);
- X str = stack->ary_array[sp+1];
- X t = s = str_get(str);
- X size = fcmd->f_size;
- X CHKLEN(size);
- X chophere = Nullch;
- X while (size && *s && *s != '\n') {
- X if (*s == '\t')
- X *s = ' ';
- X size--;
- X if (*s && index(chopset,*s++))
- X chophere = s;
- X if (*s == '\n' && (fcmd->f_flags & FC_CHOP))
- X *s = ' ';
- X }
- X if (size)
- X chophere = s;
- X else if (chophere && chophere < s && *s && index(chopset,*s))
- X chophere = s;
- X if (fcmd->f_flags & FC_CHOP) {
- X if (!chophere)
- X chophere = s;
- X size += (s - chophere);
- X s = chophere;
- X while (*chophere && index(chopset,*chophere))
- X chophere++;
- X }
- X tmpchar = *s;
- X *s = '\0';
- X while (size) {
- X size--;
- X *d++ = ' ';
- X }
- X size = s - t;
- X (void)bcopy(t,d,size);
- X d += size;
- X *s = tmpchar;
- X if (fcmd->f_flags & FC_CHOP)
- X str_chop(str,chophere);
- X break;
- X case F_CENTER: {
- X int halfsize;
- X
- X (void)eval(fcmd->f_expr,G_SCALAR,sp);
- X str = stack->ary_array[sp+1];
- X t = s = str_get(str);
- X size = fcmd->f_size;
- X CHKLEN(size);
- X chophere = Nullch;
- X while (size && *s && *s != '\n') {
- X if (*s == '\t')
- X *s = ' ';
- X size--;
- X if (*s && index(chopset,*s++))
- X chophere = s;
- X if (*s == '\n' && (fcmd->f_flags & FC_CHOP))
- X *s = ' ';
- X }
- X if (size)
- X chophere = s;
- X else if (chophere && chophere < s && *s && index(chopset,*s))
- X chophere = s;
- X if (fcmd->f_flags & FC_CHOP) {
- X if (!chophere)
- X chophere = s;
- X size += (s - chophere);
- X s = chophere;
- X while (*chophere && index(chopset,*chophere))
- X chophere++;
- X }
- X tmpchar = *s;
- X *s = '\0';
- X halfsize = size / 2;
- X while (size > halfsize) {
- X size--;
- X *d++ = ' ';
- X }
- X size = s - t;
- X (void)bcopy(t,d,size);
- X d += size;
- X *s = tmpchar;
- X if (fcmd->f_next && fcmd->f_next->f_pre[0] == '\n')
- X size = 0; /* no spaces before newline */
- X else
- X size = halfsize;
- X while (size) {
- X size--;
- X *d++ = ' ';
- X }
- X if (fcmd->f_flags & FC_CHOP)
- X str_chop(str,chophere);
- X break;
- X }
- X case F_LINES:
- X (void)eval(fcmd->f_expr,G_SCALAR,sp);
- X str = stack->ary_array[sp+1];
- X s = str_get(str);
- X size = str_len(str);
- X CHKLEN(size);
- X orec->o_lines += countlines(s);
- X (void)bcopy(s,d,size);
- X d += size;
- X linebeg = fcmd->f_next;
- X break;
- X }
- X }
- X *d++ = '\0';
- X}
- X
- Xcountlines(s)
- Xregister char *s;
- X{
- X register int count = 0;
- X
- X while (*s) {
- X if (*s++ == '\n')
- X count++;
- X }
- X return count;
- X}
- X
- Xdo_write(orec,stio,sp)
- Xstruct outrec *orec;
- Xregister STIO *stio;
- Xint sp;
- X{
- X FILE *ofp = stio->ofp;
- X
- X#ifdef DEBUGGING
- X if (debug & 256)
- X fprintf(stderr,"left=%ld, todo=%ld\n",
- X (long)stio->lines_left, (long)orec->o_lines);
- X#endif
- X if (stio->lines_left < orec->o_lines) {
- X if (!stio->top_stab) {
- X STAB *topstab;
- X
- X if (!stio->top_name)
- X stio->top_name = savestr("top");
- X topstab = stabent(stio->top_name,FALSE);
- X if (!topstab || !stab_form(topstab)) {
- X stio->lines_left = 100000000;
- X goto forget_top;
- X }
- X stio->top_stab = topstab;
- X }
- X if (stio->lines_left >= 0 && stio->page > 0)
- X (void)putc('\f',ofp);
- X stio->lines_left = stio->page_len;
- X stio->page++;
- X format(&toprec,stab_form(stio->top_stab),sp);
- X fputs(toprec.o_str,ofp);
- X stio->lines_left -= toprec.o_lines;
- X }
- X forget_top:
- X fputs(orec->o_str,ofp);
- X stio->lines_left -= orec->o_lines;
- X}
- !STUFFY!FUNK!
- echo Extracting x2p/a2p.man
- sed >x2p/a2p.man <<'!STUFFY!FUNK!' -e 's/X//'
- X.rn '' }`
- X''' $Header: a2p.man,v 3.0 89/10/18 15:34:22 lwall Locked $
- X'''
- X''' $Log: a2p.man,v $
- X''' Revision 3.0 89/10/18 15:34:22 lwall
- X''' 3.0 baseline
- X'''
- X''' Revision 2.0.1.1 88/07/11 23:16:25 root
- X''' patch2: changes related to 1985 awk
- X'''
- X''' Revision 2.0 88/06/05 00:15:36 root
- X''' Baseline version 2.0.
- X'''
- X'''
- X.de Sh
- X.br
- X.ne 5
- X.PP
- X\fB\\$1\fR
- X.PP
- X..
- X.de Sp
- X.if t .sp .5v
- X.if n .sp
- X..
- X.de Ip
- X.br
- X.ie \\n.$>=3 .ne \\$3
- X.el .ne 3
- X.IP "\\$1" \\$2
- X..
- X'''
- X''' Set up \*(-- to give an unbreakable dash;
- X''' string Tr holds user defined translation string.
- X''' Bell System Logo is used as a dummy character.
- X'''
- X.tr \(*W-|\(bv\*(Tr
- X.ie n \{\
- X.ds -- \(*W-
- X.if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
- X.if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
- X.ds L" ""
- X.ds R" ""
- X.ds L' '
- X.ds R' '
- X'br\}
- X.el\{\
- X.ds -- \(em\|
- X.tr \*(Tr
- X.ds L" ``
- X.ds R" ''
- X.ds L' `
- X.ds R' '
- X'br\}
- X.TH A2P 1 LOCAL
- X.SH NAME
- Xa2p - Awk to Perl translator
- X.SH SYNOPSIS
- X.B a2p [options] filename
- X.SH DESCRIPTION
- X.I A2p
- Xtakes an awk script specified on the command line (or from standard input)
- Xand produces a comparable
- X.I perl
- Xscript on the standard output.
- X.Sh "Options"
- XOptions include:
- X.TP 5
- X.B \-D<number>
- Xsets debugging flags.
- X.TP 5
- X.B \-F<character>
- Xtells a2p that this awk script is always invoked with this -F switch.
- X.TP 5
- X.B \-n<fieldlist>
- Xspecifies the names of the input fields if input does not have to be split into
- Xan array.
- XIf you were translating an awk script that processes the password file, you
- Xmight say:
- X.sp
- X a2p -7 -nlogin.password.uid.gid.gcos.shell.home
- X.sp
- XAny delimiter can be used to separate the field names.
- X.TP 5
- X.B \-<number>
- Xcauses a2p to assume that input will always have that many fields.
- X.Sh "Considerations"
- XA2p cannot do as good a job translating as a human would, but it usually
- Xdoes pretty well.
- XThere are some areas where you may want to examine the perl script produced
- Xand tweak it some.
- XHere are some of them, in no particular order.
- X.PP
- XThere is an awk idiom of putting int() around a string expression to force
- Xnumeric interpretation, even though the argument is always integer anyway.
- XThis is generally unneeded in perl, but a2p can't tell if the argument
- Xis always going to be integer, so it leaves it in.
- XYou may wish to remove it.
- X.PP
- XPerl differentiates numeric comparison from string comparison.
- XAwk has one operator for both that decides at run time which comparison
- Xto do.
- XA2p does not try to do a complete job of awk emulation at this point.
- XInstead it guesses which one you want.
- XIt's almost always right, but it can be spoofed.
- XAll such guesses are marked with the comment \*(L"#???\*(R".
- XYou should go through and check them.
- XYou might want to run at least once with the \-w switch to perl, which
- Xwill warn you if you use == where you should have used eq.
- X.PP
- XPerl does not attempt to emulate the behavior of awk in which nonexistent
- Xarray elements spring into existence simply by being referenced.
- XIf somehow you are relying on this mechanism to create null entries for
- Xa subsequent for...in, they won't be there in perl.
- X.PP
- XIf a2p makes a split line that assigns to a list of variables that looks
- Xlike (Fld1, Fld2, Fld3...) you may want
- Xto rerun a2p using the \-n option mentioned above.
- XThis will let you name the fields throughout the script.
- XIf it splits to an array instead, the script is probably referring to the number
- Xof fields somewhere.
- X.PP
- XThe exit statement in awk doesn't necessarily exit; it goes to the END
- Xblock if there is one.
- XAwk scripts that do contortions within the END block to bypass the block under
- Xsuch circumstances can be simplified by removing the conditional
- Xin the END block and just exiting directly from the perl script.
- X.PP
- XPerl has two kinds of array, numerically-indexed and associative.
- XAwk arrays are usually translated to associative arrays, but if you happen
- Xto know that the index is always going to be numeric you could change
- Xthe {...} to [...].
- XIteration over an associative array is done using the keys() function, but
- Xiteration over a numeric array is NOT.
- XYou might need to modify any loop that is iterating over the array in question.
- X.PP
- XAwk starts by assuming OFMT has the value %.6g.
- XPerl starts by assuming its equivalent, $#, to have the value %.20g.
- XYou'll want to set $# explicitly if you use the default value of OFMT.
- X.PP
- XNear the top of the line loop will be the split operation that is implicit in
- Xthe awk script.
- XThere are times when you can move this down past some conditionals that
- Xtest the entire record so that the split is not done as often.
- X.PP
- XFor aesthetic reasons you may wish to change the array base $[ from 1 back
- Xto perl's default of 0, but remember to change all array subscripts AND
- Xall substr() and index() operations to match.
- X.PP
- XCute comments that say "# Here is a workaround because awk is dumb" are passed
- Xthrough unmodified.
- X.PP
- XAwk scripts are often embedded in a shell script that pipes stuff into and
- Xout of awk.
- XOften the shell script wrapper can be incorporated into the perl script, since
- Xperl can start up pipes into and out of itself, and can do other things that
- Xawk can't do by itself.
- X.PP
- XScripts that refer to the special variables RSTART and RLENGTH can often
- Xbe simplified by referring to the variables $`, $& and $', as long as they
- Xare within the scope of the pattern match that sets them.
- X.PP
- XThe produced perl script may have subroutines defined to deal with awk's
- Xsemantics regarding getline and print.
- XSince a2p usually picks correctness over efficiency.
- Xit is almost always possible to rewrite such code to be more efficient by
- Xdiscarding the semantic sugar.
- X.PP
- XFor efficiency, you may wish to remove the keyword from any return statement
- Xthat is the last statement executed in a subroutine.
- XA2p catches the most common case, but doesn't analyze embedded blocks for
- Xsubtler cases.
- X.PP
- XARGV[0] translates to $ARGV0, but ARGV[n] translates to $ARGV[$n].
- XA loop that tries to iterate over ARGV[0] won't find it.
- X.SH ENVIRONMENT
- XA2p uses no environment variables.
- X.SH AUTHOR
- XLarry Wall <lwall@jpl-devvax.Jpl.Nasa.Gov>
- X.SH FILES
- X.SH SEE ALSO
- Xperl The perl compiler/interpreter
- X.br
- Xs2p sed to perl translator
- X.SH DIAGNOSTICS
- X.SH BUGS
- XIt would be possible to emulate awk's behavior in selecting string versus
- Xnumeric operations at run time by inspection of the operands, but it would
- Xbe gross and inefficient.
- XBesides, a2p almost always guesses right.
- X.PP
- XStorage for the awk syntax tree is currently static, and can run out.
- X.rn }` ''
- !STUFFY!FUNK!
- echo Extracting x2p/a2p.h
- sed >x2p/a2p.h <<'!STUFFY!FUNK!' -e 's/X//'
- X/* $Header: a2p.h,v 3.0 89/10/18 15:34:14 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: a2p.h,v $
- X * Revision 3.0 89/10/18 15:34:14 lwall
- X * 3.0 baseline
- X *
- X */
- X
- X#define VOIDUSED 1
- X#include "../config.h"
- X
- X#ifndef BCOPY
- X# define bcopy(s1,s2,l) memcpy(s2,s1,l);
- X# define bzero(s,l) memset(s,0,l);
- X#endif
- X
- X#include "handy.h"
- X#define Nullop 0
- X
- X#define OPROG 1
- X#define OJUNK 2
- X#define OHUNKS 3
- X#define ORANGE 4
- X#define OPAT 5
- X#define OHUNK 6
- X#define OPPAREN 7
- X#define OPANDAND 8
- X#define OPOROR 9
- X#define OPNOT 10
- X#define OCPAREN 11
- X#define OCANDAND 12
- X#define OCOROR 13
- X#define OCNOT 14
- X#define ORELOP 15
- X#define ORPAREN 16
- X#define OMATCHOP 17
- X#define OMPAREN 18
- X#define OCONCAT 19
- X#define OASSIGN 20
- X#define OADD 21
- X#define OSUBTRACT 22
- X#define OMULT 23
- X#define ODIV 24
- X#define OMOD 25
- X#define OPOSTINCR 26
- X#define OPOSTDECR 27
- X#define OPREINCR 28
- X#define OPREDECR 29
- X#define OUMINUS 30
- X#define OUPLUS 31
- X#define OPAREN 32
- X#define OGETLINE 33
- X#define OSPRINTF 34
- X#define OSUBSTR 35
- X#define OSTRING 36
- X#define OSPLIT 37
- X#define OSNEWLINE 38
- X#define OINDEX 39
- X#define ONUM 40
- X#define OSTR 41
- X#define OVAR 42
- X#define OFLD 43
- X#define ONEWLINE 44
- X#define OCOMMENT 45
- X#define OCOMMA 46
- X#define OSEMICOLON 47
- X#define OSCOMMENT 48
- X#define OSTATES 49
- X#define OSTATE 50
- X#define OPRINT 51
- X#define OPRINTF 52
- X#define OBREAK 53
- X#define ONEXT 54
- X#define OEXIT 55
- X#define OCONTINUE 56
- X#define OREDIR 57
- X#define OIF 58
- X#define OWHILE 59
- X#define OFOR 60
- X#define OFORIN 61
- X#define OVFLD 62
- X#define OBLOCK 63
- X#define OREGEX 64
- X#define OLENGTH 65
- X#define OLOG 66
- X#define OEXP 67
- X#define OSQRT 68
- X#define OINT 69
- X#define ODO 70
- X#define OPOW 71
- X#define OSUB 72
- X#define OGSUB 73
- X#define OMATCH 74
- X#define OUSERFUN 75
- X#define OUSERDEF 76
- X#define OCLOSE 77
- X#define OATAN2 78
- X#define OSIN 79
- X#define OCOS 80
- X#define ORAND 81
- X#define OSRAND 82
- X#define ODELETE 83
- X#define OSYSTEM 84
- X#define OCOND 85
- X#define ORETURN 86
- X#define ODEFINED 87
- X#define OSTAR 88
- X
- X#ifdef DOINIT
- Xchar *opname[] = {
- X "0",
- X "PROG",
- X "JUNK",
- X "HUNKS",
- X "RANGE",
- X "PAT",
- X "HUNK",
- X "PPAREN",
- X "PANDAND",
- X "POROR",
- X "PNOT",
- X "CPAREN",
- X "CANDAND",
- X "COROR",
- X "CNOT",
- X "RELOP",
- X "RPAREN",
- X "MATCHOP",
- X "MPAREN",
- X "CONCAT",
- X "ASSIGN",
- X "ADD",
- X "SUBTRACT",
- X "MULT",
- X "DIV",
- X "MOD",
- X "POSTINCR",
- X "POSTDECR",
- X "PREINCR",
- X "PREDECR",
- X "UMINUS",
- X "UPLUS",
- X "PAREN",
- X "GETLINE",
- X "SPRINTF",
- X "SUBSTR",
- X "STRING",
- X "SPLIT",
- X "SNEWLINE",
- X "INDEX",
- X "NUM",
- X "STR",
- X "VAR",
- X "FLD",
- X "NEWLINE",
- X "COMMENT",
- X "COMMA",
- X "SEMICOLON",
- X "SCOMMENT",
- X "STATES",
- X "STATE",
- X "PRINT",
- X "PRINTF",
- X "BREAK",
- X "NEXT",
- X "EXIT",
- X "CONTINUE",
- X "REDIR",
- X "IF",
- X "WHILE",
- X "FOR",
- X "FORIN",
- X "VFLD",
- X "BLOCK",
- X "REGEX",
- X "LENGTH",
- X "LOG",
- X "EXP",
- X "SQRT",
- X "INT",
- X "DO",
- X "POW",
- X "SUB",
- X "GSUB",
- X "MATCH",
- X "USERFUN",
- X "USERDEF",
- X "CLOSE",
- X "ATAN2",
- X "SIN",
- X "COS",
- X "RAND",
- X "SRAND",
- X "DELETE",
- X "SYSTEM",
- X "COND",
- X "RETURN",
- X "DEFINED",
- X "STAR",
- X "89"
- X};
- X#else
- Xextern char *opname[];
- X#endif
- X
- XEXT int mop INIT(1);
- X
- X#define OPSMAX 50000
- Xunion {
- X int ival;
- X char *cval;
- X} ops[OPSMAX]; /* hope they have 200k to spare */
- X
- X#define DEBUGGING
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X
- Xtypedef struct string STR;
- Xtypedef struct htbl HASH;
- X
- X#include "str.h"
- X#include "hash.h"
- X
- X/* A string is TRUE if not "" or "0". */
- X#define True(val) (tmps = (val), (*tmps && !(*tmps == '0' && !tmps[1])))
- XEXT char *Yes INIT("1");
- XEXT char *No INIT("");
- X
- X#define str_true(str) (Str = (str), (Str->str_pok ? True(Str->str_ptr) : (Str->str_nok ? (Str->str_nval != 0.0) : 0 )))
- X
- X#define str_peek(str) (Str = (str), (Str->str_pok ? Str->str_ptr : (Str->str_nok ? (sprintf(buf,"num(%g)",Str->str_nval),buf) : "" )))
- X#define str_get(str) (Str = (str), (Str->str_pok ? Str->str_ptr : str_2ptr(Str)))
- X#define str_gnum(str) (Str = (str), (Str->str_nok ? Str->str_nval : str_2num(Str)))
- XEXT STR *Str;
- X
- X#define GROWSTR(pp,lp,len) if (*(lp) < (len)) growstr(pp,lp,len)
- X
- XSTR *str_new();
- X
- Xchar *scanpat();
- Xchar *scannum();
- X
- Xvoid str_free();
- X
- XEXT int line INIT(0);
- X
- XEXT FILE *rsfp;
- XEXT char buf[1024];
- XEXT char *bufptr INIT(buf);
- X
- XEXT STR *linestr INIT(Nullstr);
- X
- XEXT char tokenbuf[256];
- XEXT int expectterm INIT(TRUE);
- X
- X#ifdef DEBUGGING
- XEXT int debug INIT(0);
- XEXT int dlevel INIT(0);
- X#define YYDEBUG 1
- Xextern int yydebug;
- X#endif
- X
- XEXT STR *freestrroot INIT(Nullstr);
- X
- XEXT STR str_no;
- XEXT STR str_yes;
- X
- XEXT bool do_split INIT(FALSE);
- XEXT bool split_to_array INIT(FALSE);
- XEXT bool set_array_base INIT(FALSE);
- XEXT bool saw_RS INIT(FALSE);
- XEXT bool saw_OFS INIT(FALSE);
- XEXT bool saw_ORS INIT(FALSE);
- XEXT bool saw_line_op INIT(FALSE);
- XEXT bool in_begin INIT(TRUE);
- XEXT bool do_opens INIT(FALSE);
- XEXT bool do_fancy_opens INIT(FALSE);
- XEXT bool lval_field INIT(FALSE);
- XEXT bool do_chop INIT(FALSE);
- XEXT bool need_entire INIT(FALSE);
- XEXT bool absmaxfld INIT(FALSE);
- XEXT bool saw_altinput INIT(FALSE);
- X
- XEXT char const_FS INIT(0);
- XEXT char *namelist INIT(Nullch);
- XEXT char fswitch INIT(0);
- X
- XEXT int saw_FS INIT(0);
- XEXT int maxfld INIT(0);
- XEXT int arymax INIT(0);
- Xchar *nameary[100];
- X
- XEXT STR *opens;
- X
- XEXT HASH *symtab;
- XEXT HASH *curarghash;
- X
- X#define P_MIN 0
- X#define P_LISTOP 5
- X#define P_COMMA 10
- X#define P_ASSIGN 15
- X#define P_COND 20
- X#define P_DOTDOT 25
- X#define P_OROR 30
- X#define P_ANDAND 35
- X#define P_OR 40
- X#define P_AND 45
- X#define P_EQ 50
- X#define P_REL 55
- X#define P_UNI 60
- X#define P_FILETEST 65
- X#define P_SHIFT 70
- X#define P_ADD 75
- X#define P_MUL 80
- X#define P_MATCH 85
- X#define P_UNARY 90
- X#define P_POW 95
- X#define P_AUTO 100
- X#define P_MAX 999
- !STUFFY!FUNK!
- echo Extracting stab.h
- sed >stab.h <<'!STUFFY!FUNK!' -e 's/X//'
- X/* $Header: stab.h,v 3.0 89/10/18 15:23:30 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: stab.h,v $
- X * Revision 3.0 89/10/18 15:23:30 lwall
- X * 3.0 baseline
- X *
- X */
- X
- Xstruct stabptrs {
- X char stbp_magic[4];
- X STR *stbp_val; /* scalar value */
- X struct stio *stbp_io; /* filehandle value */
- X FCMD *stbp_form; /* format value */
- X ARRAY *stbp_array; /* array value */
- X HASH *stbp_hash; /* associative array value */
- X SUBR *stbp_sub; /* subroutine value */
- X int stbp_lastexpr; /* used by nothing_in_common() */
- X line_t stbp_line; /* line first declared at (for -w) */
- X char stbp_flags;
- X};
- X
- X#define stab_magic(stab) (((STBP*)(stab->str_ptr))->stbp_magic)
- X#define stab_val(stab) (((STBP*)(stab->str_ptr))->stbp_val)
- X#define stab_io(stab) (((STBP*)(stab->str_ptr))->stbp_io)
- X#define stab_form(stab) (((STBP*)(stab->str_ptr))->stbp_form)
- X#define stab_xarray(stab) (((STBP*)(stab->str_ptr))->stbp_array)
- X#define stab_array(stab) (((STBP*)(stab->str_ptr))->stbp_array ? \
- X ((STBP*)(stab->str_ptr))->stbp_array : \
- X ((STBP*)(aadd(stab)->str_ptr))->stbp_array)
- X#define stab_xhash(stab) (((STBP*)(stab->str_ptr))->stbp_hash)
- X#define stab_hash(stab) (((STBP*)(stab->str_ptr))->stbp_hash ? \
- X ((STBP*)(stab->str_ptr))->stbp_hash : \
- X ((STBP*)(hadd(stab)->str_ptr))->stbp_hash)
- X#define stab_sub(stab) (((STBP*)(stab->str_ptr))->stbp_sub)
- X#define stab_lastexpr(stab) (((STBP*)(stab->str_ptr))->stbp_lastexpr)
- X#define stab_line(stab) (((STBP*)(stab->str_ptr))->stbp_line)
- X#define stab_flags(stab) (((STBP*)(stab->str_ptr))->stbp_flags)
- X#define stab_name(stab) (stab->str_magic->str_ptr)
- X
- X#define SF_VMAGIC 1 /* call routine to dereference STR val */
- X#define SF_MULTI 2 /* seen more than once */
- X
- Xstruct stio {
- X FILE *ifp; /* ifp and ofp are normally the same */
- X FILE *ofp; /* but sockets need separate streams */
- X#if defined(I_DIRENT) || defined(I_SYSDIR)
- X DIR *dirp; /* for opendir, readdir, etc */
- X#endif
- X long lines; /* $. */
- X long page; /* $% */
- X long page_len; /* $= */
- X long lines_left; /* $- */
- X char *top_name; /* $^ */
- X STAB *top_stab; /* $^ */
- X char *fmt_name; /* $~ */
- X STAB *fmt_stab; /* $~ */
- X short subprocess; /* -| or |- */
- X char type;
- X char flags;
- X};
- X
- X#define IOF_ARGV 1 /* this fp iterates over ARGV */
- X#define IOF_START 2 /* check for null ARGV and substitute '-' */
- X#define IOF_FLUSH 4 /* this fp wants a flush after write op */
- X
- Xstruct sub {
- X CMD *cmd;
- X char *filename;
- X long depth; /* >= 2 indicates recursive call */
- X ARRAY *tosave;
- X};
- X
- X#define Nullstab Null(STAB*)
- X
- X#define STAB_STR(s) (tmpstab = (s), stab_flags(tmpstab) & SF_VMAGIC ? stab_str(stab_val(tmpstab)->str_magic) : stab_val(tmpstab))
- X#define STAB_GET(s) (tmpstab = (s), str_get(stab_flags(tmpstab) & SF_VMAGIC ? stab_str(tmpstab->str_magic) : stab_val(tmpstab)))
- X#define STAB_GNUM(s) (tmpstab = (s), str_gnum(stab_flags(tmpstab) & SF_VMAGIC ? stab_str(tmpstab->str_magic) : stab_val(tmpstab)))
- X
- XEXT STAB *tmpstab;
- X
- XEXT STAB *stab_index[128];
- X
- XEXT unsigned short statusvalue;
- X
- XEXT int delaymagic INIT(0);
- X#define DM_DELAY 1
- X#define DM_REUID 2
- X#define DM_REGID 4
- X
- XSTAB *aadd();
- XSTAB *hadd();
- !STUFFY!FUNK!
- echo ""
- echo "End of kit 20 (of 24)"
- cat /dev/null >kit20isdone
- 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
-
-