[comp.os.minix] Bash patches

paradis@acestes.UUCP (Jim Paradis) (03/12/91)

This is the first of four articles containing my patches to make BASH
(Gnu's Bourne-Again Shell) work under MINIX.  I'm only posting patches
because the full sources for BASH are (like most GNU goodies) obscenely
large 8-).  It's available from finer FTP sites everywhere.

Note: These sources were built using bcc on MINIX 1.5.10 with Bruce
Evans' 32-bit patches.  Bash is way too big to run on 16-bit MINIX.
If someone else is perverse enough to try this, be my guest 8-).  Also,
I built this using estdio; you should too.  This is the only environment
I've tested this on... if you have a different environment, lotsa luck! 8-)

These patches are relative to version 1.05 of bash.  You should be sitting
in the main source directory when you execute the patches in this part.

--------------8<---- cut here ----8<---- cut here 8<-----------------------
*** bash-1.05/Makefile	Mon Oct 29 17:36:38 1990
--- minix_bash/Makefile	Sat Mar  9 23:09:14 1991
***************
*** 14,32 ****
  MAKE = make
  #CPP_DEFINES = -DHAVE_GCC -DHAVE_FIXED_INCLUDES -DHAVE_BISON
  
  CPP = /lib/cpp $(CPPFLAGS)
  #CPP = $(CC) -E
  
  CPPFLAGS = -P $(SYSTEM) $(CPP_DEFINES) -DM_DESTDIR=$(DESTDIR)
! CPP_ARGS = -DCPP_CC=$(CC) `./makeargs.sh`
  
  all:	bash-Makefile
  	$(MAKE) -f bash-Makefile
  
  bash-Makefile: cpp-Makefile Makefile machines.h makeargs.sh
  	cp cpp-Makefile tmp-Makefile.c
! 	@echo $(CPP) $(CPP_ARGS) tmp-Makefile.c \| cat -s >bash-Makefile
! 	@$(CPP) $(CPP_ARGS) tmp-Makefile.c | cat -s >bash-Makefile
  	rm -f tmp-Makefile.c
  
  # Subsequent lines contain targets that are correctly handled by an
--- 14,34 ----
  MAKE = make
  #CPP_DEFINES = -DHAVE_GCC -DHAVE_FIXED_INCLUDES -DHAVE_BISON
  
+ CC = bcc
+ 
  CPP = /lib/cpp $(CPPFLAGS)
  #CPP = $(CC) -E
  
  CPPFLAGS = -P $(SYSTEM) $(CPP_DEFINES) -DM_DESTDIR=$(DESTDIR)
! CPP_ARGS = -DMINIX -DCPP_CC=$(CC) `./makeargs.sh`
  
  all:	bash-Makefile
  	$(MAKE) -f bash-Makefile
  
  bash-Makefile: cpp-Makefile Makefile machines.h makeargs.sh
  	cp cpp-Makefile tmp-Makefile.c
! 	echo $(CPP) $(CPP_ARGS) tmp-Makefile.c \| cat >bash-Makefile
! 	$(CPP) $(CPP_ARGS) tmp-Makefile.c | cat >bash-Makefile
  	rm -f tmp-Makefile.c
  
  # Subsequent lines contain targets that are correctly handled by an

*** bash-1.05/builtins.c	Mon Oct 29 17:36:40 1990
--- minix_bash/builtins.c	Thu Nov  1 23:30:44 1990
***************
*** 19,36 ****
  Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  
  #include <stdio.h>
! #include <sys/param.h>
  
  #include <sys/types.h>
  #include <sys/stat.h>
! #include <sys/file.h>
  #include <errno.h>
  #include "shell.h"
  
  #ifndef SYSV
! #include <sys/time.h>
! #include <sys/resource.h>
! #endif
  
  #include "builtins.h"
  #include "trap.h"
--- 19,42 ----
  Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  
  #include <stdio.h>
! #ifndef MINIX
! #include <sys/param.h>
! #endif /* MINIX */
  
  #include <sys/types.h>
  #include <sys/stat.h>
! #ifndef MINIX
! #include <sys/file.h>
! #endif /* MINIX */
  #include <errno.h>
  #include "shell.h"
  
  #ifndef SYSV
! #ifndef MINIX
! #include <sys/time.h>
! #include <sys/resource.h>
! #endif /* MINIX */
! #endif /* SYSV */
  
  #include "builtins.h"
  #include "trap.h"
***************
*** 41,46 ****
--- 47,56 ----
  #include "jobs.h"
  #endif
  
+ #ifdef MINIX
+ #define	killpg(pg, sig)	kill(-(pg), (sig))
+ #endif /* MINIX */
+ 
  extern int errno;		/* Not always in <errno.h>.  Bogusness. */
  
  #ifndef sigmask
***************
*** 52,57 ****
--- 62,72 ----
  #include <sys/times.h>
  #endif
  
+ #ifdef MINIX
+ #include <fcntl.h>
+ #include <sys/times.h>
+ #endif /* MINIX */
+ 
  #if defined (HAVE_VPRINTF)
  #include <varargs.h>
  #endif
***************
*** 2190,2196 ****
     information comes from variables in jobs.c used to keep
     track of this stuff. */
  
! #if !defined (SYSV)
  static long
  scale60 (tvalp)
       struct timeval *tvalp;
--- 2205,2211 ----
     information comes from variables in jobs.c used to keep
     track of this stuff. */
  
! #if !defined(SYSV) && !defined(MINIX)
  static long
  scale60 (tvalp)
       struct timeval *tvalp;
***************
*** 2204,2210 ****
  {
    int system_minutes_used, user_minutes_used;
    long system_seconds_used, user_seconds_used;
! #ifndef SYSV
    struct rusage self, kids;
  
    no_args (list);
--- 2219,2225 ----
  {
    int system_minutes_used, user_minutes_used;
    long system_seconds_used, user_seconds_used;
! #if !defined(SYSV) && !defined(MINIX)
    struct rusage self, kids;
  
    no_args (list);

*** bash-1.05/config.h	Sun Feb 25 09:19:30 1990
--- minix_bash/config.h	Thu Nov  1 21:29:54 1990
***************
*** 39,44 ****
--- 39,49 ----
  #undef JOB_CONTROL
  #endif /* SYSV */
  
+ /* Neither does MINIX! */
+ #ifdef MINIX
+ #undef JOB_CONTROL
+ #endif /* MINIX */
+ 
  /* Define ALIAS if you want the alias features. */
  #define ALIAS
  
*** bash-1.05/cpp-Makefile	Mon Oct 29 17:36:42 1990
--- minix_bash/cpp-Makefile	Sat Mar  9 23:31:17 1991
***************
*** 50,56 ****
  BISON = bison -y
  #else
  BISON = yacc
! #endif
  
  /* If the person blithely typed "make CC=gcc", then make that work. */
  #if defined (__GNUC__) && !defined (HAVE_GCC)
--- 50,56 ----
  BISON = bison -y
  #else
  BISON = yacc
! #endif /* HAVE_BISON */
  
  /* If the person blithely typed "make CC=gcc", then make that work. */
  #if defined (__GNUC__) && !defined (HAVE_GCC)
***************
*** 174,186 ****
  
  /**/# Support libraries required.  Termcap and Readline.
  /**/# We would like to use the GNU termcap library.
  #if defined (USE_GNU_TERMCAP)
  #define TERMSRC_DEP
  TERMCAP = $(TLIBSRC)/libtermcap.a
  TERMLIB = -L$(TLIBSRC) -ltermcap
  #else
  TERMLIB = -ltermcap
! #endif
  
  READLINE= ./readline/libreadline.a
  
--- 174,190 ----
  
  /**/# Support libraries required.  Termcap and Readline.
  /**/# We would like to use the GNU termcap library.
+ #if defined (MINIX)
+ TERMLIB = 
+ #else /* !MINIX */
  #if defined (USE_GNU_TERMCAP)
  #define TERMSRC_DEP
  TERMCAP = $(TLIBSRC)/libtermcap.a
  TERMLIB = -L$(TLIBSRC) -ltermcap
  #else
  TERMLIB = -ltermcap
! #endif /* USE_GNU_TERMCAP */
! #endif /* MINIX */
  
  READLINE= ./readline/libreadline.a
  
***************
*** 222,228 ****
  LIBDEP = $(READLINE)
  #endif
  
! CSOURCES = shell.c parse.y general.c make_cmd.c print_cmd.c\
  	   dispose_cmd.c execute_cmd.c variables.c builtins.c\
  	   copy_cmd.c flags.c subst.c glob.c hash.c mailcheck.c\
  	   test.c trap.c jobs.c nojobs.c $(ALLOC_FILES) braces.c\
--- 226,232 ----
  LIBDEP = $(READLINE)
  #endif
  
! CSOURCES = shell.c y.tab.c general.c make_cmd.c print_cmd.c\
  	   dispose_cmd.c execute_cmd.c variables.c builtins.c\
  	   copy_cmd.c flags.c subst.c glob.c hash.c mailcheck.c\
  	   test.c trap.c jobs.c nojobs.c $(ALLOC_FILES) braces.c\
***************
*** 265,274 ****
  $(PROGRAM):	.build $(OBJECTS) $(LIBDEP) bash-Makefile
  	$(CC) $(LDFLAGS) -o $(PROGRAM) $(OBJECTS) \
  		$(LIBRARIES) $(LOCAL_LIBS) $(TERMLIB)
! 	$(RM) -f .make
! 
! .build:		.make newversion.aux
! 	if ./newversion.aux -build; then mv -f newversion.h version.h; fi
  
  .make:
  	@echo
--- 269,286 ----
  $(PROGRAM):	.build $(OBJECTS) $(LIBDEP) bash-Makefile
  	$(CC) $(LDFLAGS) -o $(PROGRAM) $(OBJECTS) \
  		$(LIBRARIES) $(LOCAL_LIBS) $(TERMLIB)
! #ifdef MINIX
! 	chmem +256000 $(PROGRAM)
! #endif /* MINIX */
! 	$(RM) -f .make
! 
! #ifdef MINIX
! .build:		.make newversion.aux
! 	if ./newversion.aux -build; then mv newversion.h version.h; fi
! #else /* !MINIX */
! .build:		.make newversion.aux
! 	if ./newversion.aux -build; then mv -f newversion.h version.h; fi
! #endif /* MINIX */
  
  .make:
  	@echo
***************
*** 286,297 ****
  
  shell.h:	general.h variables.h config.h
  		touch shell.h
! 
  y.tab.c:	parse.y shell.h
  		-if test -f y.tab.h; then mv -f y.tab.h old-y.tab.h; fi
  		$(BISON) -d parse.y
  		-if cmp -s old-y.tab.h y.tab.h; then mv old-y.tab.h y.tab.h; fi
! 
  $(READLINE):	$(READLINE_SOURCE)
  		(cd $(RLIBSRC); $(MAKE) $(MFLAGS) CC='$(CC)' CFLAGS='$(CFLAGS)')
  
--- 298,309 ----
  
  shell.h:	general.h variables.h config.h
  		touch shell.h
! #ifndef MINIX
  y.tab.c:	parse.y shell.h
  		-if test -f y.tab.h; then mv -f y.tab.h old-y.tab.h; fi
  		$(BISON) -d parse.y
  		-if cmp -s old-y.tab.h y.tab.h; then mv old-y.tab.h y.tab.h; fi
! #endif /* MINIX */
  $(READLINE):	$(READLINE_SOURCE)
  		(cd $(RLIBSRC); $(MAKE) $(MFLAGS) CC='$(CC)' CFLAGS='$(CFLAGS)')
  
***************
*** 321,328 ****
  #if !defined (HAVE_ALLOCA)
  #if !defined (__GNUC__)
  $(ALLOCA):	$(ALLOCA_SOURCE)
! 		$(CC) -I$(ALLOC_DIR) $(CFLAGS) -c $(ALLOCA_SOURCE)
! 		@-mv `basename $*`.o $(ALLOCA) 2>&1 >/dev/null
  #else /* GCC */
  $(ALLOCA):	$(ALLOCA_SOURCE)
  		$(CC) -I$(ALLOC_DIR) $(CFLAGS) -o $(ALLOCA) -c $(ALLOCA_SOURCE)
--- 333,344 ----
  #if !defined (HAVE_ALLOCA)
  #if !defined (__GNUC__)
  $(ALLOCA):	$(ALLOCA_SOURCE)
! #ifdef MINIX
! 		$(CC) -I$(ALLOC_DIR) $(CFLAGS) -c $(ALLOCA_SOURCE) -o $(ALLOCA)
! #else /* !MINIX */
! 		$(CC) -I$(ALLOC_DIR) $(CFLAGS) -c $(ALLOCA_SOURCE)
! 		@-mv `basename $*`.o $(ALLOCA) 2>&1 >/dev/null
! #endif /* MINIX */
  #else /* GCC */
  $(ALLOCA):	$(ALLOCA_SOURCE)
  		$(CC) -I$(ALLOC_DIR) $(CFLAGS) -o $(ALLOCA) -c $(ALLOCA_SOURCE)
***************
*** 409,416 ****
  		@echo cp $(PROGRAM).tar.Z $(PROGRAM)-`cat .distribution`.tar.Z
  		@cp $(PROGRAM).tar.Z $(PROGRAM)-`cat .distribution`.tar.Z
  
! newversion.aux:	newversion.c
! 		$(CC) -g -o newversion.aux newversion.c -lm
  
  newversion:	newversion.aux
  		rm -f .build
--- 425,437 ----
  		@echo cp $(PROGRAM).tar.Z $(PROGRAM)-`cat .distribution`.tar.Z
  		@cp $(PROGRAM).tar.Z $(PROGRAM)-`cat .distribution`.tar.Z
  
! #ifdef MINIX
! newversion.aux:	newversion.c
! 		$(CC) -o newversion.aux newversion.c
! #else /* !MINIX */
! newversion.aux:	newversion.c
! 		$(CC) -g -o newversion.aux newversion.c -lm
! #endif /* MINIX */
  
  newversion:	newversion.aux
  		rm -f .build
***************
*** 425,434 ****
  		etags $(SOURCES) $(LIBRARY_SOURCE)
  
  clean:
! 		$(RM) $(OBJECTS) $(PROGRAM) y.tab.c y.tab.h newversion.aux
  		$(RM) .make bash-Makefile
  		(cd $(RLIBSRC); $(RM) *.o *.a)
  
  dist-clean:
! 	$(RM) $(OBJECTS) $(PROGRAM) y.tab.c newversion.aux
! 	$(RM) -rf uuencoded
--- 446,463 ----
  		etags $(SOURCES) $(LIBRARY_SOURCE)
  
  clean:
! #ifdef MINIX
! 		$(RM) $(OBJECTS) $(PROGRAM) newversion.aux
! #else /* ! MINIX */
! 		$(RM) $(OBJECTS) $(PROGRAM) y.tab.c y.tab.h newversion.aux
! #endif /* MINIX */
  		$(RM) .make bash-Makefile
  		(cd $(RLIBSRC); $(RM) *.o *.a)
  
  dist-clean:
! #ifdef MINIX
! 	$(RM) $(OBJECTS) $(PROGRAM) newversion.aux
! #else /* ! MINIX */
! 	$(RM) $(OBJECTS) $(PROGRAM) y.tab.c newversion.aux
! #endif /* MINIX */
! 	$(RM) -rf uuencoded

*** bash-1.05/execute_cmd.c	Mon Oct 29 17:36:42 1990
--- minix_bash/execute_cmd.c	Thu Nov  1 23:28:00 1990
***************
*** 23,29 ****
  #ifndef SONY
  #include <fcntl.h>
  #endif
! #include <sys/file.h>
  #include <sys/stat.h>
  #include <signal.h>
  
--- 23,34 ----
  #ifndef SONY
  #include <fcntl.h>
  #endif
! #ifdef MINIX
! #include <limits.h>
! #define NOFILE OPEN_MAX
! #else
! #include <sys/file.h>
! #endif /* MINIX */
  #include <sys/stat.h>
  #include <signal.h>
  
***************
*** 31,37 ****
  #define SIGABRT SIGIOT
  #endif
  
! #include <sys/param.h>
  #include <errno.h>
  
  #include "shell.h"
--- 36,46 ----
  #define SIGABRT SIGIOT
  #endif
  
! #ifdef MINIX
! #include <sys/types.h>
! #else
! #include <sys/param.h>
! #endif /* MINIX */
  #include <errno.h>
  
  #include "shell.h"
***************
*** 1391,1397 ****
  group_member (gid)
       int gid;
  {
! #ifdef SYSV
    return ((gid == getgid ()) || (gid == geteuid ()));
  #else
  
--- 1400,1406 ----
  group_member (gid)
       int gid;
  {
! #if defined(SYSV) || defined(MINIX)
    return ((gid == getgid ()) || (gid == geteuid ()));
  #else
  
*** bash-1.05/general.c	Mon Oct 29 17:36:42 1990
--- minix_bash/general.c	Thu Nov  1 23:27:16 1990
***************
*** 25,31 ****
  #ifdef SYSV
  #include <string.h>
  #else
! #include <strings.h>
  #endif  /* SYSV */
  
  #ifndef NULL
--- 25,35 ----
  #ifdef SYSV
  #include <string.h>
  #else
! #ifdef MINIX
! #include <string.h>
! #else
! #include <strings.h>
! #endif /* MINIX */
  #endif  /* SYSV */
  
  #ifndef NULL
***************
*** 456,461 ****
--- 460,508 ----
  }
  #endif /* NO_DUP */
  
+ #ifdef MINIX
+ /* Functions needed for MINIX... */
+ 
+ char 
+ *getwd(s) 
+ char *s; 
+ { 
+ 	getcwd(s,MAXPATHLEN); 
+ 	return s; 
+ }
+ 
+ gethostname(name, namelen)
+ 	char *name;
+ 	int namelen;
+ {
+ 	FILE *	f;
+ 	char	linebuf[80];
+ 	int	i;
+ 
+ 	f = fopen("/etc/uucpname","r");
+ 	if(f == (FILE *)NULL) {
+ 		return(-1);
+ 	}
+ 
+ 	if(fgets(linebuf, 80, f) == NULL) {
+ 		return(-1);
+ 	}
+ 
+ 	for(i = 0; i < sizeof(linebuf); i++) {
+ 		if(linebuf[i] == '\n') {
+ 			linebuf[i] = '\0';
+ 			break;
+ 		}
+ 	}
+ 
+ 	if(strlen(linebuf) > namelen) {
+ 		return(-1);
+ 	}
+ 	strcpy(name, linebuf);
+ 	return(0);
+ }
+ 
+ #endif /* MINIX */
  #ifdef SYSV
  #include <sys/utsname.h>
  bcopy(s,d,n) char *d,*s; { while(n--) *d++ = *s++; }

*** bash-1.05/glob.c	Mon Oct 29 17:36:44 1990
--- minix_bash/glob.c	Thu Nov  1 22:12:36 1990
***************
*** 27,33 ****
  
  #include <sys/types.h>
  
! #if defined (SYSVr3) || defined (DIRENT)
  #  include <dirent.h>
  #  define direct dirent
  #  define	D_NAMLEN(d) strlen((d)->d_name)
--- 27,33 ----
  
  #include <sys/types.h>
  
! #if defined (SYSVr3) || defined (DIRENT) || defined(MINIX)
  #  include <dirent.h>
  #  define direct dirent
  #  define	D_NAMLEN(d) strlen((d)->d_name)
***************
*** 54,60 ****
  #define rindex	strrchr
  
  #else /* not SYSV */
! #include <strings.h>
  
  extern void bcopy ();
  #endif /* not SYSV */
--- 54,64 ----
  #define rindex	strrchr
  
  #else /* not SYSV */
! #ifdef MINIX
! #include <string.h>
! #else
! #include <strings.h>
! #endif /* MINIX */
  
  extern void bcopy ();
  #endif /* not SYSV */

*** bash-1.05/jobs.h	Fri Jan  5 13:27:38 1990
--- minix_bash/jobs.h	Thu Nov  1 21:54:24 1990
***************
*** 94,100 ****
  typedef struct process {
    struct process *next;	/* Next process in the pipeline.  A circular chain. */
    int pid;		/* Process ID. */
!   union wait status;	/* The status of this command as returned by wait. */
    int running;		/* Non-zero if this process is running. */
    char *command;	/* The particular program that is running. */
  } PROCESS;
--- 94,104 ----
  typedef struct process {
    struct process *next;	/* Next process in the pipeline.  A circular chain. */
    int pid;		/* Process ID. */
! #ifdef MINIX
!   int status;
! #else
!   union wait status;	/* The status of this command as returned by wait. */
! #endif /* MINIX */
    int running;		/* Non-zero if this process is running. */
    char *command;	/* The particular program that is running. */
  } PROCESS;

*** bash-1.05/machines.h	Mon Oct 29 17:36:46 1990
--- minix_bash/machines.h	Sat Mar  9 23:12:38 1991
***************
*** 376,381 ****
--- 376,397 ----
  #define HAVE_SETLINEBUF
  #endif  /* clipper */
  
+ /* **************************************** */
+ /*					    */
+ /*			MINIX               */
+ /*	        			    */
+ /* **************************************** */
+ /* This is for MINIX 1.5 with Bruce Evans' 386 patches.
+  * it has not been tested on any other MINIX configuration.
+  */
+ #if defined(MINIX)
+ 
+ #define M_MACHINE "PC_386"
+ #define M_OS Minix
+ #define SYSDEP_CFLAGS -DMINIX -D_MINIX -D_POSIX_SOURCE
+ 
+ #endif /* MINIX */
+ 
  /* **************************************************************** */
  /*								    */
  /*			Generic Entry   			    */

*** bash-1.05/mailcheck.c	Sat Jan 20 12:57:46 1990
--- minix_bash/mailcheck.c	Thu Nov  1 22:13:32 1990
***************
*** 21,27 ****
  #include <stdio.h>
  #include <sys/types.h>
  #include <sys/stat.h>
! #include <sys/param.h>
  #include "shell.h"
  
  #ifndef MAXPATHLEN
--- 21,29 ----
  #include <stdio.h>
  #include <sys/types.h>
  #include <sys/stat.h>
! #ifndef MINIX
! #include <sys/param.h>
! #endif /* MINIX */
  #include "shell.h"
  
  #ifndef MAXPATHLEN

*** bash-1.05/make_cmd.c	Mon Oct 29 17:36:46 1990
--- minix_bash/make_cmd.c	Thu Nov  1 21:28:02 1990
***************
*** 24,30 ****
  #ifndef SONY
  #include <fcntl.h>
  #endif
! #include <sys/file.h>
  
  #if defined (HAVE_VPRINTF)
  #include <varargs.h>
--- 24,32 ----
  #ifndef SONY
  #include <fcntl.h>
  #endif
! #ifndef MINIX
! #include <sys/file.h>
! #endif /* MINIX */
  
  #if defined (HAVE_VPRINTF)
  #include <varargs.h>
***************
*** 210,217 ****
  /* Return a command which is the connection of the word or redirection
     in ELEMENT, and the command * or NULL in COMMAND. */
  COMMAND *
! make_simple_command (element, command)
!      ELEMENT element;
       COMMAND *command;
  {
    /* If we are starting from scratch, then make the initial command
--- 212,219 ----
  /* Return a command which is the connection of the word or redirection
     in ELEMENT, and the command * or NULL in COMMAND. */
  COMMAND *
! make_simple_command (elementp, command)
!      ELEMENT *elementp;
       COMMAND *command;
  {
    /* If we are starting from scratch, then make the initial command
***************
*** 228,244 ****
        command->subshell = 0;
        command->value.Simple = temp;
      }
!   if (element.word)
!     {
!       WORD_LIST *tw = (WORD_LIST *)xmalloc (sizeof (WORD_LIST));
!       tw->word = element.word;
        tw->next = command->value.Simple->words;
        command->value.Simple->words = tw;
      }
    else
      {
!       element.redirect->next = command->value.Simple->redirects;
!       command->value.Simple->redirects = element.redirect;
      }
    return (command);
  }
--- 230,246 ----
        command->subshell = 0;
        command->value.Simple = temp;
      }
!   if (elementp->word)
!     {
!       WORD_LIST *tw = (WORD_LIST *)xmalloc (sizeof (WORD_LIST));
!       tw->word = elementp->word;
        tw->next = command->value.Simple->words;
        command->value.Simple->words = tw;
      }
    else
      {
!       elementp->redirect->next = command->value.Simple->redirects;
!       command->value.Simple->redirects = elementp->redirect;
      }
    return (command);
  }

*** bash-1.05/makeargs.sh	Mon Oct 29 17:36:46 1990
--- minix_bash/makeargs.sh	Thu Nov  1 16:14:24 1990
***************
*** 1,37 ****
! #!/bin/sh
! #
! # This file outputs a string of text which are CPP defines helping to
! # describe the operating system version.  We just take guesses by
! # looking at random files.
! 
! # Test for shared libraries (this is pretty Sunish).
! if test -f /lib/ld.so; then SHLIB=-DHAVE_SHARED_LIBS; fi
! 
! # Get name of maintainer.
! if test -f /usr/ucb/whoami; then
!   WHOAMI=`whoami`@`hostname`;
! else
!   WHOAMI=`who am i | awk '{ print $1; }'`
! fi
! 
! if [ "$WHOAMI" = "" ]; then 
!   WHOAMI=`id | sed 's/uid=[01-9]*(//' | sed 's/) [) A-Za-z01-9(=,]*//'`
!   if test -f /bin/hostname; then
!     WHOAMI=$WHOAMI@`/bin/hostname`
!   elif test -f /usr/bin/uuname; then
!     WHOAMI=`uuname`!$WHOAMI
!   fi
! fi
! 
! #
! # Is this a Xenix system?
! #
! if [ -f /xenix ]; then
!   SYSDEF="-DXenix"
!  case "`uname -p`" in
!   *286) SYSDEF="-DXenix286" ;;
!   *386) SYSDEF="-DXenix386" ;;
!  esac
! fi
! 
! echo "-DCPP_MAINTAINER=${WHOAMI} ${SHLIB} ${SYSDEF}"
--- 1 ----
! echo "-DCPP_MAINTAINER=root"

*** bash-1.05/newversion.c	Wed Jan  3 14:50:28 1990
--- minix_bash/newversion.c	Thu Nov  1 16:25:48 1990
***************
*** 28,34 ****
       char **argv;
  {
    FILE *file, *must_open ();
!   float distver = 0.0;
    int dist = 0, build = 0, buildver = 0;
    int dist_inc = 0, build_inc = 0;
    int dot_dist_needs_making = 0, dot_build_needs_making = 0;
--- 28,35 ----
       char **argv;
  {
    FILE *file, *must_open ();
!   int	distver_major = 0;
!   int	distver_minor = 0;
    int dist = 0, build = 0, buildver = 0;
    int dist_inc = 0, build_inc = 0;
    int dot_dist_needs_making = 0, dot_build_needs_making = 0;
***************
*** 51,57 ****
        arg_index++;
      }
  
!   if (!get_float_from_file (".distribution", &distver))
      dot_dist_needs_making++;
  
    if (!dist)
--- 52,58 ----
        arg_index++;
      }
  
!   if (!get_float_from_file (".distribution", &distver_major, &distver_minor))
      dot_dist_needs_making++;
  
    if (!dist)
***************
*** 62,69 ****
    else
      dist_inc++;
  
!   if (dist && arg_index < argc)
!     if (1 != sscanf (argv[arg_index], "%f", &distver))
        {
  	fprintf (stderr, "Bad input `%s'.  Expected float value for -dist.\n",
  		 argv[arg_index]);
--- 63,72 ----
    else
      dist_inc++;
  
!   if (dist && arg_index < argc) {
!     distver_major = distver_minor = 0;
!     if (2 != sscanf (argv[arg_index], "%d.%d", 
! 				&distver_major, &distver_minor))
        {
  	fprintf (stderr, "Bad input `%s'.  Expected float value for -dist.\n",
  		 argv[arg_index]);
***************
*** 74,79 ****
--- 77,83 ----
  	arg_index++;
  	dist_inc = 0;
        }
+   }
  
    if (build && arg_index < argc)
      if (1 != sscanf (argv[arg_index], "%d", &buildver))
***************
*** 88,94 ****
  	build_inc = 0;
        }
  
!   if (dot_dist_needs_making && !distver)
      {
        fprintf (stderr, "There is no `.distribution' file for me to infer from.\n");
        exit (1);
--- 92,98 ----
  	build_inc = 0;
        }
  
!   if (dot_dist_needs_making && !distver_major && !distver_minor)
      {
        fprintf (stderr, "There is no `.distribution' file for me to infer from.\n");
        exit (1);
***************
*** 97,112 ****
    if (build)
      buildver = buildver + 1;
    
!   if (dist_inc)
!     distver = distver + 0.01;
! 
!   file = must_open ("newversion.h", "w");
!   fprintf (file, "%s%.2f%s%d\n","\
  /* Version control for the shell.  This file gets changed when you say\n\
     `make newversion' to the Makefile.  It is created by newversion.aux. */\n\
  \n\
  /* The distribution version number of this shell. */\n\
! #define DISTVERSION \"", distver, "\"\n\n/* The last built version of this shell. */\n\
  #define BUILDVERSION ", buildver);
    fclose (file);
  
--- 101,121 ----
    if (build)
      buildver = buildver + 1;
    
!   if (dist_inc) {
!     distver_minor++;
!     if(distver_minor >= 100) {
! 	distver_major++;
! 	distver_minor = 0;
!     }
!   }
! 
!   file = must_open ("newversion.h", "w");
!   fprintf (file, "%s%d.%02d%s%d\n","\
  /* Version control for the shell.  This file gets changed when you say\n\
     `make newversion' to the Makefile.  It is created by newversion.aux. */\n\
  \n\
  /* The distribution version number of this shell. */\n\
! #define DISTVERSION \"", distver_major, distver_minor, "\"\n\n/* The last built version of this shell. */\n\
  #define BUILDVERSION ", buildver);
    fclose (file);
  
***************
*** 117,138 ****
    if (dist)
      {
        file = must_open (".distribution", "w");
!       fprintf (file, "%.2f\n", distver);
        fclose (file);
      }
    exit (0);
  }
  
! get_float_from_file (filename, var)
!      char *filename;
!      float *var;
  {
    FILE *stream;
    int result;
  
    if ((stream  = fopen (filename, "r")) == (FILE *)NULL)
      return (1);
!   result = fscanf (stream, "%f\n", var);
    fclose (stream);
    return (result == 1);
  }
--- 126,148 ----
    if (dist)
      {
        file = must_open (".distribution", "w");
!       fprintf (file, "%d.%02d\n", distver_major, distver_minor);
        fclose (file);
      }
    exit (0);
  }
  
! get_float_from_file (filename, var1, var2)
!      char *filename;
!      int * var1;
!      int * var2;
  {
    FILE *stream;
    int result;
  
    if ((stream  = fopen (filename, "r")) == (FILE *)NULL)
      return (1);
!   result = fscanf (stream, "%d.%d\n", var1, var2);
    fclose (stream);
    return (result == 1);
  }

*** bash-1.05/nojobs.c	Mon Oct 29 17:36:48 1990
--- minix_bash/nojobs.c	Thu Nov  1 23:29:18 1990
***************
*** 21,29 ****
  
  #include <stdio.h>
  #include <sys/types.h>
! #include <sys/ttold.h>
! #include <fcntl.h>
! #include <termio.h>
  #include <signal.h>
  #include <setjmp.h>
  #include <errno.h>
--- 21,31 ----
  
  #include <stdio.h>
  #include <sys/types.h>
! #ifndef MINIX
! #include <sys/ttold.h>
! #include <termio.h>
! #endif /* MINIX */
! #include <fcntl.h>
  #include <signal.h>
  #include <setjmp.h>
  #include <errno.h>
***************
*** 36,42 ****
  #define SIGABRT SIGIOT
  #endif
  
! #ifdef SYSV
  #define killpg(pg, sig)		kill(-(pg),(sig))
  #endif /* SYSV */
  
--- 38,44 ----
  #define SIGABRT SIGIOT
  #endif
  
! #if defined(SYSV) || defined(MINIX)
  #define killpg(pg, sig)		kill(-(pg),(sig))
  #endif /* SYSV */
  
***************
*** 149,155 ****
       int pid;
  {
    int got_pid;
!   union wait status;
  
    while ((got_pid = wait (&status)) != pid)
      {
--- 151,161 ----
       int pid;
  {
    int got_pid;
! #ifdef MINIX
!   int status;
! #else
!   union wait status;
! #endif /* MINIX */
  
    while ((got_pid = wait (&status)) != pid)
      {
***************
*** 175,181 ****
    while (1)
      {
        int got_pid;
!       union wait status;
  
        while ((got_pid = wait(&status)) != -1)  /* wait for ECHILD */
  	;
--- 181,191 ----
    while (1)
      {
        int got_pid;
! #ifdef MINIX
!       int status;
! #else
!       union wait status;
! #endif /* MINIX */
  
        while ((got_pid = wait(&status)) != -1)  /* wait for ECHILD */
  	;
***************
*** 196,208 ****
  {
    extern int interactive;
    int got_pid, return_val, oldmask;
!   union wait status;
  
    while ((got_pid = wait (&status)) != pid)
      {
        if (got_pid < 0 && errno == ECHILD)
  	{
! 	  status.w_termsig = status.w_retcode = 0;
  	  break;
  	}
        else if (got_pid < 0 && errno != EINTR)
--- 206,226 ----
  {
    extern int interactive;
    int got_pid, return_val, oldmask;
! #ifdef MINIX
!   int status;
! #else
!   union wait status;
! #endif /* MINIX */
  
    while ((got_pid = wait (&status)) != pid)
      {
        if (got_pid < 0 && errno == ECHILD)
  	{
! #ifdef MINIX
! 	  status = 0;
! #else
! 	  status.w_termsig = status.w_retcode = 0;
! #endif /* MINIX */
  	  break;
  	}
        else if (got_pid < 0 && errno != EINTR)
***************
*** 213,231 ****
      QUIT;
  
    /* Default return value. */
!   return_val = status.w_retcode & 0x7f;
! 
!   if (status.w_termsig != 0 && status.w_termsig != WSTOPPED)
!     {
!       extern char *sys_siglist[];
!       fprintf (stderr, "%s", sys_siglist[status.w_termsig]);
!       if (status.w_coredump)
! 	fprintf (stderr, " (core dumped)");
!       fprintf (stderr, "\n");
!       return_val = status.w_termsig + 128;
!     }
! 
!   if (status.w_termsig != 0)
      set_tty_state ();
    else
      get_tty_state ();
--- 231,272 ----
      QUIT;
  
    /* Default return value. */
! #ifdef MINIX
!   return_val = WEXITSTATUS(status) & 0x7f;
! #else
!   return_val = status.w_retcode & 0x7f;
! #endif /* MINIX */
! 
! #ifdef MINIX
!   if (WTERMSIG(status) != 0 && !WIFSTOPPED(status))
! #else
!   if (status.w_termsig != 0 && status.w_termsig != WSTOPPED)
! #endif /* MINIX */
!     {
!       extern char *sys_siglist[];
! #ifdef MINIX
!       fprintf (stderr, "%s", sys_siglist[WTERMSIG(status)]);
! #else
!       fprintf (stderr, "%s", sys_siglist[status.w_termsig]);
! #endif /* MINIX */
! 
! #ifndef MINIX
!       if (status.w_coredump)
! 	fprintf (stderr, " (core dumped)");
! #endif /* MINIX */
!       fprintf (stderr, "\n");
! #ifdef MINIX
!       return_val = WTERMSIG(status) + 128;
! #else
!       return_val = status.w_termsig + 128;
! #endif /* MINIX */
!     }
! 
! #ifdef MINIX
!   if (WTERMSIG(status) != 0)
! #else
!   if (status.w_termsig != 0)
! #endif /* MINIX */
      set_tty_state ();
    else
      get_tty_state ();
***************
*** 251,278 ****
    return (result);
  }
  
! static struct termio shell_tty_info;
  
  /* Fill the contents of shell_tty_info with the current tty info. */
  get_tty_state ()
  {
    int tty = open ("/dev/tty", O_RDONLY);
    if (tty != -1)
      {
        ioctl (tty, TCGETA, &shell_tty_info);
        close (tty);
      }
  }
  
  /* Make the current tty use the state in shell_tty_info. */
  set_tty_state ()
  {
    int tty = open ("/dev/tty", O_RDONLY);
    if (tty != -1)
      {
        ioctl (tty, TCSETAW, &shell_tty_info);  /* Wait for output, no flush */
        close (tty);
      }
  }
  
  /* Give the terminal to PGRP.  */
--- 292,325 ----
    return (result);
  }
  
! #ifndef MINIX
! static struct termio shell_tty_info;
! #endif /* MINIX */
  
  /* Fill the contents of shell_tty_info with the current tty info. */
  get_tty_state ()
  {
+ #ifndef MINIX
    int tty = open ("/dev/tty", O_RDONLY);
    if (tty != -1)
      {
        ioctl (tty, TCGETA, &shell_tty_info);
        close (tty);
      }
+ #endif /* MINIX */
  }
  
  /* Make the current tty use the state in shell_tty_info. */
  set_tty_state ()
  {
+ #ifndef MINIX
    int tty = open ("/dev/tty", O_RDONLY);
    if (tty != -1)
      {
        ioctl (tty, TCSETAW, &shell_tty_info);  /* Wait for output, no flush */
        close (tty);
      }
+ #endif /* MINIX */
  }
  
  /* Give the terminal to PGRP.  */

*** bash-1.05/shell.c	Mon Oct 29 17:36:50 1990
--- minix_bash/shell.c	Thu Nov  1 16:31:42 1990
***************
*** 41,52 ****
  #ifndef SONY
  #include <fcntl.h>
  #endif
! #include <sys/file.h>
  #include <sys/stat.h>
  #include <pwd.h>
  
  #if defined (HAVE_VPRINTF)
! #include <varargs.h>
  #endif
  
  #include "shell.h"
--- 41,58 ----
  #ifndef SONY
  #include <fcntl.h>
  #endif
! #ifndef MINIX
! #include <sys/file.h>
! #endif /* MINIX */
  #include <sys/stat.h>
  #include <pwd.h>
  
  #if defined (HAVE_VPRINTF)
! #ifdef MINIX
! #include <stdarg.h>
! #else
! #include <varargs.h>
! #endif /* MINIX */
  #endif
  
  #include "shell.h"
***************
*** 803,809 ****
  #ifdef SIGEMT
    SIGEMT,
  #endif
!   SIGFPE, SIGKILL, SIGBUS, SIGSEGV, SIGSYS, SIGPIPE, SIGALRM, SIGTERM,
  #ifdef SIGXCPU
    SIGXCPU,
  #endif
--- 809,819 ----
  #ifdef SIGEMT
    SIGEMT,
  #endif
!   SIGFPE, SIGKILL, SIGBUS, SIGSEGV, 
! #ifdef SIGSYS
! SIGSYS, 
! #endif
! SIGPIPE, SIGALRM, SIGTERM,
  #ifdef SIGXCPU
    SIGXCPU,
  #endif

*** bash-1.05/siglist.c	Thu Feb 22 13:53:22 1990
--- minix_bash/siglist.c	Thu Nov  1 23:43:30 1990
***************
*** 18,24 ****
  with Bash; see the file COPYING.  If not, write to the Free Software
  Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  
! #include <sys/signal.h>
  
  #ifndef NSIG
  #  define NSIG 64
--- 18,28 ----
  with Bash; see the file COPYING.  If not, write to the Free Software
  Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  
! #ifdef MINIX
! #include <signal.h>
! #else
! #include <sys/signal.h>
! #endif /* MINIX */
  
  #ifndef NSIG
  #  define NSIG 64

*** bash-1.05/test.c	Tue Jan 16 19:31:06 1990
--- minix_bash/test.c	Thu Nov  1 22:14:34 1990
***************
*** 29,35 ****
  Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  
  #include <stdio.h>
! #include <varargs.h>
  
  #ifndef SONY
  #include <fcntl.h>
--- 29,39 ----
  Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  
  #include <stdio.h>
! #ifdef MINIX
! #include <stdarg.h>
! #else
! #include <varargs.h>
! #endif /* MINIX */
  
  #ifndef SONY
  #include <fcntl.h>
***************
*** 37,43 ****
  
  #include <sys/types.h>
  #include <sys/stat.h>
! #include <sys/file.h>
  
  #ifndef R_OK
  #define R_OK 4
--- 41,51 ----
  
  #include <sys/types.h>
  #include <sys/stat.h>
! #ifdef MINIX
! #include <fcntl.h>
! #else
! #include <sys/file.h>
! #endif /* MINIX */
  
  #ifndef R_OK
  #define R_OK 4

*** bash-1.05/ulimit.c	Wed Dec 20 04:39:06 1989
--- minix_bash/ulimit.c	Thu Nov  1 22:48:58 1990
***************
*** 21,26 ****
--- 21,27 ----
  #include <stdio.h>
  #include "shell.h"
  
+ #ifndef MINIX
  #include <sys/types.h>
  #include <sys/errno.h>
  extern int errno;
***************
*** 62,71 ****
--- 63,75 ----
  
  RESOURCE_LIMIT *resource_limits = (RESOURCE_LIMIT *)NULL;
  
+ #endif /* Not MINIX */
+ 
  /* Called after we fork.  Sets the process resource limits to the
     values saved in RESOURCE_LIMITS. */
  set_process_resource_limits ()
  {
+ #ifndef MINIX
    long shell_ulimit ();
    register RESOURCE_LIMIT *limits = resource_limits;
  
***************
*** 74,79 ****
--- 78,84 ----
        shell_ulimit (limits->cmd, limits->limit, 1);
        limits = limits->next;
      }
+ #endif /* !MINIX */
  }
  
  /* Report or set limits associated with certain per-process resources.
***************
*** 82,87 ****
--- 87,96 ----
  ulimit_builtin (list)
       register WORD_LIST *list;
  {
+ #ifdef MINIX
+   report_error("ulimit not implemented under MINIX");
+   return (EXECUTION_SUCCESS);
+ #else
    long shell_ulimit ();
    register char *s;
    int c, setting, cmd, r = EXECUTION_SUCCESS;
***************
*** 229,236 ****
      }
    while (list);
    return (EXECUTION_SUCCESS);
! }
! 
  /* The ulimit that we call from within Bash.  Extended to handle
     more resources by Chet Ramey (chet@cwjcc.cwru.edu).
     WHICH says which limit to twiddle; SETTING is non-zero if NEWLIM
--- 238,247 ----
      }
    while (list);
    return (EXECUTION_SUCCESS);
! #endif /* MINIX */
! }
! 
! #ifndef MINIX
  /* The ulimit that we call from within Bash.  Extended to handle
     more resources by Chet Ramey (chet@cwjcc.cwru.edu).
     WHICH says which limit to twiddle; SETTING is non-zero if NEWLIM
***************
*** 390,393 ****
  }
  
  #endif /* !SYSV */
! 
--- 401,404 ----
  }
  
  #endif /* !SYSV */
! #endif /* !MINIX */

*** bash-1.05/unwind_prot.c	Sat Jan 20 15:02:32 1990
--- minix_bash/unwind_prot.c	Thu Nov  1 22:37:48 1990
***************
*** 25,31 ****
  /*								    */
  /* **************************************************************** */
  
! #include <sys/signal.h>
  #include "config.h"
  #include "general.h"
  
--- 25,35 ----
  /*								    */
  /* **************************************************************** */
  
! #ifdef MINIX
! #include <signal.h>
! #else
! #include <sys/signal.h>
! #endif /* MINIX */
  #include "config.h"
  #include "general.h"
  
*** bash-1.05/version.h	Mon Oct 29 17:36:52 1990
--- minix_bash/version.h	Sat Mar  9 23:31:30 1991
***************
*** 5,8 ****
  #define DISTVERSION "1.05"
  
  /* The last built version of this shell. */
! #define BUILDVERSION 14
--- 5,8 ----
  #define DISTVERSION "1.05"
  
  /* The last built version of this shell. */
! #define BUILDVERSION 4

*** bash-1.05/y.tab.h	Sat Mar  9 23:42:41 1991
--- minix_bash/y.tab.h	Thu Nov  1 21:30:24 1990
***************
*** 0 ****
--- 1,39 ----
+ 
+ typedef union  {
+   WORD_DESC *word;		/* the word that we read. */
+   int number;			/* the number that we read. */
+   WORD_LIST *word_list;
+   COMMAND *command;
+   REDIRECT *redirect;
+   ELEMENT element;
+   PATTERN_LIST *pattern;
+ } YYSTYPE;
+ extern YYSTYPE yylval;
+ # define IF 257
+ # define THEN 258
+ # define ELSE 259
+ # define ELIF 260
+ # define FI 261
+ # define CASE 262
+ # define ESAC 263
+ # define FOR 264
+ # define WHILE 265
+ # define UNTIL 266
+ # define DO 267
+ # define DONE 268
+ # define FUNCTION 269
+ # define IN 270
+ # define WORD 271
+ # define NUMBER 272
+ # define AND_AND 273
+ # define OR_OR 274
+ # define GREATER_GREATER 275
+ # define LESS_LESS 276
+ # define LESS_AND 277
+ # define GREATER_AND 278
+ # define SEMI_SEMI 279
+ # define LESS_LESS_MINUS 280
+ # define AND_GREATER 281
+ # define DOUBLE_OPEN 282
+ # define DOUBLE_CLOSE 283
+ # define yacc_EOF 284

-- 
Jim Paradis                  UUCP:  harvard!m2c!jjmhome!acestes!paradis
9 Carlstad St.               AT&T:  (508) 792-3810
Worcester, MA 01607-1569     ICBM:  42deg 13' 52",  71deg 47' 51"

paradis@acestes.UUCP (Jim Paradis) (03/12/91)

This is part 2 of the BASH patches for MINIX.

You should be sitting in the main source directory for bash when you
apply these patches

------------8<---- cut here ----8<----- cut here 8<---------------------
*** bash-1.05/y.tab.c	Sat Mar  9 23:42:41 1991
--- minix_bash/y.tab.c	Thu Nov  1 21:30:24 1990
***************
*** 0 ****
--- 1,2206 ----
+ # line 22 "parse.y"
+ #include <stdio.h>
+ #include <signal.h>
+ #include "shell.h"
+ #include "flags.h"
+ 
+ #ifdef READLINE
+ #include <readline/readline.h>
+ #include <readline/history.h>
+ #endif
+ 
+ #define YYDEBUG 1
+ extern int eof_encountered;
+ extern int no_line_editing;
+ extern int interactive;
+ 
+ # line 38 "parse.y"
+ typedef union  {
+   WORD_DESC *word;		/* the word that we read. */
+   int number;			/* the number that we read. */
+   WORD_LIST *word_list;
+   COMMAND *command;
+   REDIRECT *redirect;
+   ELEMENT element;
+   PATTERN_LIST *pattern;
+ } YYSTYPE;
+ # define IF 257
+ # define THEN 258
+ # define ELSE 259
+ # define ELIF 260
+ # define FI 261
+ # define CASE 262
+ # define ESAC 263
+ # define FOR 264
+ # define WHILE 265
+ # define UNTIL 266
+ # define DO 267
+ # define DONE 268
+ # define FUNCTION 269
+ # define IN 270
+ # define WORD 271
+ # define NUMBER 272
+ # define AND_AND 273
+ # define OR_OR 274
+ # define GREATER_GREATER 275
+ # define LESS_LESS 276
+ # define LESS_AND 277
+ # define GREATER_AND 278
+ # define SEMI_SEMI 279
+ # define LESS_LESS_MINUS 280
+ # define AND_GREATER 281
+ # define DOUBLE_OPEN 282
+ # define DOUBLE_CLOSE 283
+ # define yacc_EOF 284
+ #define yyclearin yychar = -1
+ #define yyerrok yyerrflag = 0
+ extern int yychar;
+ extern short yyerrflag;
+ #ifndef YYMAXDEPTH
+ #define YYMAXDEPTH 150
+ #endif
+ YYSTYPE yylval, yyval;
+ # define YYERRCODE 256
+ 
+ # line 349 "parse.y"
+ 
+ 
+ /* Initial size to allocate for tokens, and the
+    amount to grow them by. */
+ #define TOKEN_DEFAULT_GROW_SIZE 512
+ 
+ /* The token currently being read. */
+ int current_token = 0;
+ 
+ /* The last read token, or NULL.  read_token () uses this for context
+    checking. */
+ int last_read_token = 0;
+ 
+ /* The token read prior to last_read_token. */
+ int token_before_that = 0;
+ 
+ /* Global var is non-zero when end of file has been reached. */
+ int EOF_Reached = 0;
+ 
+ /* yy_getc () returns the next available character from input or EOF.
+    yy_ungetc (c) makes `c' the next character to read.
+    init_yy_io (get, unget), makes the function `get' the installed function
+    for getting the next character, and makes `unget' the installed function
+    for un-getting a character. */
+ return_EOF ()			/* does nothing good. */
+ {
+   return (EOF);
+ }
+ 
+ /* Variables containing the current get and unget functions. */
+ 
+ /* Some stream `types'. */
+ #define st_stream 0
+ #define st_string 1
+ 
+ Function *get_yy_char = return_EOF;
+ Function *unget_yy_char = return_EOF;
+ int yy_input_type = st_stream;
+ FILE *yy_input_dev = (FILE *)NULL;
+ 
+ /* The current stream name.  In the case of a file, this is a filename. */
+ char *stream_name = (char *)NULL;
+ 
+ /* Function to set get_yy_char and unget_yy_char. */
+ init_yy_io (get_function, unget_function, type, location)
+      Function *get_function, *unget_function;
+      int type;
+      FILE *location;
+ {
+   get_yy_char = get_function;
+   unget_yy_char = unget_function;
+   yy_input_type = type;
+   yy_input_dev = location;
+ }
+ 
+ /* Call this to get the next character of input. */
+ yy_getc ()
+ {
+   return (*get_yy_char) ();
+ }
+ 
+ /* Call this to unget C.  That is, to make C the next character
+    to be read. */
+ yy_ungetc (c)
+ {
+   return (*unget_yy_char) (c);
+ }
+ 
+ /* **************************************************************** */
+ /*								    */
+ /*		  Let input be read from readline ().		    */
+ /*								    */
+ /* **************************************************************** */
+ 
+ #ifdef READLINE
+ char *current_readline_prompt = (char *)NULL;
+ char *current_readline_line = (char *)NULL;
+ int current_readline_line_index = 0;
+ 
+ static int readline_initialized_yet = 0;
+ yy_readline_get ()
+ {
+   if (!current_readline_line)
+     {
+       char *readline ();
+       SigHandler *old_sigint;
+       extern sighandler throw_to_top_level ();
+       
+       if (!readline_initialized_yet)
+ 	{
+ 	  initialize_readline ();
+ 	  readline_initialized_yet = 1;
+ 	}
+ 
+       old_sigint = (SigHandler *)signal (SIGINT, throw_to_top_level);
+ 	  if (!current_readline_prompt)
+ 	    current_readline_line = readline ("");
+ 	  else
+ 	    current_readline_line = readline (current_readline_prompt);
+       signal (SIGINT, old_sigint);
+ 
+       current_readline_line_index = 0;
+ 
+       if (!current_readline_line)
+ 	{
+ 	  current_readline_line_index = 0;
+ 	  return (EOF);
+ 	}
+ 
+       current_readline_line =
+ 	(char *)xrealloc (current_readline_line,
+ 			  2 + strlen (current_readline_line));
+       strcat (current_readline_line, "\n");
+     }
+ 
+   if (!current_readline_line[current_readline_line_index])
+     {
+       free (current_readline_line);
+       current_readline_line = (char *)NULL;
+       return (yy_readline_get ());
+     }
+   else
+     {
+       int c = current_readline_line[current_readline_line_index++];
+       return (c);
+     }
+ }
+ 
+ yy_readline_unget (c)
+ {
+   if (current_readline_line_index && current_readline_line)
+     current_readline_line[--current_readline_line_index] = c;
+ }
+   
+ with_input_from_stdin ()
+ {
+   init_yy_io (yy_readline_get, yy_readline_unget,
+ 	      st_string, current_readline_line);
+   stream_name = savestring ("readline stdin");
+ }
+ 
+ #else  /* READLINE */
+ 
+ with_input_from_stdin ()
+ {
+   with_input_from_stream (stdin, "stdin");
+ }
+ #endif  /* READLINE */
+ 
+ /* **************************************************************** */
+ /*								    */
+ /*   Let input come from STRING.  STRING is zero terminated.	    */
+ /*								    */
+ /* **************************************************************** */
+ 
+ yy_string_get ()
+ {
+   /* If the string doesn't exist, or is empty, EOF found. */
+   if (!(char *)yy_input_dev || !*(char *)yy_input_dev)
+     return (EOF);
+   else {
+     register char *temp = (char *)yy_input_dev;
+     int c = *temp++;
+     yy_input_dev = (FILE *)temp;
+     return (c);
+   }
+ }
+ 
+ yy_string_unget (c)
+      int c;
+ {
+   register char *temp = (char *)yy_input_dev;
+   *(--temp) = c;
+   yy_input_dev = (FILE *)temp;
+   return (c);
+ }
+ 
+ with_input_from_string (string, name)
+      char *string;
+      char *name;
+ {
+   init_yy_io (yy_string_get, yy_string_unget, st_string, string);
+   stream_name = savestring (name);
+ }
+ 
+ /* **************************************************************** */
+ /*								    */
+ /*		     Let input come from STREAM.		    */
+ /*								    */
+ /* **************************************************************** */
+ 
+ yy_stream_get ()
+ {
+   if (yy_input_dev)
+ #ifdef SYSV
+     return (sysv_getc (yy_input_dev));
+ #else
+     return (getc (yy_input_dev));
+ #endif  /* SYSV */
+   else return (EOF);
+ }
+ 
+ yy_stream_unget (c)
+      int c;
+ {
+   ungetc (c, yy_input_dev);
+ }
+ 
+ with_input_from_stream (stream, name)
+      FILE *stream;
+      char *name;
+ {
+   init_yy_io (yy_stream_get, yy_stream_unget, st_stream, stream);
+   stream_name = savestring (name);
+ }
+ 
+ typedef struct stream_saver {
+   struct stream_saver *next;
+   Function *getter, *putter;
+   int type, line;
+   char *location, *name;
+ } STREAM_SAVER;
+ 
+ /* The globally known line number. */
+ int line_number = 0;
+ 
+ STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL;
+ 
+ push_stream ()
+ {
+   STREAM_SAVER *temp = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER));
+   temp->type = yy_input_type;
+   temp->location = (char *)yy_input_dev;
+   temp->getter = get_yy_char;
+   temp->putter = unget_yy_char;
+   temp->line = line_number;
+   temp->name = stream_name; stream_name = (char *)NULL;
+   temp->next = stream_list;
+   stream_list = temp;
+   EOF_Reached = line_number = 0;
+ }
+ 
+ pop_stream ()
+ {
+   if (!stream_list)
+     {
+       EOF_Reached = 1;
+     }
+   else
+     {
+       STREAM_SAVER *temp = stream_list;
+     
+       EOF_Reached = 0;
+       stream_list = stream_list->next;
+ 
+       if (stream_name)
+ 	free (stream_name);
+       stream_name = temp->name;
+ 
+       init_yy_io (temp->getter, temp->putter, temp->type, temp->location);
+       line_number = temp->line;
+       free (temp);
+     }
+ }
+ 
+ 
+ /* Return a line of text, taken from wherever yylex () reads input.
+    If there is no more input, then we return NULL. */
+ char *
+ read_a_line ()
+ {
+   char *line_buffer = (char *)NULL;
+   int index = 0, buffer_size = 0;
+   int c;
+ 
+   while (c = yy_getc ())
+     {
+       /* If there is no more input, then we return NULL. */
+       if (c == EOF)
+ 	{
+ 	  c = '\n';
+ 	  if (!line_buffer)
+ 	    return ((char *)NULL);
+ 	}
+ 
+       if (index + 1 > buffer_size)
+ 	if (!buffer_size)
+ 	  line_buffer = (char *)xmalloc (buffer_size = 200);
+ 	else
+ 	  line_buffer = (char *)xrealloc (line_buffer, buffer_size += 200);
+ 
+       line_buffer[index++] = c;
+       if (c == '\n')
+ 	{
+ 	  line_buffer[index] = '\0';
+ 	  return (line_buffer);
+ 	}
+     }
+ }
+ 
+ 
+ /* Return a line as in read_a_line (), but insure that the prompt is
+    the secondary prompt. */
+ char *
+ read_secondary_line ()
+ {
+   char *decode_prompt_string ();
+   char *temp_prompt = get_string_value ("PS2");
+ 
+ #ifdef READLINE
+   if (!no_line_editing)
+     {
+       extern char *current_readline_prompt;
+ 
+       if (current_readline_prompt)
+ 	{
+ 	  free (current_readline_prompt);
+ 	  current_readline_prompt = (char *)NULL;
+ 	}
+ 
+       if (temp_prompt)
+ 	current_readline_prompt = decode_prompt_string (temp_prompt);
+       else
+ 	current_readline_prompt = (savestring (""));
+     }
+   else
+ #endif  /* READLINE */
+     {
+       printf ("%s", temp_prompt ? temp_prompt : "");
+       fflush (stdout);
+     }
+ 
+   return (read_a_line ());
+ }
+ 
+ /* **************************************************************** */
+ /*								    */
+ /*				YYLEX ()			    */
+ /*								    */
+ /* **************************************************************** */
+ 
+ /* Reserved words.  These are only recognized as the first word of a
+    command.  TOKEN_WORD_ALIST. */
+ struct {
+   char *word;
+   int token;
+ } token_word_alist[] = {
+   {"if", IF},
+   {"then", THEN},
+   {"else", ELSE},
+   {"elif", ELIF},
+   {"fi", FI},
+   {"case", CASE},
+   {"esac", ESAC},
+   {"for", FOR},
+   {"while", WHILE},
+   {"until", UNTIL},
+   {"do", DO},
+   {"done", DONE},
+   {"in", IN},
+   {"function", FUNCTION},
+   {"{", '{'},
+   {"}", '}'},
+   {(char *)NULL, 0}
+ };
+ 
+ /* Where shell input comes from.  For each line that we read, alias
+    and history expansion are done. */
+ char *shell_input_line = (char *)NULL;
+ int shell_input_line_index = 0;
+ int shell_input_line_size = 0;
+ 
+ /* Either zero, or EOF. */
+ int shell_input_line_terminator = 0;
+ 
+ /* Return the next shell input character.  This always reads characters
+    from shell_input_line; when that line is exhausted, it is time to
+    read the next line. */
+ int
+ shell_getc (remove_quoted_newline)
+      int remove_quoted_newline;
+ {
+   extern int login_shell;
+   int c;
+ 
+   if (!shell_input_line || !shell_input_line[shell_input_line_index])
+     {
+       register int i, l;
+       char *pre_process_line (), *expansions;
+ 
+       restart_read_next_line:
+ 
+       line_number++;
+ 
+     restart_read:
+ 
+       i = 0;
+       shell_input_line_terminator = 0;
+ 
+ #ifdef JOB_CONTROL
+       notify_and_cleanup ();
+ #endif
+ 
+       clearerr (stdin);
+       while (c = yy_getc ())
+ 	{
+ 	  if (i + 2 > shell_input_line_size)
+ 	    if (!shell_input_line)
+ 	      shell_input_line = (char *)xmalloc (shell_input_line_size = 256);
+ 	    else
+ 	      shell_input_line =
+ 		(char *)xrealloc (shell_input_line, shell_input_line_size += 256);
+ 
+ 	  if (c == EOF)
+ 	    {
+ 	      clearerr (stdin);
+ 
+ 	      if (!i)
+ 		shell_input_line_terminator = EOF;
+ 
+ 	      shell_input_line[i] = '\0';
+ 	      break;
+ 	    }
+ 
+ 	  shell_input_line[i++] = c;
+ 
+ 	  if (c == '\n')
+ 	    {
+ 	      shell_input_line[--i] = '\0';
+ 	      break;
+ 	    }
+ 	}
+       shell_input_line_index = 0;
+ 
+       if (!shell_input_line[0] || shell_input_line[0] == '#')
+ 	goto after_pre_process;
+ 
+       expansions = pre_process_line (shell_input_line, 1, 1);
+ 
+       free (shell_input_line);
+       shell_input_line = expansions;
+ 
+       if (shell_input_line)
+ 	{
+ 	  if (echo_input_at_read)
+ 	    fprintf (stderr, "%s\n", shell_input_line);
+ 
+ 	  shell_input_line_size = strlen (expansions);
+ 
+ 	}
+       else
+ 	{
+ 	  shell_input_line_size = 0;
+ 	  prompt_again ();
+ 	  goto restart_read;
+ 	}
+ 
+     after_pre_process:
+       /* Add the newline to the end of this string, iff the string does
+ 	 not already end in an EOF character.  */
+       if (shell_input_line_terminator != EOF)
+ 	{
+ 	  l = strlen (shell_input_line);
+ 
+ 	  if (l + 3 > shell_input_line_size)
+ 	    shell_input_line =
+ 	      (char *)xrealloc (shell_input_line,
+ 				1 + (shell_input_line_size += 2));
+ 	  strcpy (shell_input_line + l, "\n");
+ 	}
+     }
+   
+   c = shell_input_line[shell_input_line_index];
+ 
+   if (c)
+     shell_input_line_index++;
+ 
+   if (c == '\\' && remove_quoted_newline &&
+       shell_input_line[shell_input_line_index] == '\n')
+     {
+       prompt_again ();
+       goto restart_read_next_line;
+     }
+ 
+   if (!c && shell_input_line_terminator == EOF)
+     {
+       if (shell_input_line_index != 0)
+ 	return ('\n');
+       else
+ 	return (EOF);
+     }
+ 
+   return (c);
+ }
+ 
+ /* Put C back into the input for the shell. */
+ shell_ungetc (c)
+      int c;
+ {
+   if (shell_input_line && shell_input_line_index)
+     shell_input_line[--shell_input_line_index] = c;
+ }
+ 
+ /* Discard input until CHARACTER is seen. */
+ discard_until (character)
+      int character;
+ {
+   int c;
+   while ((c = shell_getc (0)) != EOF && c != character)
+     ;
+   if (c != EOF )
+     shell_ungetc (c);
+ }
+ 
+ /* Tell readline () that we have some text for it to edit. */
+ re_edit (text)
+      char *text;
+ {
+ #ifdef READLINE
+   if (strcmp (stream_name, "readline stdin") == 0)
+     bash_re_edit (text);
+ #endif
+ }
+ 
+ /* Non-zero means do no history expansion on this line, regardless
+    of what history_expansion says. */
+ int history_expansion_inhibited = 0;
+ 
+ /* Do pre-processing on LINE.  If PRINT_CHANGES is non-zero, then
+    print the results of expanding the line if there were any changes.
+    If there is an error, return NULL, otherwise the expanded line is
+    returned.  If ADDIT is non-zero the line is added to the history
+    list after history expansion, but before alias expansion.  ADDIT
+    is just a suggestion; REMEMBER_ON_HISTORY can veto, and does.
+    Right now this does history and alias expansion. */
+ char *
+ pre_process_line (line, print_changes, addit)
+      char *line;
+      int print_changes, addit;
+ {
+   extern int history_expansion;
+   extern int remember_on_history;
+   int history_expand ();
+   char *history_value;
+   char *return_value = line;
+   int expanded = 0;
+ 
+ #ifdef ALIAS
+   char *alias_expand (), *alias_value;
+ #endif
+ 
+   /* History expand the line.  If this results in no errors, then
+      add that line to the history if ADDIT is non-zero. */
+   if (!history_expansion_inhibited && history_expansion)
+     {
+       expanded = history_expand (line, &history_value);
+ 
+       if (expanded)
+ 	{
+ 	  if (print_changes)
+ 	    fprintf (stderr, "%s\n", history_value);
+ 
+ 	  /* If there was an error, return NULL. */
+ 	  if (expanded < 0)
+ 	    {
+ 	      free (history_value);
+ 
+ 	      /* New hack.  We can allow the user to edit the
+ 		 failed history expansion. */
+ 	      re_edit (line);
+ 
+ 	      return ((char *)NULL);
+ 	    }
+ 	}
+ 
+       /* Let other expansions know that return_value can be free'ed,
+ 	 and that a line has been added to the history list. */
+       expanded = 1;
+       return_value = history_value;
+     }
+ 
+   if (addit && remember_on_history)
+     {
+       extern int history_control;
+ 
+       switch (history_control)
+ 	{
+ 	case 0:
+ 	  add_history (return_value);
+ 	  break;
+ 	case 1:
+ 	  if (*return_value != ' ')
+ 	    add_history (return_value);
+ 	  break;
+ 	case 2:
+ 	  {
+ 	    HIST_ENTRY *temp = previous_history ();
+ 	    if (!temp || (strcmp (temp->line, return_value) != 0))
+ 	      add_history (return_value);
+ 	    using_history ();
+ 	  }
+ 	  break;
+ 	}
+     }
+ 
+ #ifdef ALIAS
+   alias_value = alias_expand (return_value);
+ 
+   if (expanded)
+     {
+       expanded = 0;
+       free (return_value);
+     }
+ 
+   return_value = alias_value;
+ 
+ #else
+   return_value = savestring (line);
+ #endif /* ALIAS */
+ 
+ #ifdef ALIAS
+ #ifdef NEVER  /* Expanding history-wise here is sematically incorrect
+ 		 for this shell, and should never be done.  I figured
+ 		 it out, so just trust me, okay? */
+   /* History expand the alias.  This is a special hack.  Don't you
+      just hate this? */
+ 
+   if (!history_expansion_inhibited && history_expansion)
+     {
+       expanded = history_expand (return_value, &history_value);
+ 
+       if (expanded < 0)
+ 	{
+ 	  free (history_value);
+ 	  free (return_value);
+ 	  return ((char *)NULL);
+ 	}
+ 
+       if (expanded)
+ 	{
+ 	  free (return_value);
+ 	  return_value = history_value;
+ 	}
+     }
+ #endif  /* NEVER */
+ #endif  /* ALIAS */
+   return (return_value);
+ }
+ 
+ 
+ /* Place to remember the token.  We try to keep the buffer
+    at a reasonable size, but it can grow. */
+ char *token = NULL;
+ 
+ /* Current size of the token buffer. */
+ int token_buffer_size = 0;
+ 
+ /* Command to read_token () explaining what we want it to do. */
+ #define READ 0
+ #define RESET 1
+ 
+ /* prompt_string_pointer points to one of these,
+    never to an actual string. */
+ char *ps1_prompt, *ps2_prompt;
+ 
+ /* Handle on the current prompt string.  Indirectly points through
+    ps1_ or ps2_prompt. */
+ char **prompt_string_pointer;
+ 
+ /* Function for yyparse to call.  yylex keeps track of
+    the last two tokens read, and calls read_token.  */
+ yylex ()
+ {
+   if (interactive && (!current_token || current_token == '\n'))
+     {
+       /* Before we print a prompt, we might have to check mailboxes.
+ 	 We do this only if it is time to do so. Notice that only here
+ 	 is the mail alarm reset; nothing takes place in check_mail ()
+ 	 except the checking of mail.  Please don't change this. */
+       if (time_to_check_mail ())
+ 	{
+ 	  check_mail ();
+ 	  reset_mail_timer ();
+ 	}
+ 
+       /* Allow the execution of a random command just before the printing
+ 	 of each prompt.  If the shell variable PROMPT_COMMAND
+ 	 is set then the value of it is the command to execute. */
+       {
+ 	char *command_to_execute = get_string_value ("PROMPT_COMMAND");
+ 
+ 	if (command_to_execute)
+ 	  {
+ 	    extern Function *last_shell_builtin, *this_shell_builtin;
+ 	    Function *temp_last, *temp_this;
+ 
+ 	    temp_last = last_shell_builtin;
+ 	    temp_this = this_shell_builtin;
+ 
+ 	    parse_and_execute (savestring (command_to_execute),
+ 			       "PROMPT_COMMAND");
+ 	    last_shell_builtin = temp_last;
+ 	    this_shell_builtin = temp_this;
+ 	  }
+       }
+ 
+       prompt_again ();
+       prompt_string_pointer = &ps2_prompt;
+     }
+ 
+   token_before_that = last_read_token;
+   last_read_token = current_token;
+   current_token = read_token (READ);
+   return (current_token);
+ }
+ 
+ /* Called from shell.c when Control-C is typed at top level.  Or
+    by the error rule at top level. */
+ reset_parser ()
+ {
+   read_token (RESET);
+ }
+   
+ /* When non-zero, we have read the required tokens
+    which allow ESAC to be the next one read. */
+ static int allow_esac_as_next = 0;
+ 
+ /* When non-zero, accept single '{' as a token itself. */
+ static int allow_open_brace = 0;
+ 
+ /* DELIMITER is the value of the delimiter that is currently
+    enclosing, or zero for none. */
+ static int delimiter = 0;
+ 
+ /* When non-zero, an open-brace used to create a group is awaiting a close
+    brace partner. */
+ static int open_brace_awaiting_satisfaction = 0;
+ 
+ /* If non-zero, it is the token that we want read_token to return regardless
+    of what text is (or isn't) present to be read.  read_token resets this. */
+ int token_to_read = 0;
+ 
+ /* Read the next token.  Command can be READ (normal operation) or 
+    RESET (to normalize state. */
+ read_token (command)
+      int command;
+ {
+   int character;		/* Current character. */
+   int peek_char;		/* Temporary look-ahead character. */
+   int result;			/* The thing to return. */
+   WORD_DESC *the_word;		/* The value for YYLVAL when a WORD is read. */
+ 
+   if (token_buffer_size < TOKEN_DEFAULT_GROW_SIZE)
+     {
+       if (token)
+ 	free (token);
+       token = (char *)xmalloc (token_buffer_size = TOKEN_DEFAULT_GROW_SIZE);
+     }
+ 
+   if (command == RESET)
+     {
+       delimiter = 0;
+       open_brace_awaiting_satisfaction = 0;
+       if (shell_input_line)
+ 	{
+ 	  free (shell_input_line);
+ 	  shell_input_line = (char *)NULL;
+ 	  shell_input_line_size = 0;
+ 	}
+       last_read_token = '\n';
+       token_to_read = '\n';
+       return;
+     }
+ 
+   if (token_to_read)
+     {
+       int rt = token_to_read;
+       token_to_read = 0;
+       return (rt);
+     }
+ 
+   /* Read a single word from input.  Start by skipping blanks. */
+   while ((character = shell_getc (1)) != EOF && whitespace (character));
+ 
+   if (character == EOF)
+     return (yacc_EOF);
+ 
+   if (character == '#' && !interactive)
+     {
+       /* A comment.  Discard until EOL or EOF, and then return a newline. */
+       discard_until ('\n');
+       shell_getc (0);
+       return ('\n');
+     }
+ 
+   if (character == '\n')
+     return (character);
+ 
+   if (member (character, "()<>;&|"))
+     {
+       /* Please note that the shell does not allow whitespace to
+ 	 appear in between tokens which are character pairs, such as
+ 	 "<<" or ">>".  I believe this is the correct behaviour. */
+ 
+       if (character == (peek_char = shell_getc (1)))
+ 	{
+ 	  switch (character)
+ 	    {
+ 	      /* If '<' then we could be at "<<" or at "<<-".  We have to
+ 		 look ahead one more character. */
+ 	    case '<':
+ 	      peek_char = shell_getc (1);
+ 	      if (peek_char == '-')
+ 		return (LESS_LESS_MINUS);
+ 	      else
+ 		{
+ 		  shell_ungetc (peek_char);
+ 		  return (LESS_LESS);
+ 		}
+ 
+ 	    case '(': return (DOUBLE_OPEN);
+ 	    case ')': return (DOUBLE_CLOSE);
+ 	    case '>': return (GREATER_GREATER);
+ 	    case ';':	return (SEMI_SEMI);
+ 	    case '&': return (AND_AND);
+ 	    case '|': return (OR_OR);
+ 	    }
+ 	}
+       else
+ 	{
+ 	  if (peek_char == '&')
+ 	    {
+ 	      switch (character)
+ 		{
+ 		case '<': return (LESS_AND);
+ 		case '>': return (GREATER_AND);
+ 		}
+ 	    }
+ 	  if (peek_char == '>' && character == '&')
+ 	    return (AND_GREATER);
+ 	}
+       shell_ungetc (peek_char);
+ 
+       /* If we look like we are reading the start of a function
+ 	 definition, then let the reader know about it so that
+ 	 we will do the right thing with `{'. */
+       if (character == ')' &&
+ 	  last_read_token == '(' && token_before_that == WORD)
+ 	allow_open_brace = 1;
+ 
+       return (character);
+     }
+ 
+   /* Hack <&- (close stdin) case. */
+   if (character == '-')
+     {
+       switch (last_read_token)
+ 	{
+ 	case LESS_AND:
+ 	case GREATER_AND:
+ 	  return (character);
+ 	}
+     }
+   
+   /* Okay, if we got this far, we have to read a word.  Read one,
+      and then check it against the known ones. */
+   {
+     /* Index into the token that we are building. */
+     int token_index = 0;
+ 
+     /* ALL_DIGITS becomes zero when we see a non-digit. */
+     int all_digits = digit (character);
+ 
+     /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
+     int dollar_present = 0;
+ 
+     /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
+     int quoted = 0;
+ 
+     /* Non-zero means to ignore the value of the next character, and just
+        to add it no matter what. */
+     int pass_next_character = 0;
+ 
+     /* Non-zero means parsing a dollar-paren construct.  It is the count of
+        un-quoted closes we need to see. */
+     int dollar_paren_level = 0;
+ 
+     /* Another level variable.  This one is for dollar_parens inside of
+        double-quotes. */
+     int delimited_paren_level = 0;
+ 
+     for (;;)
+       {
+ 	if (character == EOF)
+ 	  goto got_token;
+ 
+ 	if (pass_next_character)
+ 	  {
+ 	    pass_next_character = 0;
+ 	    goto got_character;
+ 	  }
+ 
+ 	/* Handle double backslash.  These are always magic.  The
+ 	   second backslash does not cause a trailing newline to be
+ 	   eaten. */
+ 
+ 	if (character == '\\')
+ 	  {
+ 	    peek_char = shell_getc (0);
+ 	    if (peek_char != '\\')
+ 	      shell_ungetc (peek_char);
+ 	    else
+ 	      {
+ 		token[token_index++] = character;
+ 		goto got_character;
+ 	      }
+ 	  }
+ 
+ 	/* Handle backslashes.  Quote lots of things when not inside of
+ 	   double-quotes, quote some things inside of double-quotes. */
+ 
+ 	if (character == '\\' && delimiter != '\'')
+ 	  {
+ 	    peek_char = shell_getc (0);
+ 
+ 	    /* Backslash-newline is ignored in all other cases. */
+ 	    if (peek_char == '\n')
+ 	      {
+ 		character = '\n';
+ 		goto next_character;
+ 	      }
+ 	    else
+ 	      {
+ 		shell_ungetc (peek_char);
+ 
+ 		/* If the next character is to be quoted, do it now. */
+ 		if (!delimiter || delimiter == '`' ||
+ 		    ((delimiter == '"' ) &&
+ 		     (member (peek_char, slashify_in_quotes))))
+ 		  {
+ 		    pass_next_character++;
+ 		    quoted = 1;
+ 		    goto got_character;
+ 		  }
+ 	      }
+ 	  }
+ 
+ 	if (delimiter)
+ 	  {
+ 	    if (character == delimiter)
+ 	      {
+ 		delimiter = 0;
+ 		if (delimited_paren_level)
+ 		  {
+ 		    report_error ("Expected ')' before %c", character);
+ 		    return ('\n');
+ 		  }
+ 		goto got_character;
+ 	      }
+ 	  }
+ 
+ 	if (!delimiter || delimiter == '`' || delimiter == '"')
+ 	  {
+ 	    if (character == '$')
+ 	      {
+ 		peek_char = shell_getc (1);
+ 		shell_ungetc (peek_char);
+ 		if (peek_char == '(')
+ 		  {
+ 		    if (!delimiter)
+ 		      dollar_paren_level++;
+ 		    else
+ 		      delimited_paren_level++;
+ 
+ 		    pass_next_character++;
+ 		    goto got_character;
+ 		  }
+ 	      }
+ 		
+ 	    if (character == ')')
+ 	      {
+ 		if (delimiter && delimited_paren_level)
+ 		  delimited_paren_level--;
+ 
+ 		if (!delimiter && dollar_paren_level)
+ 		  {
+ 		    dollar_paren_level--;
+ 		    goto got_character;
+ 		  }
+ 	      }
+ 	  }
+ 
+ 	if (!dollar_paren_level && !delimiter &&
+ 	    member (character, " \t\n;&()|<>"))
+ 	  {
+ 	    shell_ungetc (character);
+ 	    goto got_token;
+ 	  }
+     
+ 	if (!delimiter)
+ 	  {
+ 	    if (character == '"' || character == '`' || character == '\'')
+ 	      {
+ 		quoted = 1;
+ 		delimiter = character;
+ 		goto got_character;
+ 	      }
+ 	  }
+ 
+ 	if (all_digits) all_digits = digit (character);
+ 	if (character == '$') dollar_present = 1;
+ 
+       got_character:
+ 
+ 	token[token_index++] = character;
+ 
+ 	if (token_index == (token_buffer_size - 1))
+ 	  token = (char *)xrealloc (token, (token_buffer_size
+ 					    += TOKEN_DEFAULT_GROW_SIZE));
+ 	{
+ 	  char *decode_prompt_string ();
+ 
+ 	next_character:
+ 	  if (character == '\n' && interactive)
+ 	    prompt_again ();
+ 	}
+ 	character = shell_getc ((delimiter != '\''));
+       }
+ 
+ got_token:
+ 
+     token[token_index] = '\0';
+ 	
+     if ((delimiter || dollar_paren_level) && character == EOF)
+       {
+ 	if (dollar_paren_level && !delimiter)
+ 	  delimiter = ')';
+ 
+ 	report_error ("Unexpected EOF.  Looking for `%c'.", delimiter);
+ 	return (-1);
+       }
+ 
+     if (all_digits)
+       {
+ 	/* Check to see what thing we should return.  If the last_read_token
+ 	   is a `<', or a `&', or the character which ended this token is
+ 	   a '>' or '<', then, and ONLY then, is this input token a NUMBER.
+ 	   Otherwise, it is just a word, and should be returned as such. */
+ 
+ 	if ((character == '<' || character == '>') ||
+ 	    (last_read_token == LESS_AND ||
+ 	     last_read_token == GREATER_AND))
+ 	  {
+ 	    sscanf (token, "%d", &(yylval.number));
+ 	    return (NUMBER);
+ 	  }
+       }
+ 
+     /* Handle special case.  IN is recognized if the last token
+        was WORD and the token before that was FOR or CASE. */
+     if ((strcmp (token, "in") == 0) &&
+ 	(last_read_token == WORD) &&
+ 	((token_before_that == FOR) ||
+ 	 (token_before_that == CASE)))
+       {
+ 	if (token_before_that == CASE) allow_esac_as_next++;
+ 	return (IN);
+       }
+ 
+     /* Ditto for DO in the FOR case. */
+     if ((strcmp (token, "do") == 0) &&
+ 	(last_read_token == WORD) &&
+ 	(token_before_that == FOR))
+       return (DO);
+ 
+     /* Ditto for ESAC in the CASE case. 
+        Specifically, this handles "case word in esac", which is a legal
+        construct, certainly because someone will pass an empty arg to the
+        case construct, and we don't want it to barf.  Of course, we should
+        insist that the case construct has at least one pattern in it, but
+        the designers disagree. */
+     if (allow_esac_as_next)
+       {
+ 	allow_esac_as_next--;
+ 	if (strcmp (token, "esac") == 0)
+ 	  return (ESAC);
+       }
+ 
+     /* Ditto for `{' in the FUNCTION case. */
+     if (allow_open_brace)
+       {
+ 	allow_open_brace = 0;
+ 	if (strcmp (token, "{") == 0)
+ 	  {
+ 	    open_brace_awaiting_satisfaction++;
+ 	    return ('{');
+ 	  }
+       }
+ 
+     /* Check to see if it is a reserved word. */
+     if (!dollar_present && !quoted &&
+ 	reserved_word_acceptable (last_read_token))
+       {
+ 	int i;
+ 	for (i = 0; token_word_alist[i].word != (char *)NULL; i++)
+ 	  if (strcmp (token, token_word_alist[i].word) == 0)
+ 	    {
+ 	      if (token_word_alist[i].token == '{')
+ 		open_brace_awaiting_satisfaction++;
+ 
+ 	      return (token_word_alist[i].token);
+ 	    }
+       }
+ 
+     /* What if we are attempting to satisfy an open-brace grouper? */
+     if (open_brace_awaiting_satisfaction && strcmp (token, "}") == 0)
+       {
+ 	open_brace_awaiting_satisfaction--;
+ 	return ('}');
+       }
+       
+     the_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
+     the_word->word = (char *)xmalloc (1 + strlen (token));
+     strcpy (the_word->word, token);
+     the_word->dollar_present = dollar_present;
+     the_word->quoted = quoted;
+     the_word->assignment = assignment (token);
+ 
+     yylval.word = the_word;
+     result = WORD;
+     if (last_read_token == FUNCTION)
+       allow_open_brace = 1;
+   }
+   return (result);
+ }
+ 
+ /* Return 1 if TOKEN is a token that after being read would allow
+    a reserved word to be seen, else 0. */
+ reserved_word_acceptable (token)
+      int token;
+ {
+   if (member (token, "\n;()|&{") ||
+       token == AND_AND ||
+       token == OR_OR ||
+       token == SEMI_SEMI ||
+       token == DO ||
+       token == IF ||
+       token == THEN ||
+       token == ELSE ||
+       token == ELIF ||
+       token == 0)
+     return (1);
+   else
+     return (0);
+ }
+ 
+ /* Issue a prompt, or prepare to issue a prompt when the next character
+    is read. */
+ prompt_again ()
+ {
+   char *decode_prompt_string ();
+   char *temp_prompt;
+ 
+   ps1_prompt = get_string_value ("PS1");
+   ps2_prompt = get_string_value ("PS2");
+ 
+   if (!prompt_string_pointer)
+     prompt_string_pointer = &ps1_prompt;
+ 
+   if (*prompt_string_pointer)
+     temp_prompt = decode_prompt_string (*prompt_string_pointer);
+   else
+     temp_prompt = savestring ("");
+ 
+ #ifdef READLINE
+   if (!no_line_editing)
+     {
+       if (current_readline_prompt)
+ 	free (current_readline_prompt);
+       
+       current_readline_prompt = temp_prompt;
+     }
+   else
+ #endif  /* READLINE */
+     {
+       if (interactive)
+ 	{
+ 	  fprintf (stderr, "%s", temp_prompt);
+ 	  fflush (stderr);
+ 	}
+       free (temp_prompt);
+     }
+ }
+ 
+ /* This sucks. but it is just a crock for SYSV.  The whole idea of MAXPATHLEN
+    is a crock if you ask me.  Why can't we just have dynamically defined
+    sizes?  (UCSB crashes every 20 minutes on me.) */
+ #ifndef MAXPATHLEN
+ #define MAXPATHLEN 1024
+ #endif  /* MAXPATHLEN */
+ 
+ /* Return a string which will be printed as a prompt.  The string
+    may contain special characters which are decoded as follows:
+    
+ 	\t	the time
+ 	\d	the date
+ 	\n	CRLF
+ 	\s	the name of the shell
+ 	\w	the current working directory
+ 	\W	the last element of PWD
+ 	\u	your username
+ 	\h	the hostname
+ 	\#	the command number of this command
+ 	\!	the history number of this command
+ 	\$	a $ or a # if you are root
+ 	\<octal> character code in octal
+ 	\\	a backslash
+ */
+ #ifdef MINIX
+ #include <sys/types.h>
+ #else
+ #include <sys/param.h>
+ #endif /* MINIX */
+ #include <time.h>
+ 
+ #define PROMPT_GROWTH 50
+ char *
+ decode_prompt_string (string)
+      char *string;
+ {
+   int result_size = PROMPT_GROWTH;
+   int result_index = 0;
+   char *result = (char *)xmalloc (PROMPT_GROWTH);
+   int c;
+   char *temp = (char *)NULL;
+ 
+   result[0] = 0;
+   while (c = *string++)
+     {
+       if (c == '\\')
+ 	{
+ 	  c = *string;
+ 
+ 	  switch (c)
+ 	    {
+ 
+ 	    case '0':
+ 	    case '1':
+ 	    case '2':
+ 	    case '3':
+ 	    case '4':
+ 	    case '5':
+ 	    case '6':
+ 	    case '7':
+ 	      {
+ 		char octal_string[4];
+ 		int n;
+ 
+ 		strncpy (octal_string, string, 3);
+ 		octal_string[3] = '\0';
+ 
+ 		n = read_octal (octal_string);
+ 
+ 		temp = savestring ("\\");
+ 		if (n != -1)
+ 		  {
+ 		    string += 3;
+ 		    temp[0] = n;
+ 		  }
+ 
+ 		c = 0;
+ 		goto add_string;
+ 	      }
+ 	  
+ 	    case 't':
+ 	    case 'd':
+ 
+ 	      /* Make the current time/date into a string. */
+ 	      {
+ 		long the_time = time (0);
+ 		char *ttemp = ctime (&the_time);
+ 		temp = savestring (ttemp);
+ 
+ 		if (c == 't')
+ 		  {
+ 		    strcpy (temp, temp + 11);
+ 		    temp[8] = '\0';
+ 		  }
+ 		else
+ 		  temp[10] = '\0';
+ 
+ 		goto add_string;
+ 	      }
+ 
+ 	    case 'n':
+ 	      temp = savestring ("\r\n");
+ 	      goto add_string;
+ 
+ 	    case 's':
+ 	      {
+ 		extern char *shell_name;
+ 		temp = savestring (shell_name);
+ 		goto add_string;
+ 	      }
+ 	
+ 	    case 'w':
+ 	    case 'W':
+ 	      {
+ 		/* Use the value of PWD because it is much more effecient. */
+ #define EFFICIENT
+ #ifdef EFFICIENT
+ 		char *polite_directory_format (), t_string[MAXPATHLEN];
+ 
+ 		temp = get_string_value ("PWD");
+ 
+ 		if (!temp)
+ 		  getwd (t_string);
+ 		else
+ 		  strcpy (t_string, temp);
+ #else
+ 		getwd (t_string);
+ #endif  /* EFFICIENT */
+ 
+ 		if (c == 'W')
+ 		  {
+ 		    char *rindex (), *dir = rindex (t_string, '/');
+ 		    if (dir)
+ 		      strcpy (t_string, dir + 1);
+ 		    temp = savestring (t_string);
+ 		  }
+ 		else
+ 		  temp = savestring (polite_directory_format (t_string));
+ 		goto add_string;
+ 	      }
+       
+ 	    case 'u':
+ 	      {
+ 		extern char *current_user_name;
+ 		temp = savestring (current_user_name);
+ 
+ 		goto add_string;
+ 	      }
+ 
+ 	    case 'h':
+ 	      {
+ 		extern char *current_host_name;
+ 		char *t_string, *index ();
+ 
+ 		temp = savestring (current_host_name);
+ 		if (t_string = index (temp, '.'))
+ 		  *t_string = '\0';
+ 		
+ 		goto add_string;
+ 	      }
+ 
+ 	    case '#':
+ 	      {
+ 		extern int current_command_number;
+ 		char number_buffer[20];
+ 		sprintf (number_buffer, "%d", current_command_number);
+ 		temp = savestring (number_buffer);
+ 		goto add_string;
+ 	      }
+ 
+ 	    case '!':
+ 	      {
+ 		extern int history_base, where_history ();
+ 		char number_buffer[20];
+ 
+ 		using_history ();
+ 		if (get_string_value ("HISTSIZE"))
+ 		  sprintf (number_buffer, "%d",
+ 			   history_base + where_history ());
+ 		else
+ 		  strcpy (number_buffer, "!");
+ 		temp = savestring (number_buffer);
+ 		goto add_string;
+ 	      }
+ 
+ 	    case '$':
+ 	      temp = savestring (geteuid () == 0 ? "#" : "$");
+ 	      goto add_string;
+ 
+ 	    case '\\':
+ 	      temp = savestring ("\\");
+ 	      goto add_string;
+ 
+ 	    default:
+ 	      temp = savestring ("\\ ");
+ 	      temp[1] = c;
+ 
+ 	    add_string:
+ 	      if (c)
+ 		string++;
+ 	      result =
+ 		(char *)sub_append_string (temp, result,
+ 					   &result_index, &result_size);
+ 	      temp = (char *)NULL; /* Free ()'ed in sub_append_string (). */
+ 	      result[result_index] = '\0';
+ 	      break;
+ 	    }
+ 	}
+       else
+ 	{
+ 	  while (3 + result_index > result_size)
+ 	    result = (char *)xrealloc (result, result_size += PROMPT_GROWTH);
+ 
+ 	  result[result_index++] = c;
+ 	  result[result_index] = '\0';
+ 	}
+     }
+ 
+   /* I don't really think that this is a good idea.  Do you? */
+   if (!find_variable ("NO_PROMPT_VARS"))
+     {
+       WORD_LIST *expand_string (), *list;
+       char *string_list ();
+ 
+       list = expand_string (result, 1);
+       free (result);
+       result = string_list (list);
+       dispose_words (list);
+     }
+ 
+   return (result);
+ }
+ 
+ /* Report a syntax error, and restart the parser.  Call here for fatal
+    errors. */
+ yyerror ()
+ {
+   report_syntax_error ((char *)NULL);
+   reset_parser ();
+ }
+ 
+ /* Report a syntax error with line numbers, etc.
+    Call here for recoverable errors.  If you have a message to print,
+    then place it in MESSAGE, otherwise pass NULL and this will figure
+    out an appropriate message for you. */
+ report_syntax_error (message)
+      char *message;
+ {
+   if (message)
+     {
+       if (!interactive)
+ 	{
+ 	  char *name = stream_name ? stream_name : "stdin";
+ 	  report_error ("%s:%d: `%s'", name, line_number, message);
+ 	}
+       else
+ 	report_error ("%s", message);
+ 
+       return;
+     }
+ 
+   if (shell_input_line && *shell_input_line)
+     {
+       char *error_token, *t = shell_input_line;
+       register int i = shell_input_line_index;
+       int token_end = 0;
+ 
+       if (!t[i] && i)
+ 	i--;
+ 
+       while (i && t[i] == ' ' || t[i] == '\t' || t[i] == '\n')
+ 	i--;
+ 
+       if (i)
+ 	token_end = i + 1;
+ 
+       while (i && !member (t[i], " \n\t;|&"))
+ 	i--;
+ 
+       while (i != token_end && member (t[i], " \n\t"))
+ 	i++;
+ 
+       if (token_end)
+ 	{
+ 	  error_token = (char *)alloca (1 + (token_end - i));
+ 	  strncpy (error_token, t + i, token_end - i);
+ 	  error_token[token_end - i] = '\0';
+ 
+ 	  report_error ("syntax error near `%s'", error_token);
+ 	}
+       else if ((i == 0) && (token_end == 0))    /* a 1-character token */
+ 	{
+ 	  error_token = (char *) alloca (2);
+ 	  strncpy(error_token, t + i, 1);
+ 	  error_token[1] = '\0';
+ 
+ 	  report_error ("syntax error near `%s'", error_token);
+ 	}
+ 
+       if (!interactive)
+ 	{
+ 	  char *temp = savestring (shell_input_line);
+ 	  char *name = stream_name ? stream_name : "stdin";
+ 	  int l = strlen (temp);
+ 
+ 	  while (l && temp[l - 1] == '\n')
+ 	    temp[--l] = '\0';
+ 
+ 	  report_error ("%s:%d: `%s'", name, line_number, temp);
+ 	  free (temp);
+ 	}
+     }
+   else
+     report_error ("Syntax error");
+ }
+ 
+ /* ??? Needed function. ??? We have to be able to discard the constructs
+    created during parsing.  In the case of error, we want to return
+    allocated objects to the memory pool.  In the case of no error, we want
+    to throw away the information about where the allocated objects live.
+    (dispose_command () will actually free the command. */
+ discard_parser_constructs (error_p)
+      int error_p;
+ {
+ /*   if (error_p) {
+      fprintf (stderr, "*");
+   } */
+ }
+    
+ /* Do that silly `type "bye" to exit' stuff.  You know, "ignoreeof". */
+ 
+ /* The number of times that we have encountered an EOF character without
+    another character intervening.  When this gets above the limit, the
+    shell terminates. */
+ int eof_encountered = 0;
+ 
+ /* The limit for eof_encountered. */
+ int eof_encountered_limit = 10;
+ 
+ /* If we have EOF as the only input unit, this user wants to leave
+    the shell.  If the shell is not interactive, then just leave.
+    Otherwise, if ignoreeof is set, and we haven't done this the
+    required number of times in a row, print a message. */
+ handle_eof_input_unit ()
+ {
+   extern int login_shell, EOF_Reached;
+ 
+   if (interactive)
+     {
+       /* If the user wants to "ignore" eof, then let her do so, kind of. */
+       if (find_variable ("ignoreeof") || find_variable ("IGNOREEOF"))
+ 	{
+ 	  if (eof_encountered < eof_encountered_limit)
+ 	    {
+ 	      fprintf (stderr, "Use \"%s\" to leave the shell.\n",
+ 		       login_shell ? "logout" : "exit");
+ 	      eof_encountered++;
+ 	      return;
+ 	    } 
+ 	}
+ 
+       /* In this case EOF should exit the shell.  Do it now. */
+       reset_parser ();
+       exit_builtin ((WORD_LIST *)NULL);
+     }
+   else
+     {
+       /* We don't write history files, etc., for non-interactive shells. */
+       EOF_Reached = 1;
+     }
+ }
+ short yyexca[] ={
+ -1, 1,
+ 	0, -1,
+ 	-2, 0,
+ 	};
+ # define YYNPROD 95
+ # define YYLAST 523
+ short yyact[]={
+ 
+    3,  16, 193, 116,  55,  37,  54,  99, 149, 186,
+  100,  95, 111,  33,  94,  93,  92,  66,  97,  69,
+   68,  23,  62,  22,  64,  81,  61,  53,  81,  52,
+   16,  50,  43,  42,  34, 197,  81, 172, 146,  81,
+  112, 142, 141,  85,  81,  81,  84,  81, 160, 177,
+   23,  81,  22, 195, 134,  16, 162, 150, 132, 134,
+  131, 113, 178,  79,  17, 130, 129, 198, 174, 133,
+  173,  91,  89, 116,  81,  23,  37,  22,  77, 120,
+   87,  16,  32,  86,  21,  49,  31,  20,  83,   7,
+  148,  10,  70,   6, 128, 127, 155,  41, 123,  37,
+   38,  23,  88,  22,  40,   9,   8,   2,  80,   1,
+    0,   0,  23,  21,  22,  90,   0,   0,   0,  23,
+    0,  22,   7,   7,   0,   0, 116,  71,  75,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,  21,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0, 175, 114, 115,  35,  36,   0, 183, 125,   0,
+    0,   7,   7,   7,  21, 103, 104, 105,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0, 143,  21, 145,  21,   0,   0,
+    7,   7,   0, 158, 159,  71,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0, 170,
+    0,   0,   0,   0,   0,   0,   0,   0,  13,  56,
+   57,  58,  59,  12,  60,  11,  14,  15,   0,   0,
+   19,   0,  18,  24,  98,   0,  25,  26,  27,  28,
+    0,  29,  30,  67,  65,  96,   4,  13,  35,  36,
+    0,  63,  12,  82,  11,  14,  15, 196,   0,  19,
+    0,  18,  24,   0,   0,  25,  26,  27,  28, 147,
+   29,  30,  13,   0,   5, 114, 115,  12,   0,  11,
+   14,  15, 151,   0,  19, 106,  18,  24, 107, 176,
+   25,  26,  27,  28, 194,  29,  30, 156,  13, 109,
+  154, 182, 124,  12,   0,  11,  14,  15, 156,  45,
+   19,   0,  18,  24,   0,   0,  25,  26,  27,  28,
+    0,  29,  30,  39,  24,   0,  44,  25,  26,  27,
+   28,  24,  29,  30,  25,  26,  27,  28,   0,  29,
+   30,  46,  47,  48,   0,  72,  73,  74,  51,   0,
+    0,   0,  76,  78,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0, 108,   0, 164,
+  165, 166, 167, 168, 169,   0,   0, 119,   0, 121,
+    0,   0,   0,   0,   0,   0, 110,   0,   0,   0,
+    0, 117, 118,   0,   0,   0,   0,   0,   0, 126,
+    0, 135, 136, 137, 138, 139, 140,   0,   0,   0,
+  144,   0,   0, 122,   0,   0,   0, 157,   0,   0,
+    0,   0, 165, 166, 164,   0,   0,   0,   0,   0,
+    0, 152, 153,   0,   0,   0,   0,   0, 171, 161,
+    0, 163,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0, 185,   0,   0,   0,   0, 188,
+  189, 190,   0,   0,   0,   0,   0,   0,   0,   0,
+    0, 184,   0,   0,   0, 187,   0,   0,   0, 191,
+  192,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   0, 199 };
+ short yypact[]={
+ 
+  -10,-1000,  76,-1000,  72,-1000, -25,-1000,  52,  59,
+ -1000,-238,-239,-1000,-1000,-1000,-1000,-1000,  45,-240,
+ -1000,-1000,-242,-244, -56,-245,-249, -21, -28,-251,
+ -252,-1000,-1000, -39, -39,-1000,-1000,-1000,-1000,-1000,
+   59,-1000,  19,-1000,-195,  41,-221,-224,  42,  39,
+   62, -54,-1000,-1000,-255,-256,-257,-260, -27, -38,
+ -261,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+ -119,-119,  41,  41,  41,-1000,  18,-1000,  29,-1000,
+ -1000,-1000,   2,-1000,-1000,-1000,-1000,-1000,  38,-1000,
+ -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+ -1000, -39, -39, -48, -48,-1000,-1000,-1000,  35,-1000,
+ -201,-1000,-1000,-1000,-1000,-1000,-1000,-226,-227,  64,
+ -1000,  64,-230,  -2,-1000,-1000,  37,-1000,-215,-1000,
+ -1000,-1000,-1000,-205,-1000,  41,  41,  41,  41,  41,
+   41,-1000,-1000,-1000,  64,-1000,-1000,-1000,-1000,-1000,
+ -1000,-1000,-231, -55,-1000,  27,-1000,  26,-1000,-1000,
+ -1000,-212,-1000,-196,-121,-121,-121, -51, -51,-1000,
+ -1000,  34,-1000,-1000,-1000,-262,-1000,-1000,-1000,-1000,
+ -1000,-1000,-1000,-1000,-277,  15,-1000,-206,  41,  41,
+   41,-233, -58,-1000,-1000,-1000,-1000,-1000,-1000,-1000 };
+ short yypgo[]={
+ 
+    0, 109,  88, 326, 108, 253, 107,  92, 106, 105,
+   64,  69,  87, 104,  91,  98,  96,  66,  95,  94,
+   65, 309,  90 };
+ short yyr1[]={
+ 
+    0,   1,   1,   1,   1,  15,  15,  12,  12,  12,
+   12,  12,  12,  12,  12,  12,  12,  12,  12,  12,
+   12,  12,  12,  12,  12,  12,  12,  14,  14,  13,
+   13,   8,   8,   2,   2,   2,   9,   9,   9,   9,
+    9,   9,   9,   9,   9,   9,   9,   9,   9,   9,
+    9,   9,   9,   9,   9,  10,  11,  11,  11,  19,
+   19,  20,  20,  18,  18,  17,  17,  16,  16,   3,
+    4,   4,   4,   4,   5,   5,   5,   5,   5,   5,
+    5,  22,  22,  22,  21,  21,   6,   6,   6,   7,
+    7,   7,   7,   7,   7 };
+ short yyr2[]={
+ 
+    0,   2,   1,   2,   1,   0,   2,   2,   2,   3,
+    3,   2,   3,   2,   3,   2,   3,   2,   3,   2,
+    3,   2,   3,   2,   3,   2,   2,   1,   1,   1,
+    2,   1,   2,   1,   1,   2,   6,   7,   7,  10,
+   10,   6,   7,   6,   5,   7,   6,   5,   5,   3,
+    1,   5,   6,   5,   3,   3,   4,   6,   5,   1,
+    2,   4,   4,   1,   2,   5,   5,   1,   3,   2,
+    1,   3,   3,   3,   4,   4,   4,   4,   4,   4,
+    1,   1,   1,   1,   0,   2,   1,   2,   2,   4,
+    4,   3,   3,   4,   1 };
+ short yychk[]={
+ 
+ -1000,  -1,  -6,  10, 256, 284,  -7,  -2,  -8,  -9,
+  -14, 264, 262, 257, 265, 266,  40, -10, 271, 269,
+  -12, 123,  62,  60, 272, 275, 276, 277, 278, 280,
+  281,  10,  10,  38,  59, 273, 274, 124, -14, 271,
+  -13, -12, 271, 271,  -3, -21,  -3,  -3,  -3,  40,
+  271,  -3, 271, 271,  62,  60, 275, 276, 277, 278,
+  280, 271, 271, 272,  45, 272,  45, 271, 271, 271,
+   -7,  -7, -21, -21, -21, -12, -21,  59, -21, 258,
+   -4,  10,  -5,  -2, 267, 267,  41,  41,  40,  10,
+  -10, 125, 271, 271, 271, 271, 272,  45, 272,  45,
+  271,  38,  59,  -7,  -7,  -7, 267, 270, -21, 270,
+   -3,  10,  38,  59, 273, 274, 124,  -3,  -3, -21,
+   41, -21,  -3, -15, 267, 123, -21, -18, -19, -17,
+  -20, 261, 259, -11, 260, -21, -21, -21, -21, -21,
+  -21, 268, 268, -10, -21, -10, 268, 271, -22,  10,
+   59, 284,  -3,  -3, 263, -16, 271, -21, -20, -17,
+  263,  -3, 261,  -3,  -5,  -5,  -5,  -5,  -5,  -5,
+  -10, -21, 268, 125,  41, 124, 263, 261, 258,  38,
+   59,  10, 267, 123,  -3, -21, 271,  -3, -21, -21,
+  -21,  -3,  -3, 279, 279, 259, -11, 268, 125,  -3 };
+ short yydef[]={
+ 
+    0,  -2,   0,   2,   0,   4,  86,  94,  33,  34,
+   31,   0,   0,  84,  84,  84,  84,  50,  27,   0,
+   28,  84,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   1,   3,  87,  88,  84,  84,  84,  32,  27,
+   35,  29,  84,  84,   0,   0,   0,   0,   0,   0,
+    0,   0,   7,   8,   0,   0,   0,   0,   0,   0,
+    0,  11,  13,  15,  23,  17,  21,  26,  19,  25,
+   91,  92,   0,   0,   0,  30,   0,  84,   0,  84,
+   69,  85,  70,  80,  84,  84,  49,  84,   0,  84,
+   54,  55,   9,  10,  12,  14,  16,  24,  18,  22,
+   20,   0,   0,  89,  90,  93,  84,   5,   0,  84,
+    0,  84,  84,  84,  84,  84,  84,   0,   0,   0,
+   84,   0,   0,   0,  84,  84,   0,  84,   0,  63,
+   59,  44,  84,   0,  84,  71,  72,  73,   0,   0,
+    0,  47,  48,  51,   0,  53,  36,   6,  84,  81,
+   82,  83,   0,   0,  41,   0,  67,   0,  60,  64,
+   43,   0,  46,   0,  78,  76,  77,  74,  75,  79,
+   52,   0,  37,  38,  84,   0,  42,  45,  84,  84,
+   84,  84,  84,  84,  61,  62,  68,  56,   0,   0,
+    0,   0,   0,  65,  66,  84,  58,  39,  40,  57 };
+ #ifndef lint
+ static char yaccpar_sccsid[] = "@(#)yaccpar	4.1	(Berkeley)	2/11/83";
+ #endif not lint
+ 
+ #
+ # define YYFLAG -1000
+ # define YYERROR goto yyerrlab
+ # define YYACCEPT return(0)
+ # define YYABORT return(1)
+ 
+ /*	parser for yacc output	*/
+ 
+ #ifdef YYDEBUG
+ int yydebug = 0; /* 1 for debugging */
+ #endif
+ YYSTYPE yyv[YYMAXDEPTH]; /* where the values are stored */
+ int yychar = -1; /* current input token number */
+ int yynerrs = 0;  /* number of errors */
+ short yyerrflag = 0;  /* error recovery flag */
+ 
+ yyparse() {
+ 
+ 	short yys[YYMAXDEPTH];
+ 	short yyj, yym;
+ 	register YYSTYPE *yypvt;
+ 	register short yystate, *yyps, yyn;
+ 	register YYSTYPE *yypv;
+ 	register short *yyxi;
+ 
+ 	yystate = 0;
+ 	yychar = -1;
+ 	yynerrs = 0;
+ 	yyerrflag = 0;
+ 	yyps= &yys[-1];
+ 	yypv= &yyv[-1];
+ 
+  yystack:    /* put a state and value onto the stack */
+ 
+ #ifdef YYDEBUG
+ 	if( yydebug  ) printf( "state %d, char 0%o\n", yystate, yychar );
+ #endif
+ 		if( ++yyps> &yys[YYMAXDEPTH] ) { yyerror( "yacc stack overflow" ); return(1); }
+ 		*yyps = yystate;
+ 		++yypv;
+ 		*yypv = yyval;
+ 
+  yynewstate:
+ 
+ 	yyn = yypact[yystate];
+ 
+ 	if( yyn<= YYFLAG ) goto yydefault; /* simple state */
+ 
+ 	if( yychar<0 ) if( (yychar=yylex())<0 ) yychar=0;
+ 	if( (yyn += yychar)<0 || yyn >= YYLAST ) goto yydefault;
+ 
+ 	if( yychk[ yyn=yyact[ yyn ] ] == yychar ){ /* valid shift */
+ 		yychar = -1;
+ 		yyval = yylval;
+ 		yystate = yyn;
+ 		if( yyerrflag > 0 ) --yyerrflag;
+ 		goto yystack;
+ 		}
+ 
+  yydefault:
+ 	/* default state action */
+ 
+ 	if( (yyn=yydef[yystate]) == -2 ) {
+ 		if( yychar<0 ) if( (yychar=yylex())<0 ) yychar = 0;
+ 		/* look through exception table */
+ 
+ 		for( yyxi=yyexca; (*yyxi!= (-1)) || (yyxi[1]!=yystate) ; yyxi += 2 ) ; /* VOID */
+ 
+ 		while( *(yyxi+=2) >= 0 ){
+ 			if( *yyxi == yychar ) break;
+ 			}
+ 		if( (yyn = yyxi[1]) < 0 ) return(0);   /* accept */
+ 		}
+ 
+ 	if( yyn == 0 ){ /* error */
+ 		/* error ... attempt to resume parsing */
+ 
+ 		switch( yyerrflag ){
+ 
+ 		case 0:   /* brand new error */
+ 
+ 			yyerror( "syntax error" );
+ 		yyerrlab:
+ 			++yynerrs;
+ 
+ 		case 1:
+ 		case 2: /* incompletely recovered error ... try again */
+ 
+ 			yyerrflag = 3;
+ 
+ 			/* find a state where "error" is a legal shift action */
+ 
+ 			while ( yyps >= yys ) {
+ 			   yyn = yypact[*yyps] + YYERRCODE;
+ 			   if( yyn>= 0 && yyn < YYLAST && yychk[yyact[yyn]] == YYERRCODE ){
+ 			      yystate = yyact[yyn];  /* simulate a shift of "error" */
+ 			      goto yystack;
+ 			      }
+ 			   yyn = yypact[*yyps];
+ 
+ 			   /* the current yyps has no shift onn "error", pop stack */
+ 
+ #ifdef YYDEBUG
+ 			   if( yydebug ) printf( "error recovery pops state %d, uncovers %d\n", *yyps, yyps[-1] );
+ #endif
+ 			   --yyps;
+ 			   --yypv;
+ 			   }
+ 
+ 			/* there is no state on the stack with an error shift ... abort */
+ 
+ 	yyabort:
+ 			return(1);
+ 
+ 
+ 		case 3:  /* no shift yet; clobber input char */
+ 
+ #ifdef YYDEBUG
+ 			if( yydebug ) printf( "error recovery discards char %d\n", yychar );
+ #endif
+ 
+ 			if( yychar == 0 ) goto yyabort; /* don't discard EOF, quit */
+ 			yychar = -1;
+ 			goto yynewstate;   /* try again in the same state */
+ 
+ 			}
+ 
+ 		}
+ 
+ 	/* reduction by production yyn */
+ 
+ #ifdef YYDEBUG
+ 		if( yydebug ) printf("reduce %d\n",yyn);
+ #endif
+ 		yyps -= yyr2[yyn];
+ 		yypvt = yypv;
+ 		yypv -= yyr2[yyn];
+ 		yyval = yypv[1];
+ 		yym=yyn;
+ 			/* consult goto table to find next state */
+ 		yyn = yyr1[yyn];
+ 		yyj = yypgo[yyn] + *yyps + 1;
+ 		if( yyj>=YYLAST || yychk[ yystate = yyact[yyj] ] != -yyn ) yystate = yyact[yypgo[yyn]];
+ 		switch(yym){
+ 			
+ case 1:
+ # line 78 "parse.y"
+ {
+ 			  /* Case of regular command.  Discard the error
+ 			     safety net,and return the command just parsed. */
+ 			  global_command = yypvt[-1].command;
+ 			  eof_encountered = 0;
+ 			  discard_parser_constructs (0);
+ 			  YYACCEPT;
+ 			} break;
+ case 2:
+ # line 87 "parse.y"
+ {
+ 			  /* Case of regular command, but not a very
+ 			     interesting one.  Return a NULL command. */
+ 			  global_command = (COMMAND *)NULL;
+ 			  YYACCEPT;
+ 			} break;
+ case 3:
+ # line 95 "parse.y"
+ {
+ 			  /* Error during parsing.  Return NULL command. */
+ 			  global_command = (COMMAND *)NULL;
+ 			  eof_encountered = 0;
+ 			  discard_parser_constructs (1);
+ 			  if (interactive)
+ 			    YYACCEPT;
+ 			  else
+ 			    YYABORT;
+ 			} break;
+ case 4:
+ # line 107 "parse.y"
+ {
+ 			  /* Case of EOF seen by itself.  Do ignoreeof or 
+ 			     not. */
+ 			  global_command = (COMMAND *)NULL;
+ 			  handle_eof_input_unit ();
+ 			  YYACCEPT;
+ 			} break;
+ case 5:
+ # line 117 "parse.y"
+ { yyval.word_list = NULL; } break;
+ case 6:
+ # line 119 "parse.y"
+ { yyval.word_list = make_word_list (yypvt[-0].word, yypvt[-1].word_list); } break;
+ case 7:
+ # line 123 "parse.y"
+ { yyval.redirect = make_redirection ( 1, r_output_direction, yypvt[-0].word); } break;
+ case 8:
+ # line 125 "parse.y"
+ { yyval.redirect = make_redirection ( 0, r_input_direction, yypvt[-0].word); } break;
+ case 9:
+ # line 127 "parse.y"
+ { yyval.redirect = make_redirection (yypvt[-2].number, r_output_direction, yypvt[-0].word); } break;
+ case 10:
+ # line 129 "parse.y"
+ { yyval.redirect = make_redirection (yypvt[-2].number, r_input_direction, yypvt[-0].word); } break;
+ case 11:
+ # line 131 "parse.y"
+ { yyval.redirect = make_redirection ( 1, r_appending_to, yypvt[-0].word); } break;
+ case 12:
+ # line 133 "parse.y"
+ { yyval.redirect = make_redirection (yypvt[-2].number, r_appending_to, yypvt[-0].word); } break;
+ case 13:
+ # line 135 "parse.y"
+ { yyval.redirect = make_redirection ( 0, r_reading_until, yypvt[-0].word); } break;
+ case 14:
+ # line 137 "parse.y"
+ { yyval.redirect = make_redirection (yypvt[-2].number, r_reading_until, yypvt[-0].word); } break;
+ case 15:
+ # line 139 "parse.y"
+ { yyval.redirect = make_redirection ( 0, r_duplicating, yypvt[-0].number); } break;
+ case 16:
+ # line 141 "parse.y"
+ { yyval.redirect = make_redirection (yypvt[-2].number, r_duplicating, yypvt[-0].number); } break;
+ case 17:
+ # line 143 "parse.y"
+ { yyval.redirect = make_redirection ( 1, r_duplicating, yypvt[-0].number); } break;
+ case 18:
+ # line 145 "parse.y"
+ { yyval.redirect = make_redirection (yypvt[-2].number, r_duplicating, yypvt[-0].number); } break;
+ case 19:
+ # line 147 "parse.y"
+ { yyval.redirect = make_redirection ( 0, r_deblank_reading_until, yypvt[-0].word); } break;
+ case 20:
+ # line 149 "parse.y"
+ { yyval.redirect = make_redirection (yypvt[-2].number, r_deblank_reading_until, yypvt[-0].word); } break;
+ case 21:
+ # line 151 "parse.y"
+ { yyval.redirect = make_redirection ( 1, r_close_this, 0); } break;
+ case 22:
+ # line 154 "parse.y"
+ { yyval.redirect = make_redirection (yypvt[-2].number, r_close_this, 0); } break;
+ case 23:
+ # line 156 "parse.y"
+ { yyval.redirect = make_redirection ( 0, r_close_this, 0); } break;
+ case 24:
+ # line 158 "parse.y"
+ { yyval.redirect = make_redirection (yypvt[-2].number, r_close_this, 0); } break;
+ case 25:
+ # line 160 "parse.y"
+ { yyval.redirect = make_redirection ( 1, r_err_and_out, yypvt[-0].word); } break;
+ case 26:
+ # line 162 "parse.y"
+ { yyval.redirect = make_redirection ( 1, r_err_and_out, yypvt[-0].word); } break;
+ case 27:
+ # line 166 "parse.y"
+ { yyval.element.word = yypvt[-0].word; yyval.element.redirect = 0; } break;
+ case 28:
+ # line 168 "parse.y"
+ { yyval.element.redirect = yypvt[-0].redirect; yyval.element.word = 0; } break;
+ case 30:
+ # line 173 "parse.y"
+ { yypvt[-1].redirect->next = yypvt[-0].redirect; yyval.redirect = yypvt[-1].redirect; } break;
+ case 31:
+ # line 177 "parse.y"
+ { yyval.command = make_simple_command (&(yypvt[-0].element), NULL); } break;
+ case 32:
+ # line 179 "parse.y"
+ { yyval.command = make_simple_command (&(yypvt[-0].element), yypvt[-1].command); } break;
+ case 33:
+ # line 183 "parse.y"
+ { yyval.command = clean_simple_command (yypvt[-0].command); } break;
+ case 34:
+ # line 185 "parse.y"
+ { yyval.command = yypvt[-0].command; } break;
+ case 35:
+ # line 188 "parse.y"
+ { yyval.command->redirects = yypvt[-0].redirect; yyval.command = yypvt[-1].command; } break;
+ case 36:
+ # line 192 "parse.y"
+ { yyval.command = make_for_command (yypvt[-4].word, (WORD_LIST *)add_string_to_list ("$@", NULL), yypvt[-1].command); } break;
+ case 37:
+ # line 194 "parse.y"
+ { yyval.command = make_for_command (yypvt[-5].word, (WORD_LIST *)add_string_to_list ("$@", NULL), yypvt[-1].command); } break;
+ case 38:
+ # line 196 "parse.y"
+ { yyval.command = make_for_command (yypvt[-5].word, (WORD_LIST *)add_string_to_list ("$@", NULL), yypvt[-1].command); } break;
+ case 39:
+ # line 198 "parse.y"
+ { yyval.command = make_for_command (yypvt[-8].word, (WORD_LIST *)reverse_list (yypvt[-5].word_list), yypvt[-1].command); } break;
+ case 40:
+ # line 200 "parse.y"
+ { yyval.command = make_for_command (yypvt[-8].word, (WORD_LIST *)reverse_list (yypvt[-5].word_list), yypvt[-1].command); } break;
+ case 41:
+ # line 203 "parse.y"
+ { yyval.command = make_case_command (yypvt[-4].word, NULL); } break;
+ case 42:
+ # line 205 "parse.y"
+ { yyval.command = make_case_command (yypvt[-5].word, yypvt[-2].pattern); } break;
+ case 43:
+ # line 207 "parse.y"
+ { report_syntax_error ("Inserted `;;'");
+ 			  yyval.command = make_case_command (yypvt[-4].word, yypvt[-1].pattern); } break;
+ case 44:
+ # line 211 "parse.y"
+ { yyval.command = make_if_command (yypvt[-3].command, yypvt[-1].command, NULL); } break;
+ case 45:
+ # line 213 "parse.y"
+ { yyval.command = make_if_command (yypvt[-5].command, yypvt[-3].command, yypvt[-1].command); } break;
+ case 46:
+ # line 215 "parse.y"
+ { yyval.command = make_if_command (yypvt[-4].command, yypvt[-2].command, yypvt[-1].command); } break;
+ case 47:
+ # line 218 "parse.y"
+ { yyval.command = make_while_command (yypvt[-3].command, yypvt[-1].command); } break;
+ case 48:
+ # line 220 "parse.y"
+ { yyval.command = make_until_command (yypvt[-3].command, yypvt[-1].command); } break;
+ case 49:
+ # line 223 "parse.y"
+ { yypvt[-1].command->subshell = 1; yyval.command = yypvt[-1].command; } break;
+ case 50:
+ # line 226 "parse.y"
+ { yyval.command = yypvt[-0].command; } break;
+ case 51:
+ # line 229 "parse.y"
+ { yyval.command = make_function_def (yypvt[-4].word, yypvt[-0].command); } break;
+ case 52:
+ # line 232 "parse.y"
+ { yyval.command = make_function_def (yypvt[-4].word, yypvt[-0].command); } break;
+ case 53:
+ # line 235 "parse.y"
+ { yyval.command = make_function_def (yypvt[-3].word, yypvt[-0].command); } break;
+ case 54:
+ # line 238 "parse.y"
+ { yyval.command = make_function_def (yypvt[-1].word, yypvt[-0].command); } break;
+ case 55:
+ # line 242 "parse.y"
+ { yyval.command = make_group_command (yypvt[-1].command); } break;
+ case 56:
+ # line 246 "parse.y"
+ { yyval.command = make_if_command (yypvt[-2].command, yypvt[-0].command, NULL); } break;
+ case 57:
+ # line 248 "parse.y"
+ { yyval.command = make_if_command (yypvt[-4].command, yypvt[-2].command, yypvt[-0].command); } break;
+ case 58:
+ # line 250 "parse.y"
+ { yyval.command = make_if_command (yypvt[-3].command, yypvt[-1].command, yypvt[-0].command); } break;
+ case 60:
+ # line 256 "parse.y"
+ { yypvt[-0].pattern->next = yypvt[-1].pattern; yyval.pattern = yypvt[-0].pattern; } break;
+ case 61:
+ # line 260 "parse.y"
+ { yyval.pattern = make_pattern_list (yypvt[-2].word_list, yypvt[-0].command); } break;
+ case 62:
+ # line 262 "parse.y"
+ { yyval.pattern = make_pattern_list (yypvt[-2].word_list, NULL); } break;
+ case 64:
+ # line 268 "parse.y"
+ { yypvt[-0].pattern->next = yypvt[-1].pattern; yyval.pattern = yypvt[-0].pattern; } break;
+ case 65:
+ # line 272 "parse.y"
+ { yyval.pattern = make_pattern_list (yypvt[-3].word_list, yypvt[-1].command); } break;
+ case 66:
+ # line 274 "parse.y"
+ { yyval.pattern = make_pattern_list (yypvt[-3].word_list, NULL); } break;
+ case 67:
+ # line 278 "parse.y"
+ { yyval.word_list = make_word_list (yypvt[-0].word, NULL); } break;
+ case 68:
+ # line 280 "parse.y"
+ { yyval.word_list = make_word_list (yypvt[-0].word, yypvt[-2].word_list); } break;
+ case 69:
+ # line 289 "parse.y"
+ { yyval.command = yypvt[-0].command; } break;
+ case 72:
+ # line 295 "parse.y"
+ { yyval.command = command_connect (yypvt[-2].command, 0, '&'); } break;
+ case 74:
+ # line 301 "parse.y"
+ { yyval.command = command_connect (yypvt[-3].command, yypvt[-0].command, AND_AND); } break;
+ case 75:
+ # line 303 "parse.y"
+ { yyval.command = command_connect (yypvt[-3].command, yypvt[-0].command, OR_OR); } break;
+ case 76:
+ # line 305 "parse.y"
+ { yyval.command = command_connect (yypvt[-3].command, yypvt[-0].command, '&'); } break;
+ case 77:
+ # line 307 "parse.y"
+ { yyval.command = command_connect (yypvt[-3].command, yypvt[-0].command, ';'); } break;
+ case 78:
+ # line 309 "parse.y"
+ { yyval.command = command_connect (yypvt[-3].command, yypvt[-0].command, ';'); } break;
+ case 79:
+ # line 311 "parse.y"
+ { yyval.command = command_connect (yypvt[-3].command, yypvt[-0].command, '|'); } break;
+ case 87:
+ # line 333 "parse.y"
+ { yyval.command = command_connect (yypvt[-1].command, (COMMAND *)NULL, '&'); } break;
+ case 89:
+ # line 338 "parse.y"
+ { yyval.command = command_connect (yypvt[-3].command, yypvt[-0].command, AND_AND); } break;
+ case 90:
+ # line 340 "parse.y"
+ { yyval.command = command_connect (yypvt[-3].command, yypvt[-0].command, OR_OR); } break;
+ case 91:
+ # line 342 "parse.y"
+ { yyval.command = command_connect (yypvt[-2].command, yypvt[-0].command, '&'); } break;
+ case 92:
+ # line 344 "parse.y"
+ { yyval.command = command_connect (yypvt[-2].command, yypvt[-0].command, ';'); } break;
+ case 93:
+ # line 346 "parse.y"
+ { yyval.command = command_connect (yypvt[-3].command, yypvt[-0].command, '|'); } break; 
+ 		}
+ 		goto yystack;  /* stack new state and value */
+ 
+ 	}
+ 
-- 
Jim Paradis                  UUCP:  harvard!m2c!jjmhome!acestes!paradis
9 Carlstad St.               AT&T:  (508) 792-3810
Worcester, MA 01607-1569     ICBM:  42deg 13' 52",  71deg 47' 51"

paradis@acestes.UUCP (Jim Paradis) (03/12/91)

This is part 3 of the bash patches for MINIX.

You should be sitting in the "readline" subdirectory of the main bash
source directory when you apply these patches

-------------8<---- cut here ---------8<---- cut here ----8<-----------

*** bash-1.05/readline/Makefile	Sat Feb 17 11:00:42 1990
--- minix_bash/readline/Makefile	Thu Nov  1 23:00:52 1990
***************
*** 20,25 ****
--- 20,26 ----
  
  # Define SYSV as -DSYSV if you are using a System V operating system.
  #SYSV = -DSYSV
+ MINIX = -DMINIX
  
  # HP-UX compilation requires the BSD library.
  #LOCAL_LIBS = -lBSD
***************
*** 33,39 ****
  
  DEBUG_FLAGS = -g
  LDFLAGS = $(DEBUG_FLAGS) 
! CFLAGS = $(DEBUG_FLAGS) $(TYPE) $(SYSV) -I.
  
  # A good alternative is gcc -traditional.
  #CC = gcc -traditional
--- 34,40 ----
  
  DEBUG_FLAGS = -g
  LDFLAGS = $(DEBUG_FLAGS) 
! CFLAGS = $(DEBUG_FLAGS) $(TYPE) $(SYSV) $(MINIX) -I.
  
  # A good alternative is gcc -traditional.
  #CC = gcc -traditional
***************
*** 69,87 ****
  
  readline.o:	readline.h chardefs.h  keymaps.h history.h readline.c vi_mode.c
  	$(CC) -c $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \
! 		$(LOCAL_INCLUDES) $*.c
  
  history.o:	history.c history.h
  	$(CC) -c $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \
! 		$(LOCAL_INCLUDES) $*.c
  
  funmap.o:	readline.h
  	$(CC) -c $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \
! 		$(LOCAL_INCLUDES) $*.c
  
  keymaps.o:	emacs_keymap.c vi_keymap.c keymaps.h chardefs.h keymaps.c
  	$(CC) -c $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \
! 		 $(LOCAL_INCLUDES) $*.c
  
  libtest:	libreadline.a libtest.c
  		$(CC) -o libtest $(CFLAGS) $(CPPFLAGS) -L. libtest.c -lreadline -ltermcap
--- 70,88 ----
  
  readline.o:	readline.h chardefs.h  keymaps.h history.h readline.c vi_mode.c
  	$(CC) -c $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \
! 		$(LOCAL_INCLUDES) readline.c
  
  history.o:	history.c history.h
  	$(CC) -c $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \
! 		$(LOCAL_INCLUDES) history.c
  
  funmap.o:	readline.h
  	$(CC) -c $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \
! 		$(LOCAL_INCLUDES) funmap.c
  
  keymaps.o:	emacs_keymap.c vi_keymap.c keymaps.h chardefs.h keymaps.c
  	$(CC) -c $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \
! 		 $(LOCAL_INCLUDES) keymaps.c
  
  libtest:	libreadline.a libtest.c
  		$(CC) -o libtest $(CFLAGS) $(CPPFLAGS) -L. libtest.c -lreadline -ltermcap

*** bash-1.05/readline/readline.c	Sun Feb 25 11:33:06 1990
--- minix_bash/readline/readline.c	Fri Nov  2 00:11:20 1990
***************
*** 33,39 ****
  #include <stdio.h>
  #include <sys/types.h>
  #include <fcntl.h>
! #include <sys/file.h>
  #include <signal.h>
  
  #ifdef __GNUC__
--- 33,41 ----
  #include <stdio.h>
  #include <sys/types.h>
  #include <fcntl.h>
! #ifndef MINIX
! #include <sys/file.h>
! #endif /* MINIX */
  #include <signal.h>
  
  #ifdef __GNUC__
***************
*** 68,74 ****
  
  #define HACK_TERMCAP_MOTION
  
! #ifndef SYSV
  #include <sys/dir.h>
  #else  /* SYSV */
  #if defined (xenix)
--- 70,76 ----
  
  #define HACK_TERMCAP_MOTION
  
! #if !defined(SYSV) && !defined(MINIX)
  #include <sys/dir.h>
  #else  /* SYSV */
  #if defined (xenix)
***************
*** 200,206 ****
  static FILE *in_stream, *out_stream;
  
  /* The names of the streams that we do input and output to. */
! FILE *rl_instream = stdin, *rl_outstream = stdout;
  
  /* Non-zero means echo characters as they are read. */
  int readline_echoing_p = 1;
--- 202,208 ----
  static FILE *in_stream, *out_stream;
  
  /* The names of the streams that we do input and output to. */
! FILE *rl_instream = (FILE*)0, *rl_outstream = (FILE*)0;
  
  /* Non-zero means echo characters as they are read. */
  int readline_echoing_p = 1;
***************
*** 268,277 ****
  readline (prompt)
       char *prompt;
  {
-   static rl_prep_terminal (), rl_deprep_terminal ();
    char *readline_internal ();
    char *value;
  
    rl_prompt = prompt;
  
    /* If we are at EOF return a NULL string. */
--- 270,283 ----
  readline (prompt)
       char *prompt;
  {
    char *readline_internal ();
    char *value;
  
+   if(!rl_instream) {
+ 	rl_instream = stdin;
+ 	rl_outstream = stdout;
+   }
+ 
    rl_prompt = prompt;
  
    /* If we are at EOF return a NULL string. */
***************
*** 314,319 ****
--- 320,330 ----
  {
    int lastc, c, eof_found;
  
+   if(!rl_instream) {
+ 	rl_instream = stdin;
+ 	rl_outstream = stdout;
+   }
+ 
    in_stream = rl_instream; out_stream = rl_outstream;
    lastc = eof_found = 0;
  
***************
*** 468,474 ****
       int sig, code;
       struct sigcontext *scp;
  {
-   static rl_prep_terminal (), rl_deprep_terminal ();
  
    switch (sig)
      {
--- 479,484 ----
***************
*** 492,498 ****
        rl_pending_input = 0;
  
        kill (getpid (), sig);
!       sigsetmask (0);
  
        rl_prep_terminal ();
        rl_set_signals ();
--- 502,510 ----
        rl_pending_input = 0;
  
        kill (getpid (), sig);
! #ifndef MINIX
!       sigsetmask (0);
! #endif /* MINIX */
  
        rl_prep_terminal ();
        rl_set_signals ();
***************
*** 631,639 ****
  
    if (result == -1)
      {
!       fcntl (tty, F_SETFL, O_NDELAY);
!       chars_avail = read (tty, &input, 1);
!       fcntl (tty, F_SETFL, 0);
        if (chars_avail == -1 && errno == EAGAIN)
  	return;
      }
--- 643,655 ----
  
    if (result == -1)
      {
! #ifndef MINIX
!       fcntl (tty, F_SETFL, O_NDELAY);
! #endif /* MINIX */
!       chars_avail = read (tty, &input, 1);
! #ifndef MINIX
!       fcntl (tty, F_SETFL, 0);
! #endif /* MINIX */
        if (chars_avail == -1 && errno == EAGAIN)
  	return;
      }
***************
*** 677,683 ****
      }
    else
      {
!       static int next_macro_key ();
  
        /* If input is coming from a macro, then use that. */
        if (c = next_macro_key ())
--- 693,699 ----
      }
    else
      {
!       int next_macro_key ();
  
        /* If input is coming from a macro, then use that. */
        if (c = next_macro_key ())
***************
*** 715,721 ****
  }
  
  /* I'm beginning to hate the declaration rules for various compilers. */
! static void add_macro_char ();
  
  /* Do the command associated with KEY in MAP.
     If the associated command is really a keymap, then read
--- 731,737 ----
  }
  
  /* I'm beginning to hate the declaration rules for various compilers. */
! void add_macro_char ();
  
  /* Do the command associated with KEY in MAP.
     If the associated command is really a keymap, then read
***************
*** 785,791 ****
      case ISMACR:
        if (map[key].function != (Function *)NULL)
  	{
! 	  static with_macro_input ();
  	  char *macro = savestring ((char *)map[key].function);
  
  	  with_macro_input (macro);
--- 801,807 ----
      case ISMACR:
        if (map[key].function != (Function *)NULL)
  	{
! 	  int with_macro_input ();
  	  char *macro = savestring ((char *)map[key].function);
  
  	  with_macro_input (macro);
***************
*** 836,849 ****
  struct saved_macro *macro_list = (struct saved_macro *)NULL;
  
  /* Forward declarations of static functions.  Thank you C. */
! static void push_executing_macro (), pop_executing_macro ();
  
  /* This one has to be declared earlier in the file. */
  /* static void add_macro_char (); */
  
  /* Set up to read subsequent input from STRING.
     STRING is free ()'ed when we are done with it. */
- static
  with_macro_input (string)
       char *string;
  {
--- 852,864 ----
  struct saved_macro *macro_list = (struct saved_macro *)NULL;
  
  /* Forward declarations of static functions.  Thank you C. */
! void push_executing_macro (), pop_executing_macro ();
  
  /* This one has to be declared earlier in the file. */
  /* static void add_macro_char (); */
  
  /* Set up to read subsequent input from STRING.
     STRING is free ()'ed when we are done with it. */
  with_macro_input (string)
       char *string;
  {
***************
*** 854,860 ****
  
  /* Return the next character available from a macro, or 0 if
     there are no macro characters. */
! static int
  next_macro_key ()
  {
    if (!executing_macro)
--- 869,875 ----
  
  /* Return the next character available from a macro, or 0 if
     there are no macro characters. */
! int
  next_macro_key ()
  {
    if (!executing_macro)
***************
*** 870,876 ****
  }
  
  /* Save the currently executing macro on a stack of saved macros. */
! static void
  push_executing_macro ()
  {
    struct saved_macro *saver;
--- 885,891 ----
  }
  
  /* Save the currently executing macro on a stack of saved macros. */
! void
  push_executing_macro ()
  {
    struct saved_macro *saver;
***************
*** 885,891 ****
  
  /* Discard the current macro, replacing it with the one
     on the top of the stack of saved macros. */
! static void
  pop_executing_macro ()
  {
    if (executing_macro)
--- 900,906 ----
  
  /* Discard the current macro, replacing it with the one
     on the top of the stack of saved macros. */
! void
  pop_executing_macro ()
  {
    if (executing_macro)
***************
*** 905,911 ****
  }
  
  /* Add a character to the macro being built. */
! static void
  add_macro_char (c)
       int c;
  {
--- 920,926 ----
  }
  
  /* Add a character to the macro being built. */
! void
  add_macro_char (c)
       int c;
  {
***************
*** 1026,1031 ****
--- 1041,1051 ----
  /* Initialize the entire state of the world. */
  readline_initialize_everything ()
  {
+   if(!rl_instream) {
+ 	rl_instream = stdin;
+ 	rl_outstream = stdout;
+   }
+ 
    /* Find out if we are running in Emacs. */
    running_in_emacs = (char *)getenv ("EMACS");
  
***************
*** 1065,1071 ****
  
  #ifdef NEW_TTY_DRIVER
    struct sgttyb ttybuff;
!   int tty = fileno (rl_instream);
  
    if (ioctl (tty, TIOCGETP, &ttybuff) != -1)
      {
--- 1085,1098 ----
  
  #ifdef NEW_TTY_DRIVER
    struct sgttyb ttybuff;
! 
!   int tty;
! 
!   if(!rl_instream) {
! 	rl_instream = stdin;
! 	rl_outstream = stdout;
!   }
!   tty = fileno (rl_instream);
  
    if (ioctl (tty, TIOCGETP, &ttybuff) != -1)
      {
***************
*** 1269,1278 ****
     so; what is the advantage in producing better code if we can't use it? */
  /* The following two declarations belong inside the
     function block, not here. */
! static void move_cursor_relative ();
! static void output_some_chars ();
! static void output_character_function ();
! static int compare_strings ();
  
  /* Basic redisplay algorithm. */
  rl_redisplay ()
--- 1296,1305 ----
     so; what is the advantage in producing better code if we can't use it? */
  /* The following two declarations belong inside the
     function block, not here. */
! void move_cursor_relative ();
! void output_some_chars ();
! void output_character_function ();
! int compare_strings ();
  
  /* Basic redisplay algorithm. */
  rl_redisplay ()
***************
*** 1485,1491 ****
     no differences, as well as for end of line additions must be handeled.
  
     Could be made even smarter, but this works well enough */
- static
  update_line (old, new, current_line)
       register char *old, *new;
       int current_line;
--- 1512,1517 ----
***************
*** 1632,1638 ****
  /* Move the cursor from last_c_pos to NEW, which are buffer indices.
     DATA is the contents of the screen line of interest; i.e., where
     the movement is being done. */
! static void
  move_cursor_relative (new, data)
       int new;
       char *data;
--- 1658,1664 ----
  /* Move the cursor from last_c_pos to NEW, which are buffer indices.
     DATA is the contents of the screen line of interest; i.e., where
     the movement is being done. */
! void
  move_cursor_relative (new, data)
       int new;
       char *data;
***************
*** 1888,1894 ****
  }
  
  /* A function for the use of tputs () */
! static void
  output_character_function (c)
       int c;
  {
--- 1914,1920 ----
  }
  
  /* A function for the use of tputs () */
! void
  output_character_function (c)
       int c;
  {
***************
*** 1896,1902 ****
  }
  
  /* Write COUNT characters from STRING to the output stream. */
! static void
  output_some_chars (string, count)
       char *string;
       int count;
--- 1922,1928 ----
  }
  
  /* Write COUNT characters from STRING to the output stream. */
! void
  output_some_chars (string, count)
       char *string;
       int count;
***************
*** 1906,1912 ****
  
  
  /* Delete COUNT characters from the display line. */
- static
  delete_chars (count)
       int count;
  {
--- 1932,1937 ----
***************
*** 1928,1934 ****
  }
  
  /* Insert COUNT character from STRING to the output stream. */
- static
  insert_some_chars (string, count)
       char *string;
       int count;
--- 1953,1958 ----
***************
*** 2030,2042 ****
  static struct tchars original_tchars;
  
  /* Local special characters.  This has the interrupt characters in it. */
! static struct ltchars original_ltchars;
  
  /* We use this to get and set the tty_flags. */
  static struct sgttyb the_ttybuff;
  
  /* Put the terminal in CBREAK mode so that we can detect key presses. */
- static
  rl_prep_terminal ()
  {
    int tty = fileno (rl_instream);
--- 2054,2067 ----
  static struct tchars original_tchars;
  
  /* Local special characters.  This has the interrupt characters in it. */
! #ifdef TIOCGLTC
! static struct ltchars original_ltchars;
! #endif 
  
  /* We use this to get and set the tty_flags. */
  static struct sgttyb the_ttybuff;
  
  /* Put the terminal in CBREAK mode so that we can detect key presses. */
  rl_prep_terminal ()
  {
    int tty = fileno (rl_instream);
***************
*** 2116,2132 ****
  
    the_ttybuff.sg_flags &= ~ECHO;
    the_ttybuff.sg_flags |= CBREAK;
!   ioctl (tty, TIOCSETN, &the_ttybuff);
  }
  
  /* Restore the terminal to its original state. */
- static
  rl_deprep_terminal ()
  {
    int tty = fileno (rl_instream);
  
    the_ttybuff.sg_flags = original_tty_flags;
!   ioctl (tty, TIOCSETN, &the_ttybuff);
    readline_echoing_p = 1;
  
  #if defined (TIOCLGET) && defined (LPASS8)
--- 2141,2164 ----
  
    the_ttybuff.sg_flags &= ~ECHO;
    the_ttybuff.sg_flags |= CBREAK;
! #ifdef TIOCSETN
!   ioctl (tty, TIOCSETN, &the_ttybuff);
! #else
!   ioctl (tty, TIOCSETP, &the_ttybuff);
! #endif
  }
  
  /* Restore the terminal to its original state. */
  rl_deprep_terminal ()
  {
    int tty = fileno (rl_instream);
  
    the_ttybuff.sg_flags = original_tty_flags;
! #ifdef TIOCSETN
!   ioctl (tty, TIOCSETN, &the_ttybuff);
! #else
!   ioctl (tty, TIOCSETP, &the_ttybuff);
! #endif
    readline_echoing_p = 1;
  
  #if defined (TIOCLGET) && defined (LPASS8)
***************
*** 2154,2160 ****
  
  static struct termio otio;
  
- static
  rl_prep_terminal ()
  {
    int tty = fileno (rl_instream);
--- 2186,2191 ----
***************
*** 2178,2184 ****
    ioctl (tty, TCXONC, 1);	/* Simulate a ^Q. */
  }
  
- static
  rl_deprep_terminal ()
  {
    int tty = fileno (rl_instream);
--- 2209,2214 ----
***************
*** 5190,5196 ****
  {
    extern char *possible_control_prefixes[], *possible_meta_prefixes[];
    char *rindex (), *funname, *kname;
!   static int substring_member_of_array ();
    register int c;
    int key, i;
  
--- 5220,5226 ----
  {
    extern char *possible_control_prefixes[], *possible_meta_prefixes[];
    char *rindex (), *funname, *kname;
!   int substring_member_of_array ();
    register int c;
    int key, i;
  
***************
*** 5411,5421 ****
  /* **************************************************************** */
  
  /* Return non-zero if any members of ARRAY are a substring in STRING. */
! static int
  substring_member_of_array (string, array)
       char *string, **array;
  {
!   static char *strindex ();
  
    while (*array)
      {
--- 5441,5451 ----
  /* **************************************************************** */
  
  /* Return non-zero if any members of ARRAY are a substring in STRING. */
! int
  substring_member_of_array (string, array)
       char *string, **array;
  {
!   char *strindex ();
  
    while (*array)
      {
***************
*** 5466,5472 ****
  
  /* Determine if s2 occurs in s1.  If so, return a pointer to the
     match in s1.  The compare is case insensitive. */
! static char *
  strindex (s1, s2)
       register char *s1, *s2;
  {
--- 5496,5502 ----
  
  /* Determine if s2 occurs in s1.  If so, return a pointer to the
     match in s1.  The compare is case insensitive. */
! char *
  strindex (s1, s2)
       register char *s1, *s2;
  {

-- 
Jim Paradis                  UUCP:  harvard!m2c!jjmhome!acestes!paradis
9 Carlstad St.               AT&T:  (508) 792-3810
Worcester, MA 01607-1569     ICBM:  42deg 13' 52",  71deg 47' 51"

paradis@acestes.UUCP (Jim Paradis) (03/12/91)

This is part 4 of the bash patches for MINIX.

You should be sitting in the "alloc_file" subdirectory of the main bash
source directory when you apply these patches

-------------8<---- cut here ---------8<---- cut here ----8<-----------
*** bash-1.05/alloc-files/getpagesize.h	Mon Nov  7 10:49:04 1988
--- minix_bash/alloc-files/getpagesize.h	Thu Nov  1 22:25:58 1990
***************
*** 6,12 ****
  
  #ifndef HAVE_GETPAGESIZE
  
! #include <sys/param.h>
  
  #ifdef EXEC_PAGESIZE
  #define getpagesize() EXEC_PAGESIZE
--- 6,16 ----
  
  #ifndef HAVE_GETPAGESIZE
  
! #ifdef MINIX
! #define NBPC 4096
! #else MINIX
! #include <sys/param.h>
! #endif /* MINIX */
  
  #ifdef EXEC_PAGESIZE
  #define getpagesize() EXEC_PAGESIZE

*** bash-1.05/alloc-files/malloc.c	Wed Feb 28 07:50:36 1990
--- minix_bash/alloc-files/malloc.c	Thu Nov  1 23:42:48 1990
***************
*** 167,173 ****
  
  #ifndef BSD42
  #ifndef SYSV
! #include <sys/vlimit.h>		/* warn the user when near the end */
  #endif /* not SYSV */
  #else /* if BSD42 */
  #include <sys/time.h>
--- 167,175 ----
  
  #ifndef BSD42
  #ifndef SYSV
! #ifndef MINIX
! #include <sys/vlimit.h>		/* warn the user when near the end */
! #endif /* not MINIX */
  #endif /* not SYSV */
  #else /* if BSD42 */
  #include <sys/time.h>
***************
*** 194,200 ****
  				     being the distance to the true
  				     beginning of the block.  */
  
! extern char etext;
  
  /* These two are for user programs to look at, when they are interested.  */
  
--- 196,204 ----
  				     being the distance to the true
  				     beginning of the block.  */
  
! #ifndef MINIX
! extern char etext;
! #endif /* MINIX */
  
  /* These two are for user programs to look at, when they are interested.  */
  
***************
*** 329,334 ****
--- 333,339 ----
  #endif
  #endif
  
+ #ifndef MINIX
    if (!data_space_start)
      {
        data_space_start = start_of_data ();
***************
*** 336,341 ****
--- 341,347 ----
  
    if (lim_data == 0)
      get_lim_data ();
+ #endif /* MINIX */
  
   /* On initial startup, get two blocks of each size up to 1k bytes */
    if (!gotpool)
***************
*** 343,349 ****
  
    /* Find current end of memory and issue warning if getting near max */
  
! #ifndef VMS
    /* Maximum virtual memory on VMS is difficult to calculate since it
     * depends on several dynmacially changing things. Also, alignment
     * isn't that important. That is why much of the code here is ifdef'ed
--- 349,355 ----
  
    /* Find current end of memory and issue warning if getting near max */
  
! #if !defined(VMS) && !defined(MINIX)
    /* Maximum virtual memory on VMS is difficult to calculate since it
     * depends on several dynmacially changing things. Also, alignment
     * isn't that important. That is why much of the code here is ifdef'ed
***************
*** 726,731 ****
--- 732,738 ----
   *	data.  On SYSV systems this is the data space only.
   */
  
+ #ifndef MINIX
  #ifdef SYSV
  
  get_lim_data ()
***************
*** 760,765 ****
--- 767,773 ----
  
  #endif /* BSD42 */
  #endif /* not SYSV */
+ #endif /* not MINIX */
  
  #ifdef VMS
  /* There is a problem when dumping and restoring things on VMS. Calls

-- 
Jim Paradis                  UUCP:  harvard!m2c!jjmhome!acestes!paradis
9 Carlstad St.               AT&T:  (508) 792-3810
Worcester, MA 01607-1569     ICBM:  42deg 13' 52",  71deg 47' 51"