[comp.sources.misc] v18i019: perl - The perl programming language, Part01/36

lwall@netlabs.com (Larry Wall) (04/15/91)

Submitted-by: Larry Wall <lwall@netlabs.com>
Posting-number: Volume 18, Issue 19
Archive-name: perl/part01

[There are 36 kits for perl version 4.0.]

[This is being posted at patchlevel 3. -Kent+]

Perl is a language that combines some of the features of C, sed, awk and shell.

#! /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 1 (of 36).  If kit 1 is complete, the line"
echo '"'"End of kit 1 (of 36)"'" will echo at the end.'
echo ""
export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
mkdir eg eg/sysvipc h2pl msdos os2 t t/op usub 2>/dev/null
echo Extracting os2/README.OS2
sed >os2/README.OS2 <<'!STUFFY!FUNK!' -e 's/X//'
X		   Notes on the OS/2 Perl port
X
X			Raymond Chen
X		 (rjc@math.princeton.edu)
X
X                        Kai Uwe Rommel
X          (rommel@lan.informatik.tu-muenchen.dbp.de)
X
X-1.  Background.
X
XThis port was based on the MS-DOS port by Diomidis Spinellis.
X
X0.  Set-up.
X
XFirst copy the files in the os2 directory into the parent
Xdirectory.  Also install the file msdos/dir.h in your include
Xdirectory.
X
X1.  Compiling.
X
XPerl has been compiled under MS-DOS using the Microsoft C compiler
Xversion 6.0.  Before compiling install dir.h as <sys/dir.h>.  You will
Xneed a Unix-like make program and something like yacc (e.g. bison).  I
Xjust ran yacc on my UNIX box and downloaded the resulting y.tab.[ch]
Xfiles.  Compilation takes 45 minutes on a 16MHz 386 machine running
Xno jobs other than the compiler, so you will probably need something to
Xdo in the meantime.  Like, say, lunch.  (Compilation time does not
Xinclude formatting the manual.)  If you compile with optimization
Xturned off, it takes about half as long.
X
XThe executable is 270k (perlsym.exe is 473k; if you compile
Xwithout optimization, the sizes are 329K/531K), and the top level
Xdirectory needs 800K for sources, 550K for object code, and 800K for the
Xexecutables, assuming you want to build both perl.exe and perlsym.exe
Xwith full optimization.
X
XThe makefile will compile glob for you which you will need to place
Xsomewhere in your path so that perl globbing will work correctly.  All
Xthe tests were run, although some modifications were necessary because
XOS/2 isn't UNIX. The tests that failed failed because of limitations of
Xthe operating system and aren't the fault of the compiler.  a2p and s2p
Xwere not tested.
X
XIn the eg directory you will find the syscalls.pl header file,
Xand a sample program that demonstrates some of the improvements
Xof the OS/2 version over the MS-DOS version and some of the
Xsystem calls.
X
X2.  Using OS/2 Perl
X
XThe OS/2 version of perl has much of the functionality of the Unix
Xversion.  Here are some things that don't work:  sockets, password
Xfunctions, [gs]et[eug]id, dbm functions, fork.
X
XOne thing that doesn't work is "split" with no arguments.  Somehow,
Xyylval.arg is empty ...  [[ Wait, sorry, I fixed that. --rjc ]]
X
XCare has been taken to implement the rest, although the implementation
Xmight not be the best possible.  Here are short notes on the tricky
Xbits:
X
X2.1.  In-place editing.
X
XFiles currently can be edited in-place provided you are creating a
Xbackup.  Considerable effort is made to ensure that a reasonable
Xname for the backup is selected, while still remaining within
Xthe 8.3 contraints of the FAT filesystem.  (HPFS users have nothing
Xto worry about, since HPFS doesn't have the stupid 8.3 rule.)
X
XThe rules for how OS/2 perl combines your filename with the suffix
X(the thing passed to "-i") are rather complicated, but the basic
Xidea is that the "obvious" name is chosen.
X
XHere are the rules:
X
XStyle 0:  Append the suffix exactly as UNIX perl would do it.
X          If the filesystem likes it, use it.  (HPFS will always
X          swallow it.  FAT will rarely accept it.)
X
XStyle 1:  If the suffix begins with a '.', change the file extension
X	  to whatever you supplied.  If the name matches the original
X	  name, use the fallback method.
X
XStyle 2:  If the suffix is a single character, not a '.', try to add the
X          suffix to the following places, using the first one that works.
X              [1] Append to extension.
X              [2] Append to filename,
X              [3] Replace end of extension,
X              [4] Replace end of filename.
X          If the name matches the original name, use the fallback method.
X
XStyle 3:  Any other case:  Ignore the suffix completely and use the
X          fallback method.
X
XFallback method:  Change the extension to ".$$$".  If that matches the
X          original name, then change the extension to ".~~~".
X
XIf filename is more than 1000 characters long, we die a horrible
Xdeath.  Sorry.
X
XExamples, assuming style 0 failed.
X
Xsuffix = ".bak" (style 1)
X               foo.bar => foo.bak
X               foo.bak => foo.$$$	(fallback)
X               foo.$$$ => foo.~~~	(fallback)
X               makefile => makefile.bak
X
Xsuffix = "~" (style 2)
X               foo.c => foo.c~
X               foo.c~ => foo.c~~
X               foo.c~~ => foo~.c~~
X               foo~.c~~ => foo~~.c~~
X               foo~~~~~.c~~ => foo~~~~~.$$$ (fallback)
X
X               foo.pas => foo~.pas
X               makefile => makefile.~
X               longname.fil => longname.fi~
X               longname.fi~ => longnam~.fi~
X               longnam~.fi~ => longnam~.$$$
X
X2.2.  Directory access.
X
XAre implemented, but in order to support telldir() and seekdir(),
Xthey operate by reading in the entire directory at opendir(),
Xthen handing out pieces of it each time you do a readdir().
X
X2.3.  Pipes and redirection.
X
XPipes and redirection are supported.  Although OS/2 does not
Xterminate programs which try to write to closed pipes, perl will
Xkill them for you if you do it like this:
X
X	open(I, "long-running-program|");
X	... process a few lines ...
X	close(I);	# discard the rest ...
X
XThe killing works like this:  We wait until the child program either
Xcloses its stdout or tries to write to it.  If it writes to its stdout,
Xwe kill it.  Otherwise, we cwait for it.  This is pretty much what UNIX
Xdoes by default.
X
XAll pipe commands are given to cmd.exe (or your COMSPEC) for execution as
X
X	CMD /c your-command-line
X
Xso you can go ahead and load it up with any goofy things you want,
Xlike 2>1 redirection, more pipes, && || etc.
X
XThe pipe() function is also supported, so you can go ahead and
Xmake your own funky file descriptor connections before piping off
Xa process.  However, you have to mark the descriptor you are
Xretaining as NOINHERIT before spawning, else you are in deadlock city.
XUnfortunately, there's no way to mark the handle as NOINHERIT yet.
XIt's on my wish list.
X
X2.4.  Syscall and Ioctl
X
XIOCtl is not supported because the API is very different from the
XUNIX API.  Instead, IOCtl is supported as a syscall.  Here are
Xthe syscalls I've written so far:
X
X	$OS2_GetVersion = 0;
X	$OS2_Shutdown = 1;
X	$OS2_Beep = 2;
X	$OS2_PhysicalDisk = 3;
X	$OS2_Config = 4;
X	$OS2_IOCtl = 5;
X	$OS2_QCurDisk = 6;
X	$OS2_SelectDisk = 7;
X	$OS2_SetMaxFH = 8;
X	$OS2_Sleep = 9;
X	$OS2_StartSession = 10;
X	$OS2_StopSession = 11;
X	$OS2_SelectSession = 12;
X
XThe arguments you pass are handed off to OS/2 without interpretation,
Xand the return value is returned straight to you.  However, you don't
Xhave to supply arguments for the ones whose descriptions are "must be
Xzero"; perl will supply the mandatory zeros for you.
X
X2.5.  Binary file access
X
XFiles are opened in text mode by default.  This means that CR LF pairs
Xare translated to LF. If binary access is needed the `binarymode'
Xfunction should be used.  There is currently no way to reverse the
Xeffect of the binary function.  If that is needed close and reopen the
Xfile.
X
X2.6.  Priority
X
XThe getpriority and setpriority functions are implemented, but since
XOS/2 priorities are different from UNIX priorities, the arguments aren't
Xthe same.  Basically, the arguments you pass are handed directly to
XOS/2. The only exception is the last argument to setpriority.  To make
Xit easier to make delta priorities, if the priority class is 0xff, it
Xis changed to 0.  That way, you can write
X
X	setpriority(0,0,-2)
X
Xinstead of
X
X	setpriority(0,0,0xfe)
X
Xto decrease the delta by 2.
X
X2.7.  Interpreter startup.
X
XThe effect of the Unix #!/bin/perl interpreter startup can be obtained
Xunder OS/2 by giving the script a .cmd extension and beginning the script
Xwith the line
X
X	extproc C:\binp\perl.exe -S
X
XYou should provide the appropriate path to your executable, and
Xthe -S option is necessary so that perl can find your script.
X
X2.8.  The kill function.
X
XUNIX and OS/2 have different ideas about the kill function.  I've
Xdone a pretty feeble job of taking perl's UNIXish approach and
Xtrying to jam it into the OS/2 way.  No doubt you'll find that
Xyour kill()s aren't working.  My apologies in advance.
X
X3.  Bug reports.
X
XI don't normally have access to an OS/2 machine, so if you find
Xa bug, you can go ahead and tell me about it, but the odds that
XI'd be able to fix it are slim.
X
X4.  Wish list.
X
X4.1.  OS/2.
X
XMake ENOPIPE a fatal error.
X
XPermit linking of files.  (Allegedly, they're working on this.)
X
XGet a fork.
X
XMake CMD.EXE pass through the return code of its child.
X
X4.2 perl.
X
XProvide a nice way to add new functions to perl without having
Xto understand the innards of perl.  Not being fluent in perl
Xinnards hacking, I added my extra functions via syscall.
X
X4.3. My port.
X
X4.3.1.  In-place editing.
X
XMake more idiot-proof.
X
XAllow in-place editing without backup.  (How?)
X
X4.3.2.  Spawning and piping.
X
XMake popen() cleverer.  Currently, it blindly hands everything
Xoff to CMD.EXE.  This wastes an exec if the command line didn't
Xhave any shell metacharacters and if the program being run
Xis not a batch file.
X
XClever spawning is carried out by do_spawn.  We should try
Xto make popen() do much of the same sort of preprocessing
Xas do_spawn does (which means, of course, that we probably
Xshould yank out code to be dished off into a subroutine).
X
XIn do_spawn(), use DosExecPgm instead of spawnl in order to get more
Xprecise reasons why the child terminated (RESULTCODES).
X
X
X				July 1990
X
X				Raymond Chen <rjc@math.princeton.edu>
X				1817 Oxford St. Apt 6
X				Berkeley, CA 94709-1828 USA
X
X-----------------------
XI picked up the OS/2 port with patches 19-28. When compiling, I found
Xout that os2.c and director.c were missing. I had to rewrite them because
Xeven the original author of the port (Raymond Chen) did no longer have them.
X
XI had directory routines laying around, this was no big deal.
XI rewrote os2.c, but did not implement the syscall() as described above.
XI had not the time and did not really need it. Feel free ...
X
XChanges to above described port:
X
X- the small program GLOB is now named PERLGLOB for better ordering in
X  my /bin directory
X
X- added help page (well, a graphical user interface would be overkill
X  but a simple help page should be in every program :-)
X
X- several cosmetic changes in standard distribution files because of
X  naming conventions etc., #ifdef'd OS2
X
X- syscall() not supported as noted above
X
X- chdir now recognizes also drive letters and changes also the drive
X
X- new mypopen(), mypclose() functions and simulation routines for DOS mode,
X  they are selected automatically in real mode
X- the new pclose() does not kill the child, my experience is that this is
X  not needed.
X
X- setpriority is now:   setpriority(class, pid, val)
X  see description of DosSetPrty() for class and val meanings
X- getpriority is now:   getpriority(dummy, pid)
X  see description of DosGetPrty()
X
X- kill is now:          kill(pid, sig)
X  where sig can be 0 (kill process)
X                   1-3 (send process flags A-C, see DosFlagProcess())
X  if pid is less than zero, the signal is sent to the whole
X  process tree originating at -pid.
X
XThe following files are now new with patch >=29:
X
Xreadme.os2        this file
X
Xdir.h             sys/dir.h
Xdirector.c        directory routines
Xos2.c             kernel of OS/2 port (see below)
Xpopen.c           new popen.c
Xmktemp.c          enhanced mktemp(), uses TMP env. variable, used by popen.c
Xalarm.c           PD implementation for alarm()
Xalarm.h		  header for alarm.c
X
Xperl.cs           Compiler Shell script for perl itself
Xperl.def          linker definition file for perl
Xperl.bad          names of protect-only API calls for BIND
Xperlglob.cs       Compiler Shell script for perl globbing program
Xperlglob.def      linker definition file for perlglob
Xa2p.cs            Compiler Shell script for a2p (see below)
Xa2p.def           linker definition file for a2p
Xmakefile          Makefile, not tested
X
Xperlsh.cmd        the converted perlsh
Xperldb.dif        changes required for perldb.pl (change for your needs)
Xselfrun.cmd       sample selfrunning perl script for OS/2
Xselfrun.bat       sample selfrunning perl script for DOS mode
X
XNote: I don't use make but my own utility, the Compiler Shell CS.
XIt was posted in comp.binaries.os2 or you can ask me for the newest
Xversion. The .CS files are the "makefiles" for it.
X
XNote: MS C 6.00 is required. C 5.1 is not capable of compiling perl,
Xespecially not with -DDEBUGGING
X
X
X                                August 1990
X
X                                Kai Uwe Rommel
X                                rommel@lan.informatik.tu-muenchen.dbp.de
X                                Zennerstr. 1
X                                D-8000 Muenchen 70
X
X
X+ I have verified with patchlevel 37, that the OS/2 port compiles,
X  after doing two minor changes. HPFS filenames support was also added.
X  Some bugs were fixed.
X+ To compile,
X  - you need the bison parser generator
X  - copy config.h from os2 into the main perl directory (important !)
X  - copy perl.cs and perlglob.cs from the os2 subdir to the main dir
X  - copy a2p.cs from os2 to x2p
X  - say "bison -d perl.y"
X      "ren perl_tab.c perl.c" and
X      "ren perl_tab.h perly.h"	in the main directory
X  - say "cs perl" and
X      "cs perlglob" in the main directory
X  - say "cs a2p" in the x2p subdir
X+ If you don't have CS or don't want to use it, you have to
X  construct a makefile ...
X+ If you have GNU gdbm, you can define NDBM in config.h and link with a
X  large model library of gdbm.
X+ I am not shure if I can verify the OS/2 port with each release
X  from Larry Wall. Therefore, in future releases there may be
X  changes required to compile perl for OS/2.
X 				October 1990
X				Kai Uwe Rommel
X				rommel@lan.informatik.tu-muenchen.dbp.de
X
X
XVerified patchlevel 40.
XSome bugs were fixed. Added alarm() support (using PD implementation).
X
X
X 				November 1990
X
X                                Kai Uwe Rommel
X                                rommel@lan.informatik.tu-muenchen.dbp.de
X
X
XVerified patchlevel 44.
XOnly two #ifdefs added to eval.c. Stack size for A2P had to be corrected.
XPERLGLOB separated from DOS version because of HPFS support.
X
X[Note: instead of #ifdef'ing eval.c I fixed it in perl.h--lwall]
X
X				January 1991
X
X                                Kai Uwe Rommel
X                                  rommel@lan.informatik.tu-muenchen.dbp.de
!STUFFY!FUNK!
echo Extracting README
sed >README <<'!STUFFY!FUNK!' -e 's/X//'
X
X			Perl Kit, Version 4.0
X
X		Copyright (c) 1989,1990,1991, Larry Wall
X
X    This program is free software; you can redistribute it and/or modify
X    it under the terms of the GNU General Public License as published by
X    the Free Software Foundation; either version 1, or (at your option)
X    any later version.
X
X    This program is distributed in the hope that it will be useful,
X    but WITHOUT ANY WARRANTY; without even the implied warranty of
X    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
X    GNU General Public License for more details.
X
X    You should have received a copy of the GNU General Public License
X    along with this program; if not, write to the Free Software
X    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X
X    My interpretation of the GNU General Public License is that no Perl
X    script falls under the terms of the License unless you explicitly put
X    said script under the terms of the License yourself.  Furthermore, any
X    object code linked with uperl.o does not automatically fall under the
X    terms of the License, provided such object code only adds definitions
X    of subroutines and variables, and does not otherwise impair the
X    resulting interpreter from executing any standard Perl script.  I
X    consider linking in C subroutines in this manner to be the moral
X    equivalent of defining subroutines in the Perl language itself.  You
X    may sell such an object file as proprietary provided that you provide
X    or offer to provide the Perl source, as specified by the GNU General
X    Public License.  (This is merely an alternate way of specifying input
X    to the program.)  You may also sell a binary produced by the dumping of
X    a running Perl script that belongs to you, provided that you provide or
X    offer to provide the Perl source as specified by the License.  (The
X    fact that a Perl interpreter and your code are in the same binary file
X    is, in this case, a form of mere aggregation.)  This is my interpretation
X    of the License.  If you still have concerns or difficulties understanding
X    my intent, feel free to contact me.
X
X--------------------------------------------------------------------------
X
XPerl is a language that combines some of the features of C, sed, awk and shell.
XSee the manual page for more hype.
X
XPerl will probably not run on machines with a small address space.
X
XPlease read all the directions below before you proceed any further, and
Xthen follow them carefully.
X
XAfter you have unpacked your kit, you should have all the files listed
Xin MANIFEST.
X
XInstallation
X
X1)  Run Configure.  This will figure out various things about your system.
X    Some things Configure will figure out for itself, other things it will
X    ask you about.  It will then proceed to make config.h, config.sh, and
X    Makefile.  If you're a hotshot, run Configure -d to take all the
X    defaults and then edit config.sh to patch up any flaws.
X
X    You might possibly have to trim # comments from the front of Configure
X    if your sh doesn't handle them, but all other # comments will be taken
X    care of.
X
X    (If you don't have sh, you'll have to copy the sample file config.H to
X    config.h and edit the config.h to reflect your system's peculiarities.)
X
X2)  Glance through config.h to make sure system dependencies are correct.
X    Most of them should have been taken care of by running the Configure script.
X
X    If you have any additional changes to make to the C definitions, they
X    can be done in cflags.SH.  For instance, to turn off the optimizer
X    on eval.c, find the line in the switch structure for eval.c and
X    put the command $optimize='-g' before the ;;.  You will probably
X    want to change the entry for teval.c too.  To change the C flags
X    for all the files, edit config.sh and change either $ccflags or $optimize.
X
X3)  make depend
X
X    This will look for all the includes and modify Makefile accordingly.
X    Configure will offer to do this for you.
X
X4)  make
X
X    This will attempt to make perl in the current directory.
X
X    If you can't compile successfully, try adding a -DCRIPPLED_CC flag.
X    (Just because you get no errors doesn't mean it compiled right!)
X    This simplifies some complicated expressions for compilers that
X    get indigestion easily.  If that has no effect, try turning off
X    optimization.  If you have missing routines, you probably need to
X    add some library or other, or you need to undefine some feature that
X    Configure thought was there but is defective or incomplete.
X
X    Some compilers will not compile or optimize the larger files without
X    some extra switches to use larger jump offsets or allocate larger
X    internal tables.  You can customize the switches for each file in
X    cflags.SH.  It's okay to insert rules for specific files into
X    Makefile.SH, since a default rule only takes effect in the
X    absence of a specific rule.
X
X    Most of the following hints are now done automatically by Configure.
X
X    The 3b2 needs to turn off -O.
X    Compilers with limited switch tables may have to define -DSMALLSWITCHES
X    Domain/OS 10.3 (at least) native C 6.7 may need -opt 2 for eval.c
X    AIX/RT may need a -a switch and -DCRIPPLED_CC.
X    AIX RS/6000 needs to use system malloc and avoid -O on eval.c and toke.c.
X    AIX RS/6000 needs -D_NO_PROTO.
X    SUNOS 4.0.[12] needs #define fputs(str,fp) fprintf(fp,"%s",str) in perl.h
X    SUNOS 3.[45] should use the system malloc.
X    SGI machines may need -Ddouble="long float" and -O1.
X    Vax-based systems may need to hand assemble teval.s with a -J switch.
X    Ultrix on MIPS machines may need -DLANGUAGE_C.
X    Ultrix 4.0 on MIPS machines may need -Olimit 2900 or so.
X    Ultrix 3.[01] on MIPS needs to undefine WAITPID--the system call is busted.
X    MIPS machines may need to undef d_volatile.
X    MIPS machines may need to turn off -O on cmd.c, perl.c and tperl.c.
X    Some MIPS machines may need to undefine CASTNEGFLOAT.
X    Xenix 386 needs -Sm11000 for yacc, and may need -UM_I86.
X    SCO Xenix may need -m25000 for yacc.  See also README.xenix.
X    Genix needs to use libc rather than libc_s, or #undef VARARGS.
X    NCR Tower 32 (OS 2.01.01) may need -W2,-Sl,2000 and #undef MKDIR.
X    A/UX may appears to work with -O -B/usr/lib/big/ optimizer flags.
X    A/UX needs -lposix to find rewinddir.
X    A/UX may need -ZP -DPOSIX, and -g if big cc is used.
X    FPS machines may need -J and -DBADSWITCH.
X    UTS may need one or more of -DCRIPPLED_CC, -K or -g, and undef LSTAT.
X    dynix may need to undefine CASTNEGFLOAT (d_castneg='undef' in config.sh).
X    Dnix (not dynix) may need to remove -O.
X    IRIX 3.3 may need to undefine VFORK.
X    HP/UX may need to pull cerror.o and syscall.o out of libc.a and link
X	them in explicitly.
X    If you get syntax errors on '(', try -DCRIPPLED_CC or -DBADSWITCH or both.
X    Machines with half-implemented dbm routines will need to #undef ODBM & NDBM.
X    If you have GDBM available and want it instead of NDBM, say -DHAS_GDBM.
X    C's that don't try to restore registers on longjmp() may need -DJMPCLOBBER.
X	(Try this if you get random glitches.)
X
X5)  make test
X
X    This will run the regression tests on the perl you just made.
X    If it doesn't say "All tests successful" then something went wrong.
X    See the README in the t subdirectory.  Note that you can't run it
X    in background if this disables opening of /dev/tty.  If "make test"
X    bombs out, just cd to the t directory and run TEST by hand to see if
X    it makes any difference.  If individual tests bomb, you can run
X    them by hand, e.g., ./perl op/groups.t
X
X6)  make install
X
X    This will put perl into a public directory (such as /usr/local/bin).
X    It will also try to put the man pages in a reasonable place.  It will not
X    nroff the man page, however.  You may need to be root to do this.  If
X    you are not root, you must own the directories in question and you should
X    ignore any messages about chown not working.
X
X7)  Read the manual entry before running perl.
X
X8)  IMPORTANT!  Help save the world!  Communicate any problems and suggested
X    patches to me, lwall@netlabs.com (Larry Wall), so we can
X    keep the world in sync.  If you have a problem, there's someone else
X    out there who either has had or will have the same problem.
X
X    If possible, send in patches such that the patch program will apply them.
X    Context diffs are the best, then normal diffs.  Don't send ed scripts--
X    I've probably changed my copy since the version you have.
X
X    Watch for perl patches in comp.lang.perl.  Patches will generally be
X    in a form usable by the patch program.  If you are just now bringing up
X    perl and aren't sure how many patches there are, write to me and I'll
X    send any you don't have.  Your current patch level is shown in patchlevel.h.
X
X
XJust a personal note:  I want you to know that I create nice things like this
Xbecause it pleases the Author of my story.  If this bothers you, then your
Xnotion of Authorship needs some revision.  But you can use perl anyway. :-)
X
X							The author.
!STUFFY!FUNK!
echo Extracting msdos/README.msdos
sed >msdos/README.msdos <<'!STUFFY!FUNK!' -e 's/X//'
X		   Notes on the MS-DOS Perl port
X
X			Diomidis Spinellis
X			 (dds@cc.ic.ac.uk)
X
X[0. First copy the files in the msdos directory into the parent
Xdirectory--law]
X
X1.  Compiling.
X
X     Perl has been compiled under MS-DOS using the Microsoft
XC  compiler  version 5.1.  Before compiling install dir.h as
X<sys/dir.h>.  You will need a Unix-like make  program  (e.g.
Xpdmake) and something like yacc (e.g. bison).  You could get
Xaway by running yacc and dry running make on  a  Unix  host,
Xbut  I  haven't tried it.  Compilation takes 12 minutes on a
X20MHz 386 machine (together with formating the  manual),  so
Xyou  will probably need something to do in the meantime. The
Xexecutable is 272k and the top level directory needs 1M  for
Xsources  and  about the same ammount for the object code and
Xthe executables.
X
X     The makefile will compile glob for you which  you  will
Xneed  to  place somewhere in your path so that perl globbing
Xwill work correctly.  I have not tried all the tests or  the
Xexamples,  nor the awk and sed to Perl translators.  You are
Xon your own with them.  In the eg directory I have  included
Xan  example  program  that uses ioctl to display the charac-
Xteristics of the storage devices of the system.
X
X2.  Using MS-DOS Perl
X
X     The MS-DOS version of perl has most of the  functional-
Xity of the Unix version.  Functions that can not be provided
Xunder  MS-DOS  like  sockets,  password  and  host  database
Xaccess,  fork  and wait have been ommited and will terminate
Xwith a fatal error.  Care has been taken  to  implement  the
Xrest.   In particular directory access, redirection (includ-
Xing pipes, but excluding the pipe function),  system,  ioctl
Xand sleep have been provided.
X
X[Files currently can be edited in-place provided you are cre-
Xating  a  backup.   However, if the backup coincidentally has 
Xthe same name as the original, or  if  the  resulting  backup 
Xfilename  is invalid, then the file will probably be trashed.
XFor example, don't do
X
X	perl -i~ script makefile
X	perl -i.bak script file.dat
X
Xbecause  (1)  MS-DOS treats "makefile~" and "makefile" as the
Xsame filename, and (2) "file.dat.bak" is an invalid filename.
XThe  files  "makefile"  and  "file.dat" will probably be lost 
Xforever.  Moral of the story:   Don't  use  in-place  editing 
Xunder MS-DOS. --rjc]
X
X2.1.  Interface to the MS-DOS ioctl system call.
X
X     The function code of the  ioctl  function  (the  second
Xargument) is encoded as follows:
X
X- The lowest nibble of the function code goes to AL.
X- The two middle nibbles go to CL.
X- The high nibble goes to CH.
X
X     The return code is -1 in the case of an  error  and  if
Xsuccessful:
X
X- for functions AL = 00, 09, 0a the value of the register DX
X- for functions AL = 02 - 08, 0e the value of the register AX
X- for functions AL = 01, 0b - 0f the number 0.
X
X     See the perl manual for instruction on how  to  distin-
Xguish between the return value and the success of ioctl.
X
X     Some ioctl functions need a number as the  first  argu-
Xment.   Provided  that  no  other files have been opened the
Xnumber  can  be   obtained   if   ioctl   is   called   with
X@fdnum[number]  as  the  first  argument after executing the
Xfollowing code:
X
X        @fdnum = ("STDIN", "STDOUT", "STDERR");
X        $maxdrives = 15;
X        for ($i = 3; $i < $maxdrives; $i++) {
X                open("FD$i", "nul");
X                @fdnum[$i - 1] = "FD$i";
X        }
X
X2.2.  Binary file access
X
X     Files are opened in text mode by default.   This  means
Xthat  CR LF pairs are translated to LF.  If binary access is
Xneeded the `binary'  function  should  be  used.   There  is
Xcurrently  no  way to reverse the effect of the binary func-
Xtion.  If that is needed close and reopen the file.
X
X2.3.  Interpreter startup.
X
X     The effect of the Unix #!/bin/perl interpreter  startup
Xcan  be  obtained  under  MS-DOS by giving the script a .bat
Xextension and using the following lines on its begining:
X
X        @REM=("
X        @perl %0.bat %1 %2 %3 %4 %5 %6 %7 %8 %9
X        @end ") if 0 ;
X
X(Note that you will probably want an absolute path name in
Xfront of %0.bat).
X
X				March 1990
X
X				Diomidis Spinellis <dds@cc.ic.ac.uk>
X				Myrsinis 1
X				GR-145 62 Kifissia
X				Greece
X
X--------------------------------------------------------------------------
X
X	Revisions to the MS-DOS support in Perl 4.0
X	Tom Dinger, 18 March 1991
X
XThe DOS compatibility added to Perl sometime in release 3.x was not
Xmaintained, and Perl as distributed could not be built without changes.
X
XBoth myself and Len Reed more or less "rediscovered" how to get Perl built
Xand running reliably for MS-DOS, using the Microsoft C compiler.  He and I
Xhave communicated, and will be putting together additional patches for the
XDOS version of Perl.
X
X1. Compiling Perl
X
X    For now, I have not supplied a makefile, as there is no standard for
X    make utilities under DOS.  All the files can be compiled with Microsoft
X    C 5.1, using the switches "-AL -Ox" for Large memory model, maximum
X    optimization (this turned out a few code generation bugs in MSC 5.1).
X    The code will also compile with MSC 6.00A, with the optimization
X    "-Oacegils /Gs" for all files (regcomp.c has special case code to change
X    the aliasing optimizations).
X
X    Generally, you follow the instructions given above to compile and build
X    Perl 4.0 for DOS.  I used the output of SunOS yacc run on perly.y,
X    without modification, but I expect both Bison and Berkeley-YACC will work
X    also.  From inspection of the generated code, however, I believe AT&T
X    derived YACC produces the smallest tables, i.e. uses the least memory.
X    This is important for a 300K executable file.
X
X2. Editing in-place.
X
X    You will need the file suffix.c from the os2 subdirectory -- it will
X    create a backup file with much less danger for DOS.
X
X3. A "Smarter" chdir() function.
X
X    I have added to the DOS version of Perl 4.0 a replacement chdir()
X    function.  Unlike the "normal" behavior, it is aware of drive letters
X    at the start of paths for DOS.  So for example:
X
X    perl_chdir( "B:" )      changes to the default directory, on drive B:
X    perl_chdir( "C:\FOO" )  changes to the specified directory, on drive C:
X    perl_chdir( "\BAR" )    changes to the specified directory on the
X                            current drive.
X
X4. *.BAT Scripts as Perl scripts
X
X    The strategy described above for turning a Perl script into a *.BAT
X    script do not work.  I have been using the following lines at the
X    beginning of a Perl *.BAT script:
X
X        @REM=(qq!
X        @perl -S %0.bat %1 %2 %3 %4 %5 %6 %7 %8 %9
X        @goto end !) if 0 ;
X
X    and the following at the end of the *.BAT script:
X
X        @REM=(qq!
X        :end !) if 0 ;
X
X    If you like, with the proper editor you can replace the four '!'
X    characters with some untypeable character, such as Ctrl-A.  This will
X    allow you to pass any characters, including ".." strings as arguments.
X
X4. Things to Come
X
X     *  Better temporary file handling.
X     *  A real Makefile -- Len Reed has one for Dmake 3.6
X     *  Swapping code -- swaps most of Perl out of memory (to EMS, XMS or
X	disk) before running a sub-program or pipe.
X     *	MKS command line support, both into Perl, and to other programs
X	spawned by Perl.
X     *	Smarter pipe functions, not using COMMAND.COM.
X
X
X					Tom Dinger
X					tdinger@East.Sun.COM
X					Martch 18, 1991
!STUFFY!FUNK!
echo Extracting usub/README
sed >usub/README <<'!STUFFY!FUNK!' -e 's/X//'
XThis directory contains an example of how you might link in C subroutines
Xwith perl to make your own special copy of perl.  In the perl distribution
Xdirectory, there will be (after make is run) a file called uperl.o, which
Xis all of perl except for a single undefined subroutine, named userinit().
XSee usersub.c.
X
XThe sole purpose of the userinit() routine is to call the initialization
Xroutines for any modules that you want to link in.  In this example, we just
Xcall init_curses(), which sets up to link in the BSD curses routines.
XYou'll find this in the file curses.c, which is the processed output of
Xcurses.mus.
X
XThe magicname() routine adds variable names into the symbol table.  Along
Xwith the name of the variable as Perl knows it, we pass a structure containing
Xan index identifying the variable, and the names of two C functions that
Xknow how to set or evaluate a variable given the index of the variable.
XOur example uses a macro to handle this conveniently.
X
XThe init routine calls make_usub() to add user-defined subroutine names
Xinto the symbol table.  The arguments are
X
X	make_usub(subname, subindex, subfunc, filename);
X	char *subname;
X	int subindex;
X	int subfunc();
X	char *filename;
X
XThe subname is the name that will be used in the Perl program.  The subindex
Xwill be passed to subfunc() when it is called to tell it which C function
Xis desired.  subfunc() is a glue routine that translates the arguments
Xfrom Perl internal stack form to the form required by the routine in
Xquestion, calls the desired C function, and then translates any return
Xvalue back into the stack format.  The glue routine used by curses just
Xhas a large switch statement, each branch of which does the processing
Xfor a particular C function.  The subindex could, however, be used to look
Xup a function in a dynamically linked library.  No example of this is
Xprovided.
X
XAs a help in producing the glue routine, a preprocessor called "mus" lets
Xyou specify argument and return value types in a tabular format.  An entry
Xsuch as:
X
X    CASE int waddstr
X    I       WINDOW*         win
X    I       char*           str
X    END
X
Xindicates that waddstr takes two input arguments, the first of which is a
Xpointer to a window, and the second of which is an ordinary C string.  It
Xalso indicates that an integer is returned.  The mus program turns this into:
X
X    case US_waddstr:
X        if (items != 2)
X            fatal("Usage: &waddstr($win, $str)");
X        else {
X            int retval;
X            WINDOW*     win =           *(WINDOW**)     str_get(st[1]);
X            char*       str =           (char*)         str_get(st[2]);
X
X            retval = waddstr(win, str);
X            str_numset(st[0], (double) retval);
X        }
X        return sp;
X
XIt's also possible to have output parameters, indicated by O, and input/ouput
Xparameters indicated by IO.
X
XThe mus program isn't perfect.  You'll note that curses.mus has some
Xcases which are hand coded.  They'll be passed straight through unmodified.
XYou can produce similar cases by analogy to what's in curses.c, as well
Xas similar routines in the doarg.c, dolist.c and doio.c routines of Perl.
XThe mus program is only intended to get you about 90% there.  It's not clear,
Xfor instance, how a given structure should be passed to Perl.  But that
Xshouldn't bother you--if you've gotten this far, it's already obvious
Xthat you are totally mad.
X
XHere's an example of how to return an array value:
X
X    case US_appl_errlist:
X	if (!wantarray) {
X	    str_numset(st[0], (double) appl_nerr);
X	    return sp;
X	}
X	astore(stack, sp + appl_nerr, Nullstr);		/* extend stack */
X	st = stack->ary_array + sp;			/* possibly realloced */
X	for (i = 0; i < appl_nerr; i++) {
X	    tmps = appl_errlist[i];
X	    st[i] = str_2mortal(str_make(tmps,strlen(tmps)));
X	}
X	return sp + appl_nerr - 1;
X
X
XIn addition, there is a program, man2mus, that will scan a man page for
Xfunction prototypes and attempt to construct a mus CASE entry for you.  It has
Xto guess about input/output parameters, so you'll have to tidy up after it.
XBut it can save you a lot of time if the man pages for a library are
Xreasonably well formed.
X
XIf you happen to have BSD curses on your machine, you might try compiling
Xa copy of curseperl.  The "pager" program in this directory is a rudimentary
Xstart on writing a pager--don't believe the help message, which is stolen
Xfrom the less program.
X
XThere is currently no official way to call a Perl routine back from C,
Xbut we're working on it.  It might be easiest to fake up a call to do_eval()
Xor do_subr().  This is not for the faint of heart.  If you come up with
Xsuch a glue routine, I'll be glad to add it into the distribution.
X
XUser-defined subroutines may not currently be called as a signal handler,
Xthough a signal handler may itself call a user-defined subroutine.
!STUFFY!FUNK!
echo Extracting h2pl/README
sed >h2pl/README <<'!STUFFY!FUNK!' -e 's/X//'
X[This file of Tom Christiansen's has been edited to change makelib to h2ph
Xand .h to .ph where appropriate--law.]
X
XThis directory contains files to help you convert the *.ph files generated my
Xh2ph out of the perl source directory into *.pl files with all the
Xindirection of the subroutine calls removed.  The .ph version will be more
Xsafely portable, because if something isn't defined on the new system, like
X&TIOCGETP, then you'll get a fatal run-time error on the system lacking that
Xfunction.  Using the .pl version means that the subsequent scripts will give
Xyou a 0 $TIOCGETP and God only knows what may then happen.   Still, I like the
X.pl stuff because they're faster to load.
X
XFIrst, you need to run h2ph on things like sys/ioctl.h to get stuff
Xinto the perl library directory, often /usr/local/lib/perl.  For example,
X    # h2ph sys/ioctl.h
Xtakes /usr/include/sys/ioctl.h as input and writes (without i/o redirection)
Xthe file /usr/local/lib/perl/sys/ioctl.ph, which looks like this
X
X    eval 'sub TIOCM_RTS {0004;}';
X    eval 'sub TIOCM_ST {0010;}';
X    eval 'sub TIOCM_SR {0020;}';
X    eval 'sub TIOCM_CTS {0040;}';
X    eval 'sub TIOCM_CAR {0100;}';
X
Xand much worse, rather than what Larry's ioctl.pl from the perl source dir has, 
Xwhich is:
X
X    $TIOCM_RTS = 0004;
X    $TIOCM_ST = 0010;
X    $TIOCM_SR = 0020;
X    $TIOCM_CTS = 0040;
X    $TIOCM_CAR = 0100;
X
X[Workaround for fixed bug in makedir/h2ph deleted--law.]
X
XThe more complicated ioctl subs look like this:
X
X    eval 'sub TIOCGSIZE {&TIOCGWINSZ;}';
X    eval 'sub TIOCGWINSZ {&_IOR("t", 104, \'struct winsize\');}';
X    eval 'sub TIOCSETD {&_IOW("t", 1, \'int\');}';
X    eval 'sub TIOCGETP {&_IOR("t", 8,\'struct sgttyb\');}';
X
XThe _IO[RW] routines use a %sizeof array, which (presumably) 
Xis keyed on the type name with the value being the size in bytes.  
X
XTo build %sizeof, try running this in this directory:
X
X    % ./getioctlsizes 
X
XWhich will tell you which things the %sizeof array needs
Xto hold.  You can try to build a sizeof.ph file with:
X
X    % ./getioctlsizes | ./mksizes > sizeof.ph
X
XNote that mksizes hardcodes the #include files for all the types, so it will
Xprobably require customization.  Once you have sizeof.ph, install it in the
Xperl library directory.  Run my tcbreak script to see whether you can do
Xioctls in perl now.  You'll get some kind of fatal run-time error if you
Xcan't.  That script should be included in this directory.
X
XIf this works well, now you can try to convert the *.ph files into
X*.pl files.  Try this:
X
X    foreach file ( sysexits.ph sys/{errno.ph,ioctl.ph} )
X	./mkvars $file > t/$file:r.pl
X    end
X
XThe last one will be the hardest.  If it works, should be able to 
Xrun tcbreak2 and have it work the same as tcbreak.
X
XGood luck.
!STUFFY!FUNK!
echo Extracting README.xenix
sed >README.xenix <<'!STUFFY!FUNK!' -e 's/X//'
XFrom jpl-devvax!elroy.jpl.nasa.gov!sdd.hp.com!spool.mu.edu!uunet!mcsun!ukc!stl!robobar!ronald Thu Mar  7 09:51:06 PST 1991
XArticle 4564 of comp.lang.perl:
XPath: jpl-devvax!elroy.jpl.nasa.gov!sdd.hp.com!spool.mu.edu!uunet!mcsun!ukc!stl!robobar!ronald
X>From: ronald@robobar.co.uk (Ronald S H Khoo)
XNewsgroups: comp.lang.perl
XSubject: Re: directory entries chopped on SCO Unix
XMessage-ID: <1991Mar7.083046.14410@robobar.co.uk>
XDate: 7 Mar 91 08:30:46 GMT
XReferences: <18097@ogicse.ogi.edu> <DJM.91Mar5054514@egypt.eng.umd.edu> <498@stephsf.stephsf.com>
XOrganization: Robobar Ltd., Perivale, Middx., ENGLAND.
XLines: 38
XStatus: OR
X
Xwengland@stephsf.stephsf.com (Bill England) writes:
X
X>   Would modification of the config to 
X>   drop the Xenix specific test and also dropping the -lx library
X>   work better on Xenix boxes ?  Sorry I can't test Xenix here.
X
XThis is a difficult question to answer, mostly because it's hard to
Xtell exactly what kind of Xenix you have.
X
X	Early releases didn't have any kind of ndir  -- no problem
X
X	Many releases have only sys/ndir + -lx       -- no problem
X
X	SCO Xenix 2.3.[012] have ndir + dirent, but dirent is reputedly
X		broken on .0 and .1, hence the hack to undef it.
X
X	*However*, the kernel upgrade to 2.3.3 (where dirent apparently works)
X	from any lower 2.3.? is a free upgrade, which you can anon FTP or UUCP.
X
XI use dirent -- I had to make a decision which set of directory routines
Xto throw out (so that there would be no confusion), so I threw out the
Xold ones.  This means I have to manually remove the ! defined(M_XENIX)
Xhacks from the source which is very ugh.
X
XMy opinion is that the hacks should be removed seeing as they only apply
Xto a small number of operating system versions which you upgrade for
Xfree anyway.  Chip may disagree with me.  It all rather depends on your
Xparticular point of view.
X
XYou could hack Configure to do case "`uname -r`" in 2.3.[01])
XI guess.  It's a lot of code to handle just one specific case,
Xsince you have to determine whether to do it or not as well.
X
XIn short, I Really Don't Know But It's All Very Annoying.
X
XJust another Xenix user,
X-- 
XRonald Khoo <ronald@robobar.co.uk> +44 81 991 1142 (O) +44 71 229 7741 (H)
X
X
!STUFFY!FUNK!
echo Extracting README.uport
sed >README.uport <<'!STUFFY!FUNK!' -e 's/X//'
XFrom dwm@uf.msc.umn.edu  Tue Dec 19 15:03:27 1989
XSubject: perl on Microport Un*x 2.4
X
XHere are the steps to get perl patchlevel 6 running on Microport Un*x 2.4.
X
X(1) Get the directory routines (opendir, readdir, etc) from an archive 
X    somewhere.   I got mine from uunet:  comp.sources.unix/volume9/gwyn-dir-lib
X    and comp.sources.unix/volume10/dir-lib.pch.   Compile a large memory
X    version of the library and put it in /usr/lib/large/dir.a.  Also put
X    the dir.h include file in /usr/include/sys.  [ If you don't want to
X    do this make sure I_SYSDIR does not defined in config.sh ]
X
X(2) Configure causes sh to get a segmentation fault when it does the
X    ". config.sh" near line 2551.   You will have to remove that line 
X    from Configure and make sure you get your configuration info right 
X    the first time or start over if you make a mistake.  
X
X[Or just run the .SH files by hand and proceed to the make depend.]
X
X(3) If you are using C-shell, put a blank line at the start of Configure so it
X    wont get executed by the C-shell.   If you are using ksh, you will have to
X    execute Configure with 'sh Configure'.  Configure does not work with
X    ksh.
X
X(4) When you run Configure, select compilation option -DCRIPPLED_CC.
X    I also selected -DDEBUGGING to make debugging easier.  I recommend it.
X    You can use -O, but you will then have to compile consarg.c and util.c
X    separately without -O because the optimizer generates bad code for these
X    routines.   The optimizer also dies harmlessly while optimizing cmd.c,
X    eval.c (who can blame it? [sorry, Larry]), and toke.c.   
X    I am still trying to isolate the remaining optimization problems in 
X    consarg.c and util.c.
X
X[The rest of the previously published instructions are no longer necessary.]
!STUFFY!FUNK!
echo Extracting eg/README
sed >eg/README <<'!STUFFY!FUNK!' -e 's/X//'
XAlthough supplied with the perl package, the perl scripts in this eg
Xdirectory and its subdirectories are placed in the public domain, and
Xyou may do anything with them that you wish.
X
XThis stuff is supplied on an as-is basis--little attempt has been made to make
Xany of it portable.  It's mostly here to give you an idea of what perl code
Xlooks like, and what tricks and idioms are used.
X
XSystem administrators responsible for many computers will enjoy the items
Xdown in the g directory very much.  The scan directory contains the beginnings
Xof a system to check on and report various kinds of anomalies.
X
XIf you machine doesn't support #!, the first thing you'll want to do is
Xreplace the #! with a couple of lines that look like this:
X
X	eval "exec /usr/bin/perl -S $0 $*"
X		if $running_under_some_shell;
X
Xbeing sure to include any flags that were on the #! line.  A supplied script
Xcalled "nih" will translate perl scripts in place for you:
X
X	nih g/g??
!STUFFY!FUNK!
echo Extracting t/README
sed >t/README <<'!STUFFY!FUNK!' -e 's/X//'
XThis is the perl test library.  To run all the tests, just type 'TEST'.
X
XTo add new tests, just look at the current tests and do likewise.
X
XIf a test fails, run it by itself to see if it prints any informative
Xdiagnostics.  If not, modify the test to print informative diagnostics.
XIf you put out extra lines with a '#' character on the front, you don't
Xhave to worry about removing the extra print statements later since TEST
Xignores lines beginning with '#'.
X
XIf you come up with new tests, send them to lwall@netlabs.com.
!STUFFY!FUNK!
echo Extracting eg/sysvipc/README
sed >eg/sysvipc/README <<'!STUFFY!FUNK!' -e 's/X//'
XFYEnjoyment, here are the test scripts I used while implementing SysV
XIPC in Perl.  Each of them must be run with the parameter "s" for
X"send" or "r" for "receive"; in each case, the receiver is the server
Xand the sender is the client.
X
X-- 
XChip Salzenberg at ComDev/TCT     <chip@tct.uucp>, <uunet!ateng!tct!chip>
X
X
!STUFFY!FUNK!
echo Extracting t/op/study.t
sed >t/op/study.t <<'!STUFFY!FUNK!' -e 's/X//'
X#!./perl
X
X# $Header: study.t,v 4.0 91/03/20 01:54:59 lwall Locked $
X
Xprint "1..24\n";
X
X$x = "abc\ndef\n";
Xstudy($x);
X
Xif ($x =~ /^abc/) {print "ok 1\n";} else {print "not ok 1\n";}
Xif ($x !~ /^def/) {print "ok 2\n";} else {print "not ok 2\n";}
X
X$* = 1;
Xif ($x =~ /^def/) {print "ok 3\n";} else {print "not ok 3\n";}
X$* = 0;
X
X$_ = '123';
Xstudy;
Xif (/^([0-9][0-9]*)/) {print "ok 4\n";} else {print "not ok 4\n";}
X
Xif ($x =~ /^xxx/) {print "not ok 5\n";} else {print "ok 5\n";}
Xif ($x !~ /^abc/) {print "not ok 6\n";} else {print "ok 6\n";}
X
Xif ($x =~ /def/) {print "ok 7\n";} else {print "not ok 7\n";}
Xif ($x !~ /def/) {print "not ok 8\n";} else {print "ok 8\n";}
X
Xstudy($x);
Xif ($x !~ /.def/) {print "ok 9\n";} else {print "not ok 9\n";}
Xif ($x =~ /.def/) {print "not ok 10\n";} else {print "ok 10\n";}
X
Xif ($x =~ /\ndef/) {print "ok 11\n";} else {print "not ok 11\n";}
Xif ($x !~ /\ndef/) {print "not ok 12\n";} else {print "ok 12\n";}
X
X$_ = 'aaabbbccc';
Xstudy;
Xif (/(a*b*)(c*)/ && $1 eq 'aaabbb' && $2 eq 'ccc') {
X	print "ok 13\n";
X} else {
X	print "not ok 13\n";
X}
Xif (/(a+b+c+)/ && $1 eq 'aaabbbccc') {
X	print "ok 14\n";
X} else {
X	print "not ok 14\n";
X}
X
Xif (/a+b?c+/) {print "not ok 15\n";} else {print "ok 15\n";}
X
X$_ = 'aaabccc';
Xstudy;
Xif (/a+b?c+/) {print "ok 16\n";} else {print "not ok 16\n";}
Xif (/a*b+c*/) {print "ok 17\n";} else {print "not ok 17\n";}
X
X$_ = 'aaaccc';
Xstudy;
Xif (/a*b?c*/) {print "ok 18\n";} else {print "not ok 18\n";}
Xif (/a*b+c*/) {print "not ok 19\n";} else {print "ok 19\n";}
X
X$_ = 'abcdef';
Xstudy;
Xif (/bcd|xyz/) {print "ok 20\n";} else {print "not ok 20\n";}
Xif (/xyz|bcd/) {print "ok 21\n";} else {print "not ok 21\n";}
X
Xif (m|bc/*d|) {print "ok 22\n";} else {print "not ok 22\n";}
X
Xif (/^$_$/) {print "ok 23\n";} else {print "not ok 23\n";}
X
X$* = 1;		# test 3 only tested the optimized version--this one is for real
Xif ("ab\ncd\n" =~ /^cd/) {print "ok 24\n";} else {print "not ok 24\n";}
!STUFFY!FUNK!
echo " "
echo "End of kit 1 (of 36)"
cat /dev/null >kit1isdone
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.