[comp.sources.misc] v18i040: perl - The perl programming language, Part22/36

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

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

[There are 36 kits for perl version 4.0.]

#! /bin/sh

# Make a new directory for the perl sources, cd to it, and run kits 1
# thru 36 through sh.  When all 36 kits have been run, read README.

echo "This is perl 4.0 kit 22 (of 36).  If kit 22 is complete, the line"
echo '"'"End of kit 22 (of 36)"'" will echo at the end.'
echo ""
export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
mkdir eg msdos 2>/dev/null
echo Extracting msdos/config.h
sed >msdos/config.h <<'!STUFFY!FUNK!' -e 's/X//'
X#ifndef config_h
X#define config_h
X/* config.h
X *
X * This file is hand tailored for MS-DOS and MSC 5.1 and 6.00A.
X * Tom Dinger, March 1991.
X */
X
X
X/*
X * BUGGY_MSC5:
X *	This symbol is defined if you are the unfortunate owner of the buggy
X *	Microsoft C compiler version 5.1.  It is used as a conditional to
X *	guard code sections that are known to break this compiler.
X * BUGGY_MSC6:
X *	This symbol is defined if you are the unfortunate owner of the buggy
X *	Microsoft C compiler version 6.0A.  It is used as a conditional to
X *	guard code sections that are known to break this compiler.
X */
X#define BUGGY_MSC5			/**/
X/*#undef BUGGY_MSC6			/**/
X
X
X/* EUNICE
X *	This symbol, if defined, indicates that the program is being compiled
X *	under the EUNICE package under VMS.  The program will need to handle
X *	things like files that don't go away the first time you unlink them,
X *	due to version numbering.  It will also need to compensate for lack
X *	of a respectable link() command.
X */
X/* VMS
X *	This symbol, if defined, indicates that the program is running under
X *	VMS.  It is currently only set in conjunction with the EUNICE symbol.
X */
X/*#undef	EUNICE		/**/
X/*#undef	VMS		/**/
X
X/* ALIGNBYTES
X *	This symbol contains the number of bytes required to align a double.
X *	Usual values are 2, 4, and 8.
X */
X#define ALIGNBYTES 4		/**/
X
X/* BIN
X *	This symbol holds the name of the directory in which the user wants
X *	to put publicly executable images for the package in question.  It
X *	is most often a local directory such as /usr/local/bin.
X */
X#define BIN "/usr/local/bin"             /**/
X
X/* BYTEORDER
X *	This symbol contains an encoding of the order of bytes in a long.
X *	Usual values (in octal) are 01234, 04321, 02143, 03412...
X */
X#define BYTEORDER 0x1234		/**/
X
X/* CPPSTDIN
X *	This symbol contains the first part of the string which will invoke
X *	the C preprocessor on the standard input and produce to standard
X *	output.	 Typical value of "cc -E" or "/lib/cpp".
X */
X/* CPPMINUS
X *	This symbol contains the second part of the string which will invoke
X *	the C preprocessor on the standard input and produce to standard
X *	output.  This symbol will have the value "-" if CPPSTDIN needs a minus
X *	to specify standard input, otherwise the value is "".
X */
X/* TODO: doesn't work for MSC -- it's more complicated than this */
X#define CPPSTDIN "cl "
X#define CPPMINUS ""
X
X/* HAS_BCMP
X *	This symbol, if defined, indicates that the bcmp routine is available
X *	to compare blocks of memory.  If undefined, use memcmp.  If that's
X *	not available, roll your own.
X */
X/*#undef	HAS_BCMP		/**/
X
X/* HAS_BCOPY
X *	This symbol, if defined, indicates that the bcopy routine is available
X *	to copy blocks of memory.  Otherwise you should probably use memcpy().
X */
X/*#undef	HAS_BCOPY		/**/
X
X/* HAS_BZERO
X *	This symbol, if defined, indicates that the bzero routine is available
X *	to zero blocks of memory.  Otherwise you should probably use memset()
X *	or roll your own.
X */
X/*#undef	HAS_BZERO		/**/
X
X/* CASTNEGFLOAT
X *	This symbol, if defined, indicates that this C compiler knows how to
X *	cast negative or large floating point numbers to unsigned longs, ints
X *	and shorts.
X */
X/* CASTFLAGS
X *	This symbol contains flags that say what difficulties the compiler
X *	has casting odd floating values to unsigned long:
X *		1 = couldn't cast < 0
X *		2 = couldn't cast >= 0x80000000
X */
X#define	CASTNEGFLOAT	/**/
X#define	CASTFLAGS 0	/**/
X
X/* CHARSPRINTF
X *	This symbol is defined if this system declares "char *sprintf()" in
X *	stdio.h.  The trend seems to be to declare it as "int sprintf()".  It
X *	is up to the package author to declare sprintf correctly based on the
X *	symbol.
X */
X/*#undef	CHARSPRINTF 	/**/
X
X/* HAS_CHSIZE
X *	This symbol, if defined, indicates that the chsize routine is available
X *	to truncate files.  You might need a -lx to get this routine.
X */
X#define	HAS_CHSIZE		/**/
X
X/* HAS_CRYPT
X *	This symbol, if defined, indicates that the crypt routine is available
X *	to encrypt passwords and the like.
X */
X/*#undef	HAS_CRYPT		/**/
X
X/* CSH
X *	This symbol, if defined, indicates that the C-shell exists.
X *	If defined, contains the full pathname of csh.
X */
X/*#undef CSH "/usr/bin/csh"		/**/
X
X/* DOSUID
X *	This symbol, if defined, indicates that the C program should
X *	check the script that it is executing for setuid/setgid bits, and
X *	attempt to emulate setuid/setgid on systems that have disabled
X *	setuid #! scripts because the kernel can't do it securely.
X *	It is up to the package designer to make sure that this emulation
X *	is done securely.  Among other things, it should do an fstat on
X *	the script it just opened to make sure it really is a setuid/setgid
X *	script, it should make sure the arguments passed correspond exactly
X *	to the argument on the #! line, and it should not trust any
X *	subprocesses to which it must pass the filename rather than the
X *	file descriptor of the script to be executed.
X */
X/*#undef DOSUID		/**/
X
X/* HAS_DUP2
X *	This symbol, if defined, indicates that the dup2 routine is available
X *	to dup file descriptors.  Otherwise you should use dup().
X */
X#define	HAS_DUP2		/**/
X
X/* HAS_FCHMOD
X *	This symbol, if defined, indicates that the fchmod routine is available
X *	to change mode of opened files.  If unavailable, use chmod().
X */
X/*#undef	HAS_FCHMOD		/**/
X
X/* HAS_FCHOWN
X *	This symbol, if defined, indicates that the fchown routine is available
X *	to change ownership of opened files.  If unavailable, use chown().
X */
X/*#undef	HAS_FCHOWN		/**/
X
X/* HAS_FCNTL
X *	This symbol, if defined, indicates to the C program that
X *	the fcntl() function exists.
X */
X/*#undef	HAS_FCNTL		/**/
X
X/* FLEXFILENAMES
X *	This symbol, if defined, indicates that the system supports filenames
X *	longer than 14 characters.
X */
X/*#undef	FLEXFILENAMES		/**/
X
X/* HAS_FLOCK
X *	This symbol, if defined, indicates that the flock() routine is
X *	available to do file locking.
X */
X/*#undef	HAS_FLOCK		/**/
X
X/* HAS_GETGROUPS
X *	This symbol, if defined, indicates that the getgroups() routine is
X *	available to get the list of process groups.  If unavailable, multiple
X *	groups are probably not supported.
X */
X/*#undef	HAS_GETGROUPS		/**/
X
X/* HAS_GETHOSTENT
X *	This symbol, if defined, indicates that the gethostent() routine is
X *	available to lookup host names in some data base or other.
X */
X/*#undef	HAS_GETHOSTENT		/**/
X
X/* HAS_GETPGRP
X *	This symbol, if defined, indicates that the getpgrp() routine is
X *	available to get the current process group.
X */
X/*#undef	HAS_GETPGRP		/**/
X
X/* HAS_GETPGRP2
X *	This symbol, if defined, indicates that the getpgrp2() (as in DG/UX)
X *	routine is available to get the current process group.
X */
X/*#undef	HAS_GETPGRP2		/**/
X
X/* HAS_GETPRIORITY
X *	This symbol, if defined, indicates that the getpriority() routine is
X *	available to get a process's priority.
X */
X/*#undef	HAS_GETPRIORITY		/**/
X
X/* HAS_HTONS
X *	This symbol, if defined, indicates that the htons routine (and friends)
X *	are available to do network order byte swapping.
X */
X/* HAS_HTONL
X *	This symbol, if defined, indicates that the htonl routine (and friends)
X *	are available to do network order byte swapping.
X */
X/* HAS_NTOHS
X *	This symbol, if defined, indicates that the ntohs routine (and friends)
X *	are available to do network order byte swapping.
X */
X/* HAS_NTOHL
X *	This symbol, if defined, indicates that the ntohl routine (and friends)
X *	are available to do network order byte swapping.
X */
X/*#undef	HAS_HTONS	/**/
X/*#undef	HAS_HTONL	/**/
X/*#undef	HAS_NTOHS	/**/
X/*#undef	HAS_NTOHL	/**/
X
X/* index
X *	This preprocessor symbol is defined, along with rindex, if the system
X *	uses the strchr and strrchr routines instead.
X */
X/* rindex
X *	This preprocessor symbol is defined, along with index, if the system
X *	uses the strchr and strrchr routines instead.
X */
X#define	index strchr	/* cultural */
X#define	rindex strrchr	/*  differences? */
X
X/* HAS_KILLPG
X *	This symbol, if defined, indicates that the killpg routine is available
X *	to kill process groups.  If unavailable, you probably should use kill
X *	with a negative process number.
X */
X/*#undef	HAS_KILLPG		/**/
X
X/* HAS_LSTAT
X *	This symbol, if defined, indicates that the lstat() routine is
X *	available to stat symbolic links.
X */
X/*#undef	HAS_LSTAT		/**/
X
X/* HAS_MEMCMP
X *	This symbol, if defined, indicates that the memcmp routine is available
X *	to compare blocks of memory.  If undefined, roll your own.
X */
X#define	HAS_MEMCMP		/**/
X
X/* HAS_MEMCPY
X *	This symbol, if defined, indicates that the memcpy routine is available
X *	to copy blocks of memory.  Otherwise you should probably use bcopy().
X *	If neither is defined, roll your own.
X */
X#define	HAS_MEMCPY		/**/
X
X/* HAS_MKDIR
X *	This symbol, if defined, indicates that the mkdir routine is available
X *	to create directories.  Otherwise you should fork off a new process to
X *	exec /bin/mkdir.
X */
X#define	HAS_MKDIR		/**/
X
X/* HAS_MSG
X *	This symbol, if defined, indicates that the entire msg*(2) library is
X *	supported.
X */
X/*#undef	HAS_MSG		/**/
X
X/* HAS_MSGCTL
X *	This symbol, if defined, indicates that the msgctl() routine is
X *	available to stat symbolic links.
X */
X/*#undef	HAS_MSGCTL		/**/
X
X/* HAS_MSGGET
X *	This symbol, if defined, indicates that the msgget() routine is
X *	available to stat symbolic links.
X */
X/*#undef	HAS_MSGGET		/**/
X
X/* HAS_MSGRCV
X *	This symbol, if defined, indicates that the msgrcv() routine is
X *	available to stat symbolic links.
X */
X/*#undef	HAS_MSGRCV		/**/
X
X/* HAS_MSGSND
X *	This symbol, if defined, indicates that the msgsnd() routine is
X *	available to stat symbolic links.
X */
X/*#undef	HAS_MSGSND		/**/
X
X/* HAS_NDBM
X *	This symbol, if defined, indicates that ndbm.h exists and should
X *	be included.
X */
X/*#undef	HAS_NDBM		/**/
X
X/* HAS_ODBM
X *	This symbol, if defined, indicates that dbm.h exists and should
X *	be included.
X */
X/*#undef	HAS_ODBM		/**/
X
X/* HAS_OPEN3
X *	This manifest constant lets the C program know that the three
X *	argument form of open(2) is available.
X */
X#define	HAS_OPEN3		/**/
X
X/* HAS_READDIR
X *	This symbol, if defined, indicates that the readdir routine is available
X *	from the C library to read directories.
X */
X#define	HAS_READDIR		/**/
X
X/* HAS_RENAME
X *	This symbol, if defined, indicates that the rename routine is available
X *	to rename files.  Otherwise you should do the unlink(), link(), unlink()
X *	trick.
X */
X#define	HAS_RENAME		/**/
X
X/* HAS_RMDIR
X *	This symbol, if defined, indicates that the rmdir routine is available
X *	to remove directories.  Otherwise you should fork off a new process to
X *	exec /bin/rmdir.
X */
X#define	HAS_RMDIR		/**/
X
X/* HAS_SELECT
X *	This symbol, if defined, indicates that the select() subroutine
X *	exists.
X */
X/*#undef	HAS_SELECT	/**/
X
X/* HAS_SEM
X *	This symbol, if defined, indicates that the entire sem*(2) library is
X *	supported.
X */
X/*#undef	HAS_SEM		/**/
X
X/* HAS_SEMCTL
X *	This symbol, if defined, indicates that the semctl() routine is
X *	available to stat symbolic links.
X */
X/*#undef	HAS_SEMCTL		/**/
X
X/* HAS_SEMGET
X *	This symbol, if defined, indicates that the semget() routine is
X *	available to stat symbolic links.
X */
X/*#undef	HAS_SEMGET		/**/
X
X/* HAS_SEMOP
X *	This symbol, if defined, indicates that the semop() routine is
X *	available to stat symbolic links.
X */
X/*#undef	HAS_SEMOP		/**/
X
X/* HAS_SETEGID
X *	This symbol, if defined, indicates that the setegid routine is available
X *	to change the effective gid of the current program.
X */
X/*#undef	HAS_SETEGID		/**/
X
X/* HAS_SETEUID
X *	This symbol, if defined, indicates that the seteuid routine is available
X *	to change the effective uid of the current program.
X */
X/*#undef	HAS_SETEUID		/**/
X
X/* HAS_SETPGRP
X *	This symbol, if defined, indicates that the setpgrp() routine is
X *	available to set the current process group.
X */
X/*#undef	HAS_SETPGRP		/**/
X
X/* HAS_SETPGRP2
X *	This symbol, if defined, indicates that the setpgrp2() (as in DG/UX)
X *	routine is available to set the current process group.
X */
X/*#undef	HAS_SETPGRP2		/**/
X
X/* HAS_SETPRIORITY
X *	This symbol, if defined, indicates that the setpriority() routine is
X *	available to set a process's priority.
X */
X/*#undef	HAS_SETPRIORITY		/**/
X
X/* HAS_SETREGID
X *	This symbol, if defined, indicates that the setregid routine is
X *	available to change the real and effective gid of the current program.
X */
X/* HAS_SETRESGID
X *	This symbol, if defined, indicates that the setresgid routine is
X *	available to change the real, effective and saved gid of the current
X *	program.
X */
X/*#undef	HAS_SETREGID		/**/
X/*#undef	HAS_SETRESGID		/**/
X
X/* HAS_SETREUID
X *	This symbol, if defined, indicates that the setreuid routine is
X *	available to change the real and effective uid of the current program.
X */
X/* HAS_SETRESUID
X *	This symbol, if defined, indicates that the setresuid routine is
X *	available to change the real, effective and saved uid of the current
X *	program.
X */
X/*#undef	HAS_SETREUID		/**/
X/*#undef	HAS_SETRESUID		/**/
X
X/* HAS_SETRGID
X *	This symbol, if defined, indicates that the setrgid routine is available
X *	to change the real gid of the current program.
X */
X/*#undef	HAS_SETRGID		/**/
X
X/* HAS_SETRUID
X *	This symbol, if defined, indicates that the setruid routine is available
X *	to change the real uid of the current program.
X */
X/*#undef	HAS_SETRUID		/**/
X
X/* HAS_SHM
X *	This symbol, if defined, indicates that the entire shm*(2) library is
X *	supported.
X */
X/*#undef	HAS_SHM		/**/
X
X/* HAS_SHMAT
X *	This symbol, if defined, indicates that the shmat() routine is
X *	available to stat symbolic links.
X */
X/*#undef	HAS_SHMAT		/**/
X
X/* HAS_SHMCTL
X *	This symbol, if defined, indicates that the shmctl() routine is
X *	available to stat symbolic links.
X */
X/*#undef	HAS_SHMCTL		/**/
X
X/* HAS_SHMDT
X *	This symbol, if defined, indicates that the shmdt() routine is
X *	available to stat symbolic links.
X */
X/*#undef	HAS_SHMDT		/**/
X
X/* HAS_SHMGET
X *	This symbol, if defined, indicates that the shmget() routine is
X *	available to stat symbolic links.
X */
X/*#undef	HAS_SHMGET		/**/
X
X/* HAS_SOCKET
X *	This symbol, if defined, indicates that the BSD socket interface is
X *	supported.
X */
X/* HAS_SOCKETPAIR
X *	This symbol, if defined, indicates that the BSD socketpair call is
X *	supported.
X */
X/* OLDSOCKET
X *	This symbol, if defined, indicates that the 4.1c BSD socket interface
X *	is supported instead of the 4.2/4.3 BSD socket interface.
X */
X/*#undef	HAS_SOCKET		/**/
X
X/*#undef	HAS_SOCKETPAIR	/**/
X
X/*#undef	OLDSOCKET	/**/
X
X/* STATBLOCKS
X *	This symbol is defined if this system has a stat structure declaring
X *	st_blksize and st_blocks.
X */
X/*#undef	STATBLOCKS 	/**/
X
X/* STDSTDIO
X *	This symbol is defined if this system has a FILE structure declaring
X *	_ptr and _cnt in stdio.h.
X *
X *	NOTE: [Tom Dinger, 23 February 1991] You also need the _filbuf()
X *	function, usually referred to by the getc() macro in stdio.h.
X */
X#define	STDSTDIO 	/**/
X
X/* STRUCTCOPY
X *	This symbol, if defined, indicates that this C compiler knows how
X *	to copy structures.  If undefined, you'll need to use a block copy
X *	routine of some sort instead.
X */
X#define	STRUCTCOPY	/**/
X
X/* HAS_STRERROR
X *	This symbol, if defined, indicates that the strerror() routine is
X *	available to translate error numbers to strings.
X */
X#define	HAS_STRERROR		/**/
X
X/* HAS_SYMLINK
X *	This symbol, if defined, indicates that the symlink routine is available
X *	to create symbolic links.
X */
X/*#undef	HAS_SYMLINK		/**/
X
X/* HAS_SYSCALL
X *	This symbol, if defined, indicates that the syscall routine is available
X *	to call arbitrary system calls.  If undefined, that's tough.
X */
X/*#undef	HAS_SYSCALL		/**/
X
X/* HAS_TRUNCATE
X *	This symbol, if defined, indicates that the truncate routine is
X *	available to truncate files.
X */
X/*#undef	HAS_TRUNCATE		/**/
X
X/* HAS_VFORK
X *	This symbol, if defined, indicates that vfork() exists.
X */
X/*#undef	HAS_VFORK	/**/
X
X/* VOIDSIG
X *	This symbol is defined if this system declares "void (*signal())()" in
X *	signal.h.  The old way was to declare it as "int (*signal())()".  It
X *	is up to the package author to declare things correctly based on the
X *	symbol.
X */
X/* TO_SIGNAL
X *	This symbol's value is either "void" or "int", corresponding to the
X *	appropriate return "type" of a signal handler.  Thus, one can declare
X *	a signal handler using "TO_SIGNAL (*handler())()", and define the
X *	handler using "TO_SIGNAL handler(sig)".
X */
X#define	VOIDSIG 	/**/
X#define	TO_SIGNAL	int 	/**/
X
X/* HASVOLATILE
X *	This symbol, if defined, indicates that this C compiler knows about
X *	the volatile declaration.
X */
X/*#undef	HASVOLATILE	/**/
X
X/* HAS_VPRINTF
X *	This symbol, if defined, indicates that the vprintf routine is available
X *	to printf with a pointer to an argument list.  If unavailable, you
X *	may need to write your own, probably in terms of _doprnt().
X */
X/* CHARVSPRINTF
X *	This symbol is defined if this system has vsprintf() returning type
X *	(char*).  The trend seems to be to declare it as "int vsprintf()".  It
X *	is up to the package author to declare vsprintf correctly based on the
X *	symbol.
X */
X#define	HAS_VPRINTF	/**/
X/*#undef	CHARVSPRINTF 	/**/
X
X/* HAS_WAIT4
X *	This symbol, if defined, indicates that wait4() exists.
X */
X/*#undef	HAS_WAIT4	/**/
X
X/* HAS_WAITPID
X *	This symbol, if defined, indicates that waitpid() exists.
X */
X/*#undef	HAS_WAITPID	/**/
X
X/* GIDTYPE
X *	This symbol has a value like gid_t, int, ushort, or whatever type is
X *	used to declare group ids in the kernel.
X */
X#define GIDTYPE int		/**/
X
X/* I_FCNTL
X *	This manifest constant tells the C program to include <fcntl.h>.
X */
X#define	I_FCNTL	/**/
X
X/* I_GRP
X *	This symbol, if defined, indicates to the C program that it should
X *	include grp.h.
X */
X/*#undef	I_GRP		/**/
X
X/* I_NETINET_IN
X *	This symbol, if defined, indicates to the C program that it should
X *	include netinet/in.h.
X */
X/* I_SYS_IN
X *	This symbol, if defined, indicates to the C program that it should
X *	include sys/in.h.
X */
X/*#undef	I_NETINET_IN		/**/
X/*#undef	I_SYS_IN		/**/
X
X/* I_PWD
X *	This symbol, if defined, indicates to the C program that it should
X *	include pwd.h.
X */
X/* PWQUOTA
X *	This symbol, if defined, indicates to the C program that struct passwd
X *	contains pw_quota.
X */
X/* PWAGE
X *	This symbol, if defined, indicates to the C program that struct passwd
X *	contains pw_age.
X */
X/* PWCHANGE
X *	This symbol, if defined, indicates to the C program that struct passwd
X *	contains pw_change.
X */
X/* PWCLASS
X *	This symbol, if defined, indicates to the C program that struct passwd
X *	contains pw_class.
X */
X/* PWEXPIRE
X *	This symbol, if defined, indicates to the C program that struct passwd
X *	contains pw_expire.
X */
X/* PWCOMMENT
X *	This symbol, if defined, indicates to the C program that struct passwd
X *	contains pw_comment.
X */
X/*#undef	I_PWD		/**/
X/*#undef	PWQUOTA		/**/
X/*#undef	PWAGE		/**/
X/*#undef	PWCHANGE	/**/
X/*#undef	PWCLASS		/**/
X/*#undef	PWEXPIRE	/**/
X/*#undef	PWCOMMENT	/**/
X
X/* I_SYS_FILE
X *	This manifest constant tells the C program to include <sys/file.h>.
X */
X/*#undef	I_SYS_FILE	/**/
X
X/* I_SYSIOCTL
X *	This symbol, if defined, indicates that sys/ioctl.h exists and should
X *	be included.
X */
X/*#undef	I_SYSIOCTL		/**/
X
X/* I_TIME
X *	This symbol is defined if the program should include <time.h>.
X */
X/* I_SYS_TIME
X *	This symbol is defined if the program should include <sys/time.h>.
X */
X/* SYSTIMEKERNEL
X *	This symbol is defined if the program should include <sys/time.h>
X *	with KERNEL defined.
X */
X/* I_SYS_SELECT
X *	This symbol is defined if the program should include <sys/select.h>.
X */
X#define	I_TIME	 	/**/
X/*#undef	I_SYS_TIME 	/**/
X/*#undef	SYSTIMEKERNEL 	/**/
X/*#undef	I_SYS_SELECT 	/**/
X
X/* I_UTIME
X *	This symbol, if defined, indicates to the C program that it should
X *	include utime.h.
X */
X/*#undef	I_UTIME		/**/
X
X/* I_VARARGS
X *	This symbol, if defined, indicates to the C program that it should
X *	include varargs.h.
X */
X#define	I_VARARGS		/**/
X
X/* I_VFORK
X *	This symbol, if defined, indicates to the C program that it should
X *	include vfork.h.
X */
X/*#undef	I_VFORK		/**/
X
X/* INTSIZE
X *	This symbol contains the size of an int, so that the C preprocessor
X *	can make decisions based on it.
X */
X#define INTSIZE 2		/**/
X
X/* I_DIRENT
X *	This symbol, if defined, indicates that the program should use the
X *	P1003-style directory routines, and include <dirent.h>.
X */
X/* I_SYS_DIR
X *	This symbol, if defined, indicates that the program should use the
X *	directory functions by including <sys/dir.h>.
X */
X/* I_NDIR
X *	This symbol, if defined, indicates that the program should include the
X *	system's version of ndir.h, rather than the one with this package.
X */
X/* I_SYS_NDIR
X *	This symbol, if defined, indicates that the program should include the
X *	system's version of sys/ndir.h, rather than the one with this package.
X */
X/* I_MY_DIR
X *	This symbol, if defined, indicates that the program should compile
X *	the ndir.c code provided with the package.
X */
X/* DIRNAMLEN
X *	This symbol, if defined, indicates to the C program that the length
X *	of directory entry names is provided by a d_namlen field.  Otherwise
X *	you need to do strlen() on the d_name field.
X */
X/*#undef	I_DIRENT	/**/
X#define	I_SYS_DIR	/**/
X/*#undef	I_NDIR		/**/
X/*#undef	I_SYS_NDIR	/**/
X/*#undef	I_MY_DIR	/**/
X/*#undef	DIRNAMLEN	/**/
X
X
X/* RANDBITS
X *	This symbol contains the number of bits of random number the rand()
X *	function produces.  Usual values are 15, 16, and 31.
X */
X#define RANDBITS 31		/**/
X
X/* SCRIPTDIR
X *	This symbol holds the name of the directory in which the user wants
X *	to put publicly executable scripts for the package in question.  It
X *	is often a directory that is mounted across diverse architectures.
X */
X#define SCRIPTDIR "C:/bin/perl"             /**/
X
X/* SIG_NAME
X *	This symbol contains an list of signal names in order.
X *
X *	Note: This list is specific for Microsoft C 5.1 and 6.0, which only
X *	support SIGINT, SIGFPE, SIGILL, SIGSEGV, and SIGABRT on
X *	DOS 3.x, but in addition defines SIGTERM, SIGBREAK, SIGUSR1,
X *	SIGUSR2, and SIGUSR3.
X */
X#define SIG_NAME \
X "ZERO","HUP","INT","QUIT","ILL","TRAP","IOT","EMT","FPE","KILL",\
X "BUS","SEGV","SYS","PIPE","ALRM","TERM","USR1","USR2","TSTP","CONT",\
X "USR3","BREAK","ABRT"		/**/
X
X/* STDCHAR
X *	This symbol is defined to be the type of char used in stdio.h.
X *	It has the values "unsigned char" or "char".
X */
X#define STDCHAR char	/**/
X
X/* UIDTYPE
X *	This symbol has a value like uid_t, int, ushort, or whatever type is
X *	used to declare user ids in the kernel.
X */
X#define UIDTYPE int		/**/
X
X/* VOIDHAVE
X *	This symbol indicates how much support of the void type is given by this
X *	compiler.  What various bits mean:
X *
X *	    1 = supports declaration of void
X *	    2 = supports arrays of pointers to functions returning void
X *	    4 = supports comparisons between pointers to void functions and
X *		    addresses of void functions
X *
X *	The package designer should define VOIDWANT to indicate the requirements
X *	of the package.  This can be done either by #defining VOIDWANT before
X *	including config.h, or by defining voidwant in Myinit.U.  If the level
X *	of void support necessary is not present, config.h defines void to "int",
X *	VOID to the empty string, and VOIDP to "char *".
X */
X/* void
X *	This symbol is used for void casts.  On implementations which support
X *	void appropriately, its value is "void".  Otherwise, its value maps
X *	to "int".
X */
X/* VOID
X *	This symbol's value is "void" if the implementation supports void
X *	appropriately.  Otherwise, its value is the empty string.  The primary
X *	use of this symbol is in specifying void parameter lists for function
X *	prototypes.
X */
X/* VOIDP
X *	This symbol is used for casting generic pointers.  On implementations
X *	which support void appropriately, its value is "void *".  Otherwise,
X *	its value is "char *".
X */
X#ifndef VOIDWANT
X#define VOIDWANT 1
X#endif
X#define VOIDHAVE 1
X#if (VOIDHAVE & VOIDWANT) != VOIDWANT
X#define void int		/* is void to be avoided? */
X#define VOID
X#define VOIDP (char *)
X#define M_VOID		/* Xenix strikes again */
X#else
X#define VOID void
X#define VOIDP (void *)
X#endif
X
X/* PRIVLIB
X *	This symbol contains the name of the private library for this package.
X *	The library is private in the sense that it needn't be in anyone's
X *	execution path, but it should be accessible by the world.  The program
X *	should be prepared to do ~ expansion.
X */
X#define PRIVLIB "/usr/local/lib/perl"		/**/
X
X/*
X * BINARY:
X *	This symbol is defined if you run under an operating system that
X *	distinguishes between binary and text files.  If so the function
X *	setmode will be used to set the file into binary mode.
X */
X#define BINARY
X
X#define S_ISUID 0
X#define S_ISGID 0
X
X/* For MSC5.1, toke.c "runs out of heap space" unless CRIPPLED_CC is
X * defined.
X */
X#if defined(BUGGY_MSC5) || defined(BUGGY_MSC6)
X#define		CRIPPLED_CC		/**/
X#endif
X
X/* MSC (5.1 and 6.0) doesn't know about S_IFBLK or S_IFIFO -- these are
X * normally found in sys/stat.h
X */
X#define S_IFBLK	(S_IFDIR | S_IFCHR)
X#define	S_IFIFO	0010000
X
X/* Define SUFFIX to get special DOS suffix-replacement code */
X#define SUFFIX				/**/
X
X/* Add this for the DOS-specific chdir() function */
X#define chdir perl_chdir
X
X#endif
!STUFFY!FUNK!
echo Extracting perly.y
sed >perly.y <<'!STUFFY!FUNK!' -e 's/X//'
X/* $Header: perly.y,v 4.0 91/03/20 01:38:40 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:	perly.y,v $
X * Revision 4.0  91/03/20  01:38:40  lwall
X * 4.0 baseline.
X * 
X */
X
X%{
X#include "INTERN.h"
X#include "perl.h"
X
XSTAB *scrstab;
XARG *arg4;	/* rarely used arguments to make_op() */
XARG *arg5;
X
X%}
X
X%start prog
X
X%union {
X    int	ival;
X    char *cval;
X    ARG *arg;
X    CMD *cmdval;
X    struct compcmd compval;
X    STAB *stabval;
X    FCMD *formval;
X}
X
X%token <cval> WORD
X%token <ival> APPEND OPEN SSELECT LOOPEX
X%token <ival> USING FORMAT DO SHIFT PUSH POP LVALFUN
X%token <ival> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE SPLIT FLIST
X%token <ival> FOR FILOP FILOP2 FILOP3 FILOP4 FILOP22 FILOP25
X%token <ival> FUNC0 FUNC1 FUNC2 FUNC2x FUNC3 FUNC4 FUNC5 HSHFUN HSHFUN3
X%token <ival> FLIST2 SUB FILETEST LOCAL DELETE
X%token <ival> RELOP EQOP MULOP ADDOP PACKAGE AMPER
X%token <formval> FORMLIST
X%token <stabval> REG ARYLEN ARY HSH STAR
X%token <arg> SUBST PATTERN
X%token <arg> RSTRING TRANS
X
X%type <ival> prog decl format remember
X%type <cmdval> block lineseq line loop cond sideff nexpr else
X%type <arg> expr sexpr cexpr csexpr term handle aryword hshword
X%type <arg> texpr listop bareword
X%type <cval> label
X%type <compval> compblock
X
X%nonassoc <ival> LISTOP
X%left ','
X%right '='
X%right '?' ':'
X%nonassoc DOTDOT
X%left OROR
X%left ANDAND
X%left '|' '^'
X%left '&'
X%nonassoc EQOP
X%nonassoc RELOP
X%nonassoc <ival> UNIOP
X%nonassoc FILETEST
X%left LS RS
X%left ADDOP
X%left MULOP
X%left MATCH NMATCH 
X%right '!' '~' UMINUS
X%right POW
X%nonassoc INC DEC
X%left '('
X
X%% /* RULES */
X
Xprog	:	/* NULL */
X		{
X#if defined(YYDEBUG) && defined(DEBUGGING)
X		    yydebug = (debug & 1);
X#endif
X		}
X	/*CONTINUED*/	lineseq
X			{ if (in_eval)
X				eval_root = block_head($2);
X			    else
X				main_root = block_head($2); }
X	;
X
Xcompblock:	block CONTINUE block
X			{ $$.comp_true = $1; $$.comp_alt = $3; }
X	|	block else
X			{ $$.comp_true = $1; $$.comp_alt = $2; }
X	;
X
Xelse	:	/* NULL */
X			{ $$ = Nullcmd; }
X	|	ELSE block
X			{ $$ = $2; }
X	|	ELSIF '(' expr ')' compblock
X			{ cmdline = $1;
X			    $$ = make_ccmd(C_ELSIF,$3,$5); }
X	;
X
Xblock	:	'{' remember lineseq '}'
X			{ $$ = block_head($3);
X			  if (savestack->ary_fill > $2)
X			    restorelist($2); }
X	;
X
Xremember:	/* NULL */	/* in case they push a package name */
X			{ $$ = savestack->ary_fill; }
X	;
X
Xlineseq	:	/* NULL */
X			{ $$ = Nullcmd; }
X	|	lineseq line
X			{ $$ = append_line($1,$2); }
X	;
X
Xline	:	decl
X			{ $$ = Nullcmd; }
X	|	label cond
X			{ $$ = add_label($1,$2); }
X	|	loop	/* loops add their own labels */
X	|	label ';'
X			{ if ($1 != Nullch) {
X			      $$ = add_label($1, make_acmd(C_EXPR, Nullstab,
X				  Nullarg, Nullarg) );
X			    }
X			    else {
X			      $$ = Nullcmd;
X			      cmdline = NOLINE;
X			    } }
X	|	label sideff ';'
X			{ $$ = add_label($1,$2); }
X	;
X
Xsideff	:	error
X			{ $$ = Nullcmd; }
X	|	expr
X			{ $$ = make_acmd(C_EXPR, Nullstab, $1, Nullarg); }
X	|	expr IF expr
X			{ $$ = addcond(
X			       make_acmd(C_EXPR, Nullstab, Nullarg, $1), $3); }
X	|	expr UNLESS expr
X			{ $$ = addcond(invert(
X			       make_acmd(C_EXPR, Nullstab, Nullarg, $1)), $3); }
X	|	expr WHILE expr
X			{ $$ = addloop(
X			       make_acmd(C_EXPR, Nullstab, Nullarg, $1), $3); }
X	|	expr UNTIL expr
X			{ $$ = addloop(invert(
X			       make_acmd(C_EXPR, Nullstab, Nullarg, $1)), $3); }
X	;
X
Xcond	:	IF '(' expr ')' compblock
X			{ cmdline = $1;
X			    $$ = make_icmd(C_IF,$3,$5); }
X	|	UNLESS '(' expr ')' compblock
X			{ cmdline = $1;
X			    $$ = invert(make_icmd(C_IF,$3,$5)); }
X	|	IF block compblock
X			{ cmdline = $1;
X			    $$ = make_ccmd(C_IF,cmd_to_arg($2),$3); }
X	|	UNLESS block compblock
X			{ cmdline = $1;
X			    $$ = invert(make_ccmd(C_IF,cmd_to_arg($2),$3)); }
X	;
X
Xloop	:	label WHILE '(' texpr ')' compblock
X			{ cmdline = $2;
X			    $$ = wopt(add_label($1,
X			    make_ccmd(C_WHILE,$4,$6) )); }
X	|	label UNTIL '(' expr ')' compblock
X			{ cmdline = $2;
X			    $$ = wopt(add_label($1,
X			    invert(make_ccmd(C_WHILE,$4,$6)) )); }
X	|	label WHILE block compblock
X			{ cmdline = $2;
X			    $$ = wopt(add_label($1,
X			    make_ccmd(C_WHILE, cmd_to_arg($3),$4) )); }
X	|	label UNTIL block compblock
X			{ cmdline = $2;
X			    $$ = wopt(add_label($1,
X			    invert(make_ccmd(C_WHILE, cmd_to_arg($3),$4)) )); }
X	|	label FOR REG '(' expr ')' compblock
X			{ cmdline = $2;
X			    /*
X			     * The following gobbledygook catches EXPRs that
X			     * aren't explicit array refs and translates
X			     *		foreach VAR (EXPR) {
X			     * into
X			     *		@ary = EXPR;
X			     *		foreach VAR (@ary) {
X			     * where @ary is a hidden array made by genstab().
X			     * (Note that @ary may become a local array if
X			     * it is determined that it might be called
X			     * recursively.  See cmd_tosave().)
X			     */
X			    if ($5->arg_type != O_ARRAY) {
X				scrstab = aadd(genstab());
X				$$ = append_line(
X				    make_acmd(C_EXPR, Nullstab,
X				      l(make_op(O_ASSIGN,2,
X					listish(make_op(O_ARRAY, 1,
X					  stab2arg(A_STAB,scrstab),
X					  Nullarg,Nullarg )),
X					listish(make_list($5)),
X					Nullarg)),
X				      Nullarg),
X				    wopt(over($3,add_label($1,
X				      make_ccmd(C_WHILE,
X					make_op(O_ARRAY, 1,
X					  stab2arg(A_STAB,scrstab),
X					  Nullarg,Nullarg ),
X					$7)))));
X				$$->c_line = $2;
X				$$->c_head->c_line = $2;
X			    }
X			    else {
X				$$ = wopt(over($3,add_label($1,
X				make_ccmd(C_WHILE,$5,$7) )));
X			    }
X			}
X	|	label FOR '(' expr ')' compblock
X			{ cmdline = $2;
X			    if ($4->arg_type != O_ARRAY) {
X				scrstab = aadd(genstab());
X				$$ = append_line(
X				    make_acmd(C_EXPR, Nullstab,
X				      l(make_op(O_ASSIGN,2,
X					listish(make_op(O_ARRAY, 1,
X					  stab2arg(A_STAB,scrstab),
X					  Nullarg,Nullarg )),
X					listish(make_list($4)),
X					Nullarg)),
X				      Nullarg),
X				    wopt(over(defstab,add_label($1,
X				      make_ccmd(C_WHILE,
X					make_op(O_ARRAY, 1,
X					  stab2arg(A_STAB,scrstab),
X					  Nullarg,Nullarg ),
X					$6)))));
X				$$->c_line = $2;
X				$$->c_head->c_line = $2;
X			    }
X			    else {	/* lisp, anyone? */
X				$$ = wopt(over(defstab,add_label($1,
X				make_ccmd(C_WHILE,$4,$6) )));
X			    }
X			}
X	|	label FOR '(' nexpr ';' texpr ';' nexpr ')' block
X			/* basically fake up an initialize-while lineseq */
X			{   yyval.compval.comp_true = $10;
X			    yyval.compval.comp_alt = $8;
X			    cmdline = $2;
X			    $$ = append_line($4,wopt(add_label($1,
X				make_ccmd(C_WHILE,$6,yyval.compval) ))); }
X	|	label compblock	/* a block is a loop that happens once */
X			{ $$ = add_label($1,make_ccmd(C_BLOCK,Nullarg,$2)); }
X	;
X
Xnexpr	:	/* NULL */
X			{ $$ = Nullcmd; }
X	|	sideff
X	;
X
Xtexpr	:	/* NULL means true */
X			{ (void)scanstr("1"); $$ = yylval.arg; }
X	|	expr
X	;
X
Xlabel	:	/* empty */
X			{ $$ = Nullch; }
X	|	WORD ':'
X	;
X
Xdecl	:	format
X			{ $$ = 0; }
X	|	subrout
X			{ $$ = 0; }
X	|	package
X			{ $$ = 0; }
X	;
X
Xformat	:	FORMAT WORD '=' FORMLIST
X			{ if (strEQ($2,"stdout"))
X			    make_form(stabent("STDOUT",TRUE),$4);
X			  else if (strEQ($2,"stderr"))
X			    make_form(stabent("STDERR",TRUE),$4);
X			  else
X			    make_form(stabent($2,TRUE),$4);
X			  Safefree($2); $2 = Nullch; }
X	|	FORMAT '=' FORMLIST
X			{ make_form(stabent("STDOUT",TRUE),$3); }
X	;
X
Xsubrout	:	SUB WORD block
X			{ make_sub($2,$3); }
X	;
X
Xpackage :	PACKAGE WORD ';'
X			{ char tmpbuf[256];
X			  STAB *tmpstab;
X
X			  savehptr(&curstash);
X			  saveitem(curstname);
X			  str_set(curstname,$2);
X			  sprintf(tmpbuf,"'_%s",$2);
X			  tmpstab = stabent(tmpbuf,TRUE);
X			  if (!stab_xhash(tmpstab))
X			      stab_xhash(tmpstab) = hnew(0);
X			  curstash = stab_xhash(tmpstab);
X			  if (!curstash->tbl_name)
X			      curstash->tbl_name = savestr($2);
X			  curstash->tbl_coeffsize = 0;
X			  Safefree($2); $2 = Nullch;
X			  cmdline = NOLINE;
X			}
X	;
X
Xcexpr	:	',' expr
X			{ $$ = $2; }
X	;
X
Xexpr	:	expr ',' sexpr
X			{ $$ = make_op(O_COMMA, 2, $1, $3, Nullarg); }
X	|	sexpr
X	;
X
Xcsexpr	:	',' sexpr
X			{ $$ = $2; }
X	;
X
Xsexpr	:	sexpr '=' sexpr
X			{   $1 = listish($1);
X			    if ($1->arg_type == O_ASSIGN && $1->arg_len == 1)
X				$1->arg_type = O_ITEM;	/* a local() */
X			    if ($1->arg_type == O_LIST)
X				$3 = listish($3);
X			    $$ = l(make_op(O_ASSIGN, 2, $1, $3, Nullarg)); }
X	|	sexpr POW '=' sexpr
X			{ $$ = l(make_op(O_POW, 2, $1, $4, Nullarg)); }
X	|	sexpr MULOP '=' sexpr
X			{ $$ = l(make_op($2, 2, $1, $4, Nullarg)); }
X	|	sexpr ADDOP '=' sexpr
X			{ $$ = rcatmaybe(l(make_op($2, 2, $1, $4, Nullarg)));}
X	|	sexpr LS '=' sexpr
X			{ $$ = l(make_op(O_LEFT_SHIFT, 2, $1, $4, Nullarg)); }
X	|	sexpr RS '=' sexpr
X			{ $$ = l(make_op(O_RIGHT_SHIFT, 2, $1, $4, Nullarg)); }
X	|	sexpr '&' '=' sexpr
X			{ $$ = l(make_op(O_BIT_AND, 2, $1, $4, Nullarg)); }
X	|	sexpr '^' '=' sexpr
X			{ $$ = l(make_op(O_XOR, 2, $1, $4, Nullarg)); }
X	|	sexpr '|' '=' sexpr
X			{ $$ = l(make_op(O_BIT_OR, 2, $1, $4, Nullarg)); }
X
X
X	|	sexpr POW sexpr
X			{ $$ = make_op(O_POW, 2, $1, $3, Nullarg); }
X	|	sexpr MULOP sexpr
X			{ if ($2 == O_REPEAT)
X			      $1 = listish($1);
X			    $$ = make_op($2, 2, $1, $3, Nullarg);
X			    if ($2 == O_REPEAT) {
X				if ($$[1].arg_type != A_EXPR ||
X				  $$[1].arg_ptr.arg_arg->arg_type != O_LIST)
X				    $$[1].arg_flags &= ~AF_ARYOK;
X			    } }
X	|	sexpr ADDOP sexpr
X			{ $$ = make_op($2, 2, $1, $3, Nullarg); }
X	|	sexpr LS sexpr
X			{ $$ = make_op(O_LEFT_SHIFT, 2, $1, $3, Nullarg); }
X	|	sexpr RS sexpr
X			{ $$ = make_op(O_RIGHT_SHIFT, 2, $1, $3, Nullarg); }
X	|	sexpr RELOP sexpr
X			{ $$ = make_op($2, 2, $1, $3, Nullarg); }
X	|	sexpr EQOP sexpr
X			{ $$ = make_op($2, 2, $1, $3, Nullarg); }
X	|	sexpr '&' sexpr
X			{ $$ = make_op(O_BIT_AND, 2, $1, $3, Nullarg); }
X	|	sexpr '^' sexpr
X			{ $$ = make_op(O_XOR, 2, $1, $3, Nullarg); }
X	|	sexpr '|' sexpr
X			{ $$ = make_op(O_BIT_OR, 2, $1, $3, Nullarg); }
X	|	sexpr DOTDOT sexpr
X			{ arg4 = Nullarg;
X			  $$ = make_op(O_F_OR_R, 4, $1, $3, Nullarg); }
X	|	sexpr ANDAND sexpr
X			{ $$ = make_op(O_AND, 2, $1, $3, Nullarg); }
X	|	sexpr OROR sexpr
X			{ $$ = make_op(O_OR, 2, $1, $3, Nullarg); }
X	|	sexpr '?' sexpr ':' sexpr
X			{ $$ = make_op(O_COND_EXPR, 3, $1, $3, $5); }
X	|	sexpr MATCH sexpr
X			{ $$ = mod_match(O_MATCH, $1, $3); }
X	|	sexpr NMATCH sexpr
X			{ $$ = mod_match(O_NMATCH, $1, $3); }
X	|	term
X			{ $$ = $1; }
X	;
X
Xterm	:	'-' term %prec UMINUS
X			{ $$ = make_op(O_NEGATE, 1, $2, Nullarg, Nullarg); }
X	|	'+' term %prec UMINUS
X			{ $$ = $2; }
X	|	'!' term
X			{ $$ = make_op(O_NOT, 1, $2, Nullarg, Nullarg); }
X	|	'~' term
X			{ $$ = make_op(O_COMPLEMENT, 1, $2, Nullarg, Nullarg);}
X	|	term INC
X			{ $$ = addflags(1, AF_POST|AF_UP,
X			    l(make_op(O_ITEM,1,$1,Nullarg,Nullarg))); }
X	|	term DEC
X			{ $$ = addflags(1, AF_POST,
X			    l(make_op(O_ITEM,1,$1,Nullarg,Nullarg))); }
X	|	INC term
X			{ $$ = addflags(1, AF_PRE|AF_UP,
X			    l(make_op(O_ITEM,1,$2,Nullarg,Nullarg))); }
X	|	DEC term
X			{ $$ = addflags(1, AF_PRE,
X			    l(make_op(O_ITEM,1,$2,Nullarg,Nullarg))); }
X	|	FILETEST WORD
X			{ opargs[$1] = 0;	/* force it special */
X			    $$ = make_op($1, 1,
X				stab2arg(A_STAB,stabent($2,TRUE)),
X				Nullarg, Nullarg);
X			}
X	|	FILETEST sexpr
X			{ opargs[$1] = 1;
X			    $$ = make_op($1, 1, $2, Nullarg, Nullarg); }
X	|	FILETEST
X			{ opargs[$1] = ($1 != O_FTTTY);
X			    $$ = make_op($1, 1,
X				stab2arg(A_STAB,
X				  $1 == O_FTTTY?stabent("STDIN",TRUE):defstab),
X				Nullarg, Nullarg); }
X	|	LOCAL '(' expr ')'
X			{ $$ = l(localize(make_op(O_ASSIGN, 1,
X				localize(listish(make_list($3))),
X				Nullarg,Nullarg))); }
X	|	'(' expr ',' ')'
X			{ $$ = make_list($2); }
X	|	'(' expr ')'
X			{ $$ = make_list($2); }
X	|	'(' ')'
X			{ $$ = make_list(Nullarg); }
X	|	DO sexpr	%prec FILETEST
X			{ $$ = make_op(O_DOFILE,2,$2,Nullarg,Nullarg);
X			  allstabs = TRUE;}
X	|	DO block	%prec '('
X			{ $$ = cmd_to_arg($2); }
X	|	REG	%prec '('
X			{ $$ = stab2arg(A_STAB,$1); }
X	|	STAR	%prec '('
X			{ $$ = stab2arg(A_STAR,$1); }
X	|	REG '[' expr ']'	%prec '('
X			{ $$ = make_op(O_AELEM, 2,
X				stab2arg(A_STAB,aadd($1)), $3, Nullarg); }
X	|	HSH 	%prec '('
X			{ $$ = make_op(O_HASH, 1,
X				stab2arg(A_STAB,$1),
X				Nullarg, Nullarg); }
X	|	ARY 	%prec '('
X			{ $$ = make_op(O_ARRAY, 1,
X				stab2arg(A_STAB,$1),
X				Nullarg, Nullarg); }
X	|	REG '{' expr '}'	%prec '('
X			{ $$ = make_op(O_HELEM, 2,
X				stab2arg(A_STAB,hadd($1)),
X				jmaybe($3),
X				Nullarg); }
X	|	'(' expr ')' '[' expr ']'	%prec '('
X			{ $$ = make_op(O_LSLICE, 3,
X				Nullarg,
X				listish(make_list($5)),
X				listish(make_list($2))); }
X	|	'(' ')' '[' expr ']'	%prec '('
X			{ $$ = make_op(O_LSLICE, 3,
X				Nullarg,
X				listish(make_list($4)),
X				Nullarg); }
X	|	ARY '[' expr ']'	%prec '('
X			{ $$ = make_op(O_ASLICE, 2,
X				stab2arg(A_STAB,aadd($1)),
X				listish(make_list($3)),
X				Nullarg); }
X	|	ARY '{' expr '}'	%prec '('
X			{ $$ = make_op(O_HSLICE, 2,
X				stab2arg(A_STAB,hadd($1)),
X				listish(make_list($3)),
X				Nullarg); }
X	|	DELETE REG '{' expr '}'	%prec '('
X			{ $$ = make_op(O_DELETE, 2,
X				stab2arg(A_STAB,hadd($2)),
X				jmaybe($4),
X				Nullarg); }
X	|	ARYLEN	%prec '('
X			{ $$ = stab2arg(A_ARYLEN,$1); }
X	|	RSTRING	%prec '('
X			{ $$ = $1; }
X	|	PATTERN	%prec '('
X			{ $$ = $1; }
X	|	SUBST	%prec '('
X			{ $$ = $1; }
X	|	TRANS	%prec '('
X			{ $$ = $1; }
X	|	DO WORD '(' expr ')'
X			{ $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
X				stab2arg(A_WORD,stabent($2,TRUE)),
X				make_list($4),
X				Nullarg); Safefree($2); $2 = Nullch;
X			    $$->arg_flags |= AF_DEPR; }
X	|	AMPER WORD '(' expr ')'
X			{ $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
X				stab2arg(A_WORD,stabent($2,TRUE)),
X				make_list($4),
X				Nullarg); Safefree($2); $2 = Nullch; }
X	|	DO WORD '(' ')'
X			{ $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
X				stab2arg(A_WORD,stabent($2,TRUE)),
X				make_list(Nullarg),
X				Nullarg);
X			    $$->arg_flags |= AF_DEPR; }
X	|	AMPER WORD '(' ')'
X			{ $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
X				stab2arg(A_WORD,stabent($2,TRUE)),
X				make_list(Nullarg),
X				Nullarg); }
X	|	AMPER WORD
X			{ $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
X				stab2arg(A_WORD,stabent($2,TRUE)),
X				Nullarg,
X				Nullarg); }
X	|	DO REG '(' expr ')'
X			{ $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
X				stab2arg(A_STAB,$2),
X				make_list($4),
X				Nullarg);
X			    $$->arg_flags |= AF_DEPR; }
X	|	AMPER REG '(' expr ')'
X			{ $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
X				stab2arg(A_STAB,$2),
X				make_list($4),
X				Nullarg); }
X	|	DO REG '(' ')'
X			{ $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
X				stab2arg(A_STAB,$2),
X				make_list(Nullarg),
X				Nullarg);
X			    $$->arg_flags |= AF_DEPR; }
X	|	AMPER REG '(' ')'
X			{ $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
X				stab2arg(A_STAB,$2),
X				make_list(Nullarg),
X				Nullarg); }
X	|	AMPER REG
X			{ $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
X				stab2arg(A_STAB,$2),
X				Nullarg,
X				Nullarg); }
X	|	LOOPEX
X			{ $$ = make_op($1,0,Nullarg,Nullarg,Nullarg); }
X	|	LOOPEX WORD
X			{ $$ = make_op($1,1,cval_to_arg($2),
X			    Nullarg,Nullarg); }
X	|	UNIOP
X			{ $$ = make_op($1,0,Nullarg,Nullarg,Nullarg); }
X	|	UNIOP sexpr
X			{ $$ = make_op($1,1,$2,Nullarg,Nullarg); }
X	|	SSELECT
X			{ $$ = make_op(O_SELECT, 0, Nullarg, Nullarg, Nullarg);}
X	|	SSELECT '(' handle ')'
X			{ $$ = make_op(O_SELECT, 1, $3, Nullarg, Nullarg); }
X	|	SSELECT '(' sexpr csexpr csexpr csexpr ')'
X			{ arg4 = $6;
X			  $$ = make_op(O_SSELECT, 4, $3, $4, $5); }
X	|	OPEN WORD	%prec '('
X			{ $$ = make_op(O_OPEN, 2,
X			    stab2arg(A_WORD,stabent($2,TRUE)),
X			    stab2arg(A_STAB,stabent($2,TRUE)),
X			    Nullarg); }
X	|	OPEN '(' WORD ')'
X			{ $$ = make_op(O_OPEN, 2,
X			    stab2arg(A_WORD,stabent($3,TRUE)),
X			    stab2arg(A_STAB,stabent($3,TRUE)),
X			    Nullarg); }
X	|	OPEN '(' handle cexpr ')'
X			{ $$ = make_op(O_OPEN, 2,
X			    $3,
X			    $4, Nullarg); }
X	|	FILOP '(' handle ')'
X			{ $$ = make_op($1, 1,
X			    $3,
X			    Nullarg, Nullarg); }
X	|	FILOP WORD
X			{ $$ = make_op($1, 1,
X			    stab2arg(A_WORD,stabent($2,TRUE)),
X			    Nullarg, Nullarg);
X			  Safefree($2); $2 = Nullch; }
X	|	FILOP REG
X			{ $$ = make_op($1, 1,
X			    stab2arg(A_STAB,$2),
X			    Nullarg, Nullarg); }
X	|	FILOP '(' ')'
X			{ $$ = make_op($1, 1,
X			    stab2arg(A_WORD,Nullstab),
X			    Nullarg, Nullarg); }
X	|	FILOP	%prec '('
X			{ $$ = make_op($1, 0,
X			    Nullarg, Nullarg, Nullarg); }
X	|	FILOP2 '(' handle cexpr ')'
X			{ $$ = make_op($1, 2, $3, $4, Nullarg); }
X	|	FILOP3 '(' handle csexpr cexpr ')'
X			{ $$ = make_op($1, 3, $3, $4, make_list($5)); }
X	|	FILOP22 '(' handle ',' handle ')'
X			{ $$ = make_op($1, 2, $3, $5, Nullarg); }
X	|	FILOP4 '(' handle csexpr csexpr cexpr ')'
X			{ arg4 = $6; $$ = make_op($1, 4, $3, $4, $5); }
X	|	FILOP25 '(' handle ',' handle csexpr csexpr cexpr ')'
X			{ arg4 = $7; arg5 = $8;
X			  $$ = make_op($1, 5, $3, $5, $6); }
X	|	PUSH '(' aryword cexpr ')'
X			{ $$ = make_op($1, 2,
X			    $3,
X			    make_list($4),
X			    Nullarg); }
X	|	POP aryword	%prec '('
X			{ $$ = make_op(O_POP, 1, $2, Nullarg, Nullarg); }
X	|	POP '(' aryword ')'
X			{ $$ = make_op(O_POP, 1, $3, Nullarg, Nullarg); }
X	|	SHIFT aryword	%prec '('
X			{ $$ = make_op(O_SHIFT, 1, $2, Nullarg, Nullarg); }
X	|	SHIFT '(' aryword ')'
X			{ $$ = make_op(O_SHIFT, 1, $3, Nullarg, Nullarg); }
X	|	SHIFT	%prec '('
X			{ $$ = make_op(O_SHIFT, 1,
X			    stab2arg(A_STAB,
X			      aadd(stabent(subline ? "_" : "ARGV", TRUE))),
X			    Nullarg, Nullarg); }
X	|	SPLIT	%prec '('
X			{   static char p[]="/\\s+/";
X			    char *oldend = bufend;
X			    ARG *oldarg = yylval.arg;
X			    
X			    bufend=p+5;
X			    (void)scanpat(p);
X			    bufend=oldend;
X			    $$ = make_split(defstab,yylval.arg,Nullarg);
X			    yylval.arg = oldarg; }
X	|	SPLIT '(' sexpr csexpr csexpr ')'
X			{ $$ = mod_match(O_MATCH, $4,
X			  make_split(defstab,$3,$5));}
X	|	SPLIT '(' sexpr csexpr ')'
X			{ $$ = mod_match(O_MATCH, $4,
X			  make_split(defstab,$3,Nullarg) ); }
X	|	SPLIT '(' sexpr ')'
X			{ $$ = mod_match(O_MATCH,
X			    stab2arg(A_STAB,defstab),
X			    make_split(defstab,$3,Nullarg) ); }
X	|	FLIST2 '(' sexpr cexpr ')'
X			{ $$ = make_op($1, 2,
X			    $3,
X			    listish(make_list($4)),
X			    Nullarg); }
X	|	FLIST '(' expr ')'
X			{ $$ = make_op($1, 1,
X			    make_list($3),
X			    Nullarg,
X			    Nullarg); }
X	|	LVALFUN sexpr	%prec '('
X			{ $$ = l(make_op($1, 1, fixl($1,$2),
X			    Nullarg, Nullarg)); }
X	|	LVALFUN
X			{ $$ = l(make_op($1, 1,
X			    stab2arg(A_STAB,defstab),
X			    Nullarg, Nullarg)); }
X	|	FUNC0
X			{ $$ = make_op($1, 0, Nullarg, Nullarg, Nullarg); }
X	|	FUNC0 '(' ')'
X			{ $$ = make_op($1, 0, Nullarg, Nullarg, Nullarg); }
X	|	FUNC1 '(' ')'
X			{ $$ = make_op($1, 0, Nullarg, Nullarg, Nullarg); }
X	|	FUNC1 '(' expr ')'
X			{ $$ = make_op($1, 1, $3, Nullarg, Nullarg); }
X	|	FUNC2 '(' sexpr cexpr ')'
X			{ $$ = make_op($1, 2, $3, $4, Nullarg);
X			    if ($1 == O_INDEX && $$[2].arg_type == A_SINGLE)
X				fbmcompile($$[2].arg_ptr.arg_str,0); }
X	|	FUNC2x '(' sexpr csexpr ')'
X			{ $$ = make_op($1, 2, $3, $4, Nullarg);
X			    if ($1 == O_INDEX && $$[2].arg_type == A_SINGLE)
X				fbmcompile($$[2].arg_ptr.arg_str,0); }
X	|	FUNC2x '(' sexpr csexpr cexpr ')'
X			{ $$ = make_op($1, 3, $3, $4, $5);
X			    if ($1 == O_INDEX && $$[2].arg_type == A_SINGLE)
X				fbmcompile($$[2].arg_ptr.arg_str,0); }
X	|	FUNC3 '(' sexpr csexpr cexpr ')'
X			{ $$ = make_op($1, 3, $3, $4, $5); }
X	|	FUNC4 '(' sexpr csexpr csexpr cexpr ')'
X			{ arg4 = $6;
X			  $$ = make_op($1, 4, $3, $4, $5); }
X	|	FUNC5 '(' sexpr csexpr csexpr csexpr cexpr ')'
X			{ arg4 = $6; arg5 = $7;
X			  $$ = make_op($1, 5, $3, $4, $5); }
X	|	HSHFUN '(' hshword ')'
X			{ $$ = make_op($1, 1,
X				$3,
X				Nullarg,
X				Nullarg); }
X	|	HSHFUN hshword
X			{ $$ = make_op($1, 1,
X				$2,
X				Nullarg,
X				Nullarg); }
X	|	HSHFUN3 '(' hshword csexpr cexpr ')'
X			{ $$ = make_op($1, 3, $3, $4, $5); }
X	|	bareword
X	|	listop
X	;
X
Xlistop	:	LISTOP
X			{ $$ = make_op($1,2,
X				stab2arg(A_WORD,Nullstab),
X				stab2arg(A_STAB,defstab),
X				Nullarg); }
X	|	LISTOP expr
X			{ $$ = make_op($1,2,
X				stab2arg(A_WORD,Nullstab),
X				maybelistish($1,make_list($2)),
X				Nullarg); }
X	|	LISTOP WORD
X			{ $$ = make_op($1,2,
X				stab2arg(A_WORD,stabent($2,TRUE)),
X				stab2arg(A_STAB,defstab),
X				Nullarg); }
X	|	LISTOP WORD expr
X			{ $$ = make_op($1,2,
X				stab2arg(A_WORD,stabent($2,TRUE)),
X				maybelistish($1,make_list($3)),
X				Nullarg); Safefree($2); $2 = Nullch; }
X	|	LISTOP REG expr
X			{ $$ = make_op($1,2,
X				stab2arg(A_STAB,$2),
X				maybelistish($1,make_list($3)),
X				Nullarg); }
X	;
X
Xhandle	:	WORD
X			{ $$ = stab2arg(A_WORD,stabent($1,TRUE));
X			  Safefree($1); $1 = Nullch;}
X	|	sexpr
X	;
X
Xaryword	:	WORD
X			{ $$ = stab2arg(A_WORD,aadd(stabent($1,TRUE)));
X			    Safefree($1); $1 = Nullch; }
X	|	ARY
X			{ $$ = stab2arg(A_STAB,$1); }
X	;
X
Xhshword	:	WORD
X			{ $$ = stab2arg(A_WORD,hadd(stabent($1,TRUE)));
X			    Safefree($1); $1 = Nullch; }
X	|	HSH
X			{ $$ = stab2arg(A_STAB,$1); }
X	;
X
X/*
X * NOTE:  The following entry must stay at the end of the file so that
X * reduce/reduce conflicts resolve to it only if it's the only option.
X */
X
Xbareword:	WORD
X			{ char *s;
X			    $$ = op_new(1);
X			    $$->arg_type = O_ITEM;
X			    $$[1].arg_type = A_SINGLE;
X			    $$[1].arg_ptr.arg_str = str_make($1,0);
X			    for (s = $1; *s && islower(*s); s++) ;
X			    if (dowarn && !*s)
X				warn(
X				  "\"%s\" may clash with future reserved word",
X				  $1 );
X			}
X
X%% /* PROGRAM */
!STUFFY!FUNK!
echo Extracting eg/findtar
sed >eg/findtar <<'!STUFFY!FUNK!' -e 's/X//'
X#!/usr/bin/perl
X
X# $Header: findtar,v 4.0 91/03/20 01:09:48 lwall Locked $
X
X# findtar takes find-style arguments and spits out a tarfile on stdout.
X# It won't work unless your find supports -ls and your tar the I flag.
X
X$args = join(' ',@ARGV);
Xopen(find,"/usr/bin/find $args -ls |") || die "Can't run find for you.";
X
Xopen(tar,"| /bin/tar cIf - -") || die "Can't run tar for you: $!";
X
Xwhile (<find>) {
X    @x = split(' ');
X    if ($x[2] =~ /^d/) { print tar '-d ';}
X    print tar $x[10],"\n";
X}
!STUFFY!FUNK!
echo " "
echo "End of kit 22 (of 36)"
cat /dev/null >kit22isdone
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.