[gnu.utils.bug] patch #1 for gawk 2.11

arnold@unix.cc.emory.edu (Arnold D. Robbins) (11/11/89)

This should be appearing shortly for ftp on prep as well.
-----------
This is an official patch to gawk 2.11, please apply it.  Changes to
dvi, postscript, and *-info files are omitted.

FIRST: remove pc.d/makefile.pc and pc.d/names.lnk.  This patch creates
a new file pc.d/Makefile.pc.  In turn, the new makefile automatically
builds names.lnk.

Apply with patch -p to make sure files in subdirectories are correctly
patched.

With this patch, gawk moves from "beta" to production status.
-------------------------------------------------
diff -cr patch.0/CHANGES ./CHANGES
*** patch.0/CHANGES	Wed Oct 18 11:02:23 1989
--- ./CHANGES	Fri Nov 10 11:46:20 1989
***************
*** 1,3 ****
--- 1,23 ----
+ Changes from 2.11beta to 2.11.1 (production)
+ --------------------------------------------
+ 
+ Went from "beta" to production status!!!
+ 
+ Now flushes stdout before closing pipes or redirected files to
+ synchonize output.
+ 
+ MS-DOS changes added in.
+ 
+ Signal handler return type parameterized in Makefile and awk.h and
+ some lint removed.  debug.c cleaned up.
+ 
+ Fixed FS splitting to never match null strings, per book.
+ 
+ Correction to the manual's description of FS.
+ 
+ Some compilers break on char *foo = "string" + 4 so fixed version.sh and
+ main.c.
+ 
  Changes from 2.10beta to 2.11beta
  ---------------------------------
  
diff -cr patch.0/Makefile ./Makefile
*** patch.0/Makefile	Tue Oct 24 16:37:47 1989
--- ./Makefile	Tue Nov  7 10:18:27 1989
***************
*** 55,60 ****
--- 55,61 ----
  #	-DSTRTOD_MISSING	- lacks strtod() routine
  #	-DTMPNAM_MISSING	- lacks or deficient tmpnam() routine
  #	-DVPRINTF_MISSING	- lacks vprintf and associated routines
+ #	-DSIGTYPE=int		- signal routines return int (default void)
  
  # Sun running SunOS 4.x
  MISSING = -DSTRERROR_MISSING -DSTRCASE_MISSING
***************
*** 71,77 ****
  # MISSING = -DBSDSTDIO -DMEMCMP_MISSING -DMEMCPY_MISSING -DMEMSET_MISSING \
  #	-DSTRERROR_MISSING -DSTRTOD_MISSING -DVPRINTF_MISSING \
  #	-DSTRCASE_MISSING -DTMPNAM_MISSING \
! #	-DGETOPT_MISSING -DSTRCHR_MISSING
  
  # On Amdahl UTS, a SysVr2-derived system
  # MISSING = -DBCOPY_MISSING -DSPRINTF_INT -DRANDOM_MISSING -DSTRERROR_MISSING \
--- 72,78 ----
  # MISSING = -DBSDSTDIO -DMEMCMP_MISSING -DMEMCPY_MISSING -DMEMSET_MISSING \
  #	-DSTRERROR_MISSING -DSTRTOD_MISSING -DVPRINTF_MISSING \
  #	-DSTRCASE_MISSING -DTMPNAM_MISSING \
! #	-DGETOPT_MISSING -DSTRCHR_MISSING -DSIGTYPE=int
  
  # On Amdahl UTS, a SysVr2-derived system
  # MISSING = -DBCOPY_MISSING -DSPRINTF_INT -DRANDOM_MISSING -DSTRERROR_MISSING \
***************
*** 81,87 ****
  # Also choose just one of -g and -O.
  CC=		 gcc
  
! OPTIMIZE=	-O
  PROFILE=	#-pg
  DEBUG=		#-DDEBUG #-DMEMDEBUG #-DFUNC_TRACE #-DMPROF
  DEBUGGER=	#-g -Bstatic
--- 82,88 ----
  # Also choose just one of -g and -O.
  CC=		 gcc
  
! OPTIMIZE=	-O -g
  PROFILE=	#-pg
  DEBUG=		#-DDEBUG #-DMEMDEBUG #-DFUNC_TRACE #-DMPROF
  DEBUGGER=	#-g -Bstatic
***************
*** 142,148 ****
  
  MISC = CHANGES COPYING FUTURES Makefile PROBLEMS README
  
! PCSTUFF= pc.d/makefile.pc pc.d/names.lnk pc.d/popen.c pc.d/popen.h
  
  ALLDOC= gawk.dvi $(INFOFILES)
  
--- 143,149 ----
  
  MISC = CHANGES COPYING FUTURES Makefile PROBLEMS README
  
! PCSTUFF= pc.d/Makefile.pc pc.d/popen.c pc.d/popen.h
  
  ALLDOC= gawk.dvi $(INFOFILES)
  
diff -cr patch.0/README ./README
*** patch.0/README	Thu Oct 12 16:59:53 1989
--- ./README	Fri Nov 10 11:47:27 1989
***************
*** 1,6 ****
  README:
  
! This is GNU Awk 2.11 Beta. It should be upwardly compatible with the
  System V Release 4 awk.
  
  This release is essentially a bug fix release.  The files have been
--- 1,6 ----
  README:
  
! This is GNU Awk 2.11. It should be upwardly compatible with the
  System V Release 4 awk.
  
  This release is essentially a bug fix release.  The files have been
***************
*** 19,25 ****
  
  User visible changes:
  	Compatibility mode is now obtained via new -c option.
! 	The new ANSI \a and \x escapes are now a standard part of gawk
  		as Unix nawk has picked them up.
  	The new tolower() and toupper() functions are also standard.
  	A new undocumented option, -nostalgia, has been added.
--- 19,25 ----
  
  User visible changes:
  	Compatibility mode is now obtained via new -c option.
! 	The new ANSI C \a and \x escapes are now a standard part of gawk
  		as Unix nawk has picked them up.
  	The new tolower() and toupper() functions are also standard.
  	A new undocumented option, -nostalgia, has been added.
***************
*** 37,48 ****
  	Still more memory leaks plugged.
  	Lots of changes to improve performance and portability.
  
! PC users take note!  PC support is not provided in this release as we
! 	could not get anyone to do it; the person who did it for 2.10 lost
! 	his network connectivity.  It may be provided later either by
! 	us or by him.  The stuff in pc.d is from 2.10; anyone who cares
! 	to make it work for 2.11 under MS-DOS is welcome to do so and
! 	to feed the changes back to us.
  
  INSTALLATION:
  
--- 37,46 ----
  	Still more memory leaks plugged.
  	Lots of changes to improve performance and portability.
  
! PC users, you've been saved!
! 	As of patchlevel 1, we are now supplying MS-DOS "support."  Said
! 	support was generously provided by Kent Williams, who is now
! 	the contact person for it.  See below for his address.
  
  INSTALLATION:
  
***************
*** 65,71 ****
  want to get a copy of bison from the FSF too.)
  
  If you have an MS-DOS system, use the stuff in pc.d.
- (But see the note above.)
  
  PRINTING THE MANUAL
  
--- 63,68 ----
***************
*** 92,103 ****
  INTERNET	david@cs.dal.ca
  
  Arnold Robbins
! Emory University Computing Center
! Emory University, Atlanta, GA, 30322, USA
  
! INTERNET:	arnold@emoryu1.cc.emory.edu
! UUCP:		{ gatech, mtxinu }!emoryu1!arnold
! BITNET:		arnold@emoryu1
  
  If you can't contact either of us, try Jay Fenlason, hack@prep.ai.mit.edu
  AKA mit-eddie!prep!hack.  During odd hours he can sometimes be reached at
--- 89,99 ----
  INTERNET	david@cs.dal.ca
  
  Arnold Robbins
! 1315 Kittredge Court, N.E.
! Atlanta, GA, 30329-3539, USA
  
! INTERNET:	arnold@skeeve.atl.ga.us
! UUCP:		{ gatech, emory, emoryu1 }!skeeve!arnold
  
  If you can't contact either of us, try Jay Fenlason, hack@prep.ai.mit.edu
  AKA mit-eddie!prep!hack.  During odd hours he can sometimes be reached at
***************
*** 107,116 ****
  
  MS-DOS SUPPORT
  
! (This section is now outdated, see above.)
! 
! Support for MSC 5.1 was supplied by Conrad Kwok and Scott Garfinkle.
! Scott is the contact person if you have problems with the MS-DOS version,
! uunet!cos!stubby!seg.  (NOTE! This is a new address.) Of course, if it's
  a generic bug, we want to hear about it too, but if it isn't reproducible
  under Unix, we won't be as interested.
--- 103,111 ----
  
  MS-DOS SUPPORT
  
! Support for MSC 5.1 was supplied for 2.11 by Kent Williams, who can be
! reached at williams@umaxc.weeg.uiowa.edu.  It relies heavily on the
! earlier work done for 2.10 by Conrad Kwok and Scott Garfinkle.  Bug
! reports on the MS-DOS version should go to Kent.  Of course, if it's
  a generic bug, we want to hear about it too, but if it isn't reproducible
  under Unix, we won't be as interested.
diff -cr patch.0/array.c ./array.c
*** patch.0/array.c	Thu Aug 31 11:46:15 1989
--- ./array.c	Mon Nov  6 13:55:53 1989
***************
*** 55,61 ****
  	subsep = SUBSEP_node->lnode->stptr;
  	len = r->stlen + subseplen + 1;
  	emalloc(str, char *, len, "concat_exp");
- 	s = str;
  	memcpy(str, r->stptr, r->stlen+1);
  	s = str + r->stlen;
  	free_temp(r);
--- 55,60 ----
***************
*** 176,182 ****
  assoc_lookup(symbol, subs)
  NODE *symbol, *subs;
  {
! 	register int hash1 = 0, i;
  	register NODE *bucket;
  
  	hash1 = hash_calc(subs);
--- 175,181 ----
  assoc_lookup(symbol, subs)
  NODE *symbol, *subs;
  {
! 	register int hash1, i;
  	register NODE *bucket;
  
  	hash1 = hash_calc(subs);
***************
*** 207,213 ****
  do_delete(symbol, tree)
  NODE *symbol, *tree;
  {
! 	register int hash1 = 0;
  	register NODE *bucket, *last;
  	NODE *subs;
  
--- 206,212 ----
  do_delete(symbol, tree)
  NODE *symbol, *tree;
  {
! 	register int hash1;
  	register NODE *bucket, *last;
  	NODE *subs;
  
diff -cr patch.0/awk.h ./awk.h
*** patch.0/awk.h	Mon Oct 23 19:18:23 1989
--- ./awk.h	Mon Nov  6 14:00:55 1989
***************
*** 80,90 ****
--- 80,94 ----
  /* extern int fprintf(FILE *, char *, ...); */
  extern int fprintf();
  extern int vfprintf();
+ #ifndef MSDOS
  extern int fwrite(char *, int, int, FILE *);
+ #endif
  extern int fflush(FILE *);
  extern int fclose(FILE *);
  extern int pclose(FILE *);
+ #ifndef MSDOS
  extern int fputs(char *, FILE *);
+ #endif
  extern void abort();
  extern int isatty(int);
  extern void exit(int);
***************
*** 99,105 ****
--- 103,111 ----
  extern int open();
  extern int pipe(int *);
  extern int dup2(int, int);
+ #ifndef MSDOS
  extern int unlink(char *);
+ #endif
  extern int fork();
  extern int execl(/* char *, char *, ... */);
  extern int read(int, char *, int);
***************
*** 149,155 ****
--- 155,163 ----
  extern double atof();
  #endif
  
+ #ifndef MSDOS
  extern int errno;
+ #endif	/* MSDOS */
  
  /* ------------------ Constants, Structures, Typedefs  ------------------ */
  #define AWKNUM	double
***************
*** 593,598 ****
--- 601,610 ----
  #	else
  #		define BELL	'\057'
  #	endif
+ #endif
+ 
+ #ifndef SIGTYPE
+ #define SIGTYPE	void
  #endif
  
  extern char casetable[];	/* for case-independent regexp matching */
diff -cr patch.0/awk.y ./awk.y
*** patch.0/awk.y	Wed Oct 18 11:02:07 1989
--- ./awk.y	Mon Nov  6 13:55:54 1989
***************
*** 755,763 ****
  	char *scan;
  
  	errcount++;
- 	va_start(args);
- 	mesg = va_arg(args, char *);
- 	va_end(args);
  	/* Find the current line in the input file */
  	if (! lexptr) {
  		beg = "(END OF FILE)";
--- 755,760 ----
***************
*** 782,788 ****
--- 779,788 ----
  			putc(' ', stderr);
  	putc('^', stderr);
  	putc(' ', stderr);
+ 	va_start(args);
+ 	mesg = va_arg(args, char *);
  	vfprintf(stderr, mesg, args);
+ 	va_end(args);
  	putc('\n', stderr);
  	exit(1);
  }
***************
*** 808,814 ****
  {
  	register int c = *(*string_ptr)++;
  	register int i;
! 	register int count = 0;
  
  	switch (c) {
  	case 'a':
--- 808,814 ----
  {
  	register int c = *(*string_ptr)++;
  	register int i;
! 	register int count;
  
  	switch (c) {
  	case 'a':
diff -cr patch.0/builtin.c ./builtin.c
*** patch.0/builtin.c	Wed Oct 18 11:02:08 1989
--- ./builtin.c	Mon Nov  6 13:55:54 1989
***************
*** 477,483 ****
  				(void) strcpy(cp, "*f");
  				(void) sprintf(obuf + olen, cpbuf, (int) fw, (double) tmpval);
  			}
- 			cp = obuf + olen;
  			ofre -= strlen(obuf + olen);
  			olen += strlen(obuf + olen);	/* There may be nulls */
  			s0 = s1;
--- 477,482 ----
***************
*** 500,506 ****
  				(void) strcpy(cp, "*e");
  				(void) sprintf(obuf + olen, cpbuf, (int) fw, (double) tmpval);
  			}
- 			cp = obuf + olen;
  			ofre -= strlen(obuf + olen);
  			olen += strlen(obuf + olen);	/* There may be nulls */
  			s0 = s1;
--- 499,504 ----
diff -cr patch.0/debug.c ./debug.c
*** patch.0/debug.c	Wed Aug  9 23:06:00 1989
--- ./debug.c	Mon Nov  6 13:57:30 1989
***************
*** 37,69 ****
   * wants to.  
   */
  char *nnames[] = {
! 		  "Illegal Node",
! 		  "Times", "Divide", "Mod", "Plus", "Minus",
! 		  "Cond-pair", "Subscript", "Concat",
! 		  "++Pre", "--Pre", "Post++",
! 		  "Post--", "Uminus", "Field",
! 		  "Assign", "*=", "/=", "%=",
! 		  "+=", "-=",
! 		  "And", "Or",
! 		  "Equal", "!=", "Less", "Greater", "<=", ">=",
! 		  "Not",
! 		  "Match", "Nomatch",
! 		  "String", "TmpString", "Number",
! 	  "Rule_list", "Rule_node", "State_list", "If_branches", "Exp_list",
! 		  "Param_list",
! 		  "BEGIN", "END", "IF", "WHILE",
! 		  "FOR",
! 		  "arrayfor", "BREAK", "CONTINUE", "PRINT", "PRINTF",
! 
! 		  "next", "exit", "DO", "RETURN", "DELETE",
! 		  "redirect", "Append", "pipe", "Pipe in",
! 		  "redirect input", "variable", "Varray",
! 		  "builtin", "Line-range",
! 		  "In_Array", "FUNCTION", "function def", "function call",
! 		  "local variable",
! 		  "getline", "sub", "gsub", "match", "?:",
! 		  "^", "^=", "/regexp/", "Str_num",
! 		  "~~", "!~~",
  };
  
  ptree(n)
--- 37,67 ----
   * wants to.  
   */
  char *nnames[] = {
! 	"illegal", "times", "quotient", "mod", "plus",
! 	"minus", "cond_pair", "subscript", "concat", "exp",
! 	/* 10 */
! 	"preincrement", "predecrement", "postincrement", "postdecrement",
! 	"unary_minus",
! 	"field_spec", "assign", "assign_times", "assign_quotient", "assign_mod",
! 	/* 20 */
! 	"assign_plus", "assign_minus", "assign_exp", "and", "or",
! 	"equal", "notequal", "less", "greater", "leq",
! 	/* 30 */
! 	"geq", "match", "nomatch", "not", "rule_list",
! 	"rule_node", "statement_list", "if_branches", "expression_list",
! 	"param_list",
! 	/* 40 */
! 	"K_if", "K_while", "K_for", "K_arrayfor", "K_break",
! 	"K_continue", "K_print", "K_printf", "K_next", "K_exit",
! 	/* 50 */
! 	"K_do", "K_return", "K_delete", "K_getline", "K_function",
! 	"redirect_output", "redirect_append", "redirect_pipe",
! 	"redirect_pipein", "redirect_input",
! 	/* 60 */
! 	"var", "var_array", "val", "builtin", "line_range",
! 	"in_array", "func", "func_call", "cond_exp", "regex",
! 	/* 70 */
! 	"hashnode", "ahash"
  };
  
  ptree(n)
***************
*** 123,128 ****
--- 121,129 ----
  		printf("(0x%x Local variable %s)\n", ptr, ptr->param);
  		if (ptr->rnode)
  			print_parse_tree(ptr->rnode);
+ 		return;
+ 	case Node_regex:
+ 		printf("(0x%x Regular expression %s\n", ptr, ptr->re_text);
  		return;
  	}
  	if (ptr->lnode)
diff -cr patch.0/eval.c ./eval.c
*** patch.0/eval.c	Wed Oct 18 11:02:09 1989
--- ./eval.c	Mon Nov  6 14:07:40 1989
***************
*** 585,590 ****
--- 585,592 ----
  		if ((lx = t2->numbr) == t2->numbr) {	/* integer exponent */
  			if (lx == 0)
  				x = 1;
+ 			else if (lx == 1)
+ 				x = t1->numbr;
  			else {
  				/* doing it this way should be more precise */
  				for (x = x2 = t1->numbr; --lx; )
***************
*** 820,825 ****
--- 822,829 ----
  		if ((ltemp = rval) == rval) {	/* integer exponent */
  			if (ltemp == 0)
  				assign_number(lhs, (AWKNUM) 1);
+ 			else if (ltemp == 1)
+ 				assign_number(lhs, lval);
  			else {
  				/* doing it this way should be more precise */
  				for (t1 = t2 = lval; --ltemp; )
diff -cr patch.0/field.c ./field.c
*** patch.0/field.c	Fri Sep  8 16:25:46 1989
--- ./field.c	Mon Nov  6 13:58:26 1989
***************
*** 266,275 ****
  			    && scan < end)
  				scan++;
  		}
! 		while (re_split(scan, (int)(end - scan), fs, &reregs) != -1 &&
! 		    NF < up_to) {
! 			(*set)(++NF, scan, reregs.start[0], n);
  			scan += reregs.end[0];
  		}
  		if (NF != up_to && scan <= end) {
  			if (!(rs == 0 && scan == end)) {
--- 266,287 ----
  			    && scan < end)
  				scan++;
  		}
! 		s = scan;
! 		while (scan < end
! 		    && re_split(scan, (int)(end - scan), fs, &reregs) != -1
! 		    && NF < up_to) {
! 			if (reregs.end[0] == 0) {	/* null match */
! 				scan++;
! 				if (scan == end) {
! 					(*set)(++NF, s, scan - s, n);
! 					up_to = NF;
! 					break;
! 				}
! 				continue;
! 			}
! 			(*set)(++NF, s, scan - s + reregs.start[0], n);
  			scan += reregs.end[0];
+ 			s = scan;
  		}
  		if (NF != up_to && scan <= end) {
  			if (!(rs == 0 && scan == end)) {
diff -cr patch.0/gawk.texinfo ./gawk.texinfo
*** patch.0/gawk.texinfo	Tue Oct 24 12:30:44 1989
--- ./gawk.texinfo	Thu Nov  9 20:53:52 1989
***************
*** 67,73 ****
  @sp 2
  
  This is Edition 0.11 Beta of @cite{The GAWK Manual}, @*
! for the 2.11 Beta version of the GNU implementation @*
  of AWK.
  
  @sp 2
--- 67,73 ----
  @sp 2
  
  This is Edition 0.11 Beta of @cite{The GAWK Manual}, @*
! for the 2.11.1 version of the GNU implementation @*
  of AWK.
  
  @sp 2
***************
*** 1614,1624 ****
  @cindex @samp{-F} option
  
  The way @code{awk} splits an input record into fields is controlled by
! the @dfn{field separator}, which is a regular expression.  @code{awk}
! scans the input record for matches for this regular expression; these
! matches separate fields.  The fields themselves are the text between the
! matches.  For example, if the field separator is @samp{oo}, then the
! following line:
  
  @example
  moo goo gai pan
--- 1614,1623 ----
  @cindex @samp{-F} option
  
  The way @code{awk} splits an input record into fields is controlled by
! the @dfn{field separator}, which is a single character or a regular
! expression.  @code{awk} scans the input record for matches for the
! separator; the fields themselves are the text between the matches.  For
! example, if the field separator is @samp{oo}, then the following line:
  
  @example
  moo goo gai pan
***************
*** 1682,1693 ****
  @code{FS} is a special case: it is taken to specify the default manner
  of delimiting fields.
  
! If @code{FS} is any other single character, such as @code{","}, then two
! successive occurrences of that character do delimit an empty field.  The
! space character is the only special case.
  
! You can set @code{FS} to be a string containing several characters.  For
! example, the assignment:@refill
  
  @example
  FS = ", \t"
--- 1681,1696 ----
  @code{FS} is a special case: it is taken to specify the default manner
  of delimiting fields.
  
! If @code{FS} is any other single character, such as @code{","}, then
! each occurrence of that character separates two fields.  Two consecutive
! occurrences delimit an empty field.  If the character occurs at the
! beginning or the end of the line, that too delimits an empty field.  The
! space character is the only single character which does not follow these
! rules.
  
! More generally, the value of @code{FS} may be a string containing any
! regular expression.  Then each match in the record for the regular
! expression separates fields.  For example, the assignment:@refill
  
  @example
  FS = ", \t"
***************
*** 1698,1709 ****
  space and a tab, into a field separator.  (@samp{\t} stands for a
  tab.)@refill
  
! More generally, the value of @code{FS} may be a string containing any
! regular expression.  Then each match in the record for the regular
! expression separates fields.  For example, if you want single spaces to
! separate fields the way single commas were used above, you can set
! @code{FS} to @w{@code{"[@ ]"}}.  This regular expression matches a single
! space and nothing else.
  
  @cindex field separator, setting on command line
  @cindex command line, setting @code{FS} on
--- 1701,1710 ----
  space and a tab, into a field separator.  (@samp{\t} stands for a
  tab.)@refill
  
! For a less trivial example of a regular expression, suppose you want
! single spaces to separate fields the way single commas were used above.
! You can set @code{FS} to @w{@code{"[@ ]"}}.  This regular expression
! matches a single space and nothing else.
  
  @cindex field separator, setting on command line
  @cindex command line, setting @code{FS} on
***************
*** 6496,6503 ****
  @c @vindex FS
  @item FS
  @code{FS} is the input field separator (@pxref{Field Separators}).
! The value is a regular expression that matches the separations
! between fields in an input record.
  
  The default value is @w{@code{" "}}, a string consisting of a single
  space.  As a special exception, this value actually means that any
--- 6497,6505 ----
  @c @vindex FS
  @item FS
  @code{FS} is the input field separator (@pxref{Field Separators}).
! The value is a single-character string or a multi-character regular
! expression that matches the separations between fields in an input
! record.
  
  The default value is @w{@code{" "}}, a string consisting of a single
  space.  As a special exception, this value actually means that any
diff -cr patch.0/io.c ./io.c
*** patch.0/io.c	Mon Oct 23 19:18:23 1989
--- ./io.c	Mon Nov  6 14:23:24 1989
***************
*** 27,35 ****
  #ifndef O_RDONLY
  #include <fcntl.h>
  #endif
- #if defined(MSDOS)
- #include "popen.h"
- #endif
  #include <signal.h>
  
  extern FILE *popen();
--- 27,32 ----
***************
*** 396,401 ****
--- 393,399 ----
  	free_temp(tmp);
  	if (rp == NULL) /* no match */
  		return tmp_number((AWKNUM) 0.0);
+ 	fflush(stdout);	/* synchronize regular output */
  	return tmp_number((AWKNUM)close_redir(rp));
  }
  
***************
*** 529,534 ****
--- 527,533 ----
  #endif
  }
  
+ #ifndef MSDOS
  static IOBUF *
  gawk_popen(cmd, rp)
  char *cmd;
***************
*** 541,547 ****
  	rp->iop = NULL;
  	if (pipe(p) < 0)
  		return NULL;
! 	if((pid = fork()) == 0) {
  		close(p[0]);
  		dup2(p[1], 1);
  		close(p[1]);
--- 540,546 ----
  	rp->iop = NULL;
  	if (pipe(p) < 0)
  		return NULL;
! 	if ((pid = fork()) == 0) {
  		close(p[0]);
  		dup2(p[1], 1);
  		close(p[1]);
***************
*** 548,554 ****
  		execl("/bin/sh", "sh", "-c", cmd, 0);
  		_exit(127);
  	}
! 	if(pid == -1)
  		return NULL;
  	rp->pid = pid;
  	close(p[1]);
--- 547,553 ----
  		execl("/bin/sh", "sh", "-c", cmd, 0);
  		_exit(127);
  	}
! 	if (pid == -1)
  		return NULL;
  	rp->pid = pid;
  	close(p[1]);
***************
*** 559,569 ****
  gawk_pclose(rp)
  struct redirect *rp;
  {
! 	void (*hstat)(), (*istat)(), (*qstat)();
  	int pid;
  	int status;
  	struct redirect *redp;
- 	extern int errno;
  
  	iop_close(rp->iop);
  	if (rp->pid == -1)
--- 558,567 ----
  gawk_pclose(rp)
  struct redirect *rp;
  {
! 	SIGTYPE (*hstat)(), (*istat)(), (*qstat)();
  	int pid;
  	int status;
  	struct redirect *redp;
  
  	iop_close(rp->iop);
  	if (rp->pid == -1)
***************
*** 593,598 ****
--- 591,644 ----
  	signal(SIGQUIT, qstat);
  	return(rp->status);
  }
+ #else
+ static
+ struct {
+ 	char *command;
+ 	char *name;
+ } pipes[_NFILE];
+ 
+ static IOBUF *
+ gawk_popen(cmd, rp)
+ char *cmd;
+ struct redirect *rp;
+ {
+ 	extern char *strdup(const char *);
+ 	int current;
+ 	char *name;
+ 	static char cmdbuf[256];
+ 
+ 	/* get a name to use.  */
+ 	if ((name = tempnam(".", "pip")) == NULL)
+ 		return NULL;
+ 	sprintf(cmdbuf,"%s > %s", cmd, name);
+ 	system(cmdbuf);
+ 	if ((current = open(name,O_RDONLY)) == -1)
+ 		return NULL;
+ 	pipes[current].name = name;
+ 	pipes[current].command = strdup(cmd);
+ 	return (rp->iop = iop_alloc(current));
+ }
+ 
+ static int
+ gawk_pclose(rp)
+ struct redirect *rp;
+ {
+ 	int cur = rp->iop->fd;
+ 	int rval;
+ 
+ 	rval = iop_close(rp->iop);
+ 
+ 	/* check for an open file  */
+ 	if (pipes[cur].name == NULL)
+ 		return -1;
+ 	unlink(pipes[cur].name);
+ 	free(pipes[cur].name);
+ 	pipes[cur].name = NULL;
+ 	free(pipes[cur].command);
+ 	return rval;
+ }
+ #endif
  
  #define	DO_END_OF_BUF	len = bp - iop->off;\
  			used = last - start;\
diff -cr patch.0/main.c ./main.c
*** patch.0/main.c	Tue Oct 17 13:08:24 1989
--- ./main.c	Thu Nov  9 20:53:17 1989
***************
*** 115,121 ****
  	extern char *optarg;
   	extern char *strrchr();
   	extern char *tmpnam();
! 	extern int catchsig();
  	int i;
  	int nostalgia;
  #ifdef somtime_in_the_future
--- 115,121 ----
  	extern char *optarg;
   	extern char *strrchr();
   	extern char *tmpnam();
! 	extern SIGTYPE catchsig();
  	int i;
  	int nostalgia;
  #ifdef somtime_in_the_future
***************
*** 127,132 ****
--- 127,135 ----
  	(void) signal(SIGFPE, catchsig);
  	(void) signal(SIGSEGV, catchsig);
  
+ 	if (strncmp(version_string, "@(#)", 4) == 0)
+ 		version_string += 4;
+ 
  	myname = strrchr(argv[0], '/');
  	if (myname == NULL)
  		myname = argv[0];
***************
*** 297,302 ****
--- 300,307 ----
  	if (close_io() != 0 && exit_val == 0)
  		exit_val = 1;
  	exit(exit_val);
+ 	/* NOTREACHED */
+ 	return exit_val;
  }
  
  static void
***************
*** 374,384 ****
  				c = parse_escape(&src);
  				if (c < 0)
  					cant_happen();
! 				*dest++ = c;
  				break;
  			default:
  				*dest++ = '\\';
! 				*dest++ = c;
  				src++;
  				break;
  			}
--- 379,389 ----
  				c = parse_escape(&src);
  				if (c < 0)
  					cant_happen();
! 				*dest++ = (char)c;
  				break;
  			default:
  				*dest++ = '\\';
! 				*dest++ = (char)c;
  				src++;
  				break;
  			}
***************
*** 529,535 ****
  	}
  }
  
! int
  catchsig(sig, code)
  int sig, code;
  {
--- 534,540 ----
  	}
  }
  
! SIGTYPE
  catchsig(sig, code)
  int sig, code;
  {
diff -cr patch.0/missing.c ./missing.c
*** patch.0/missing.c	Mon Sep 25 13:11:19 1989
--- ./missing.c	Fri Nov 10 11:38:42 1989
***************
*** 1,3 ****
--- 1,11 ----
+ #ifdef MSDOS
+ #define BCOPY_MISSING
+ #define STRCASE_MISSING
+ #define BLKSIZE_MISSING
+ #define SPRINTF_INT
+ #define RANDOM_MISSING
+ #define GETOPT_MISSING
+ #endif
  
  #ifdef DUP2_MISSING
  #include "missing.d/dup2.c"
diff -cr patch.0/missing.d/random.c ./missing.d/random.c
*** patch.0/missing.d/random.c	Thu Apr 13 08:01:19 1989
--- ./missing.d/random.c	Fri Nov 10 10:28:46 1989
***************
*** 236,242 ****
  	if(  n  <  BREAK_1  )  {
  	    if(  n  <  BREAK_0  )  {
  		fprintf( stderr, "initstate: not enough state (%d bytes) with which to do jack; ignored.\n", n );
! 		return;
  	    }
  	    rand_type = TYPE_0;
  	    rand_deg = DEG_0;
--- 236,242 ----
  	if(  n  <  BREAK_1  )  {
  	    if(  n  <  BREAK_0  )  {
  		fprintf( stderr, "initstate: not enough state (%d bytes) with which to do jack; ignored.\n", n );
! 		return 0;
  	    }
  	    rand_type = TYPE_0;
  	    rand_deg = DEG_0;
diff -cr patch.0/node.c ./node.c
*** patch.0/node.c	Wed Oct 11 18:57:31 1989
--- ./node.c	Mon Nov  6 14:30:32 1989
***************
*** 60,66 ****
  	} else {
  		errno = 0;
  		n->numbr = (AWKNUM) strtod(n->stptr, &ptr);
! 		if (errno == 0 && ptr == n->stptr + n->stlen)
  			n->flags |= NUMERIC;
  	}
  	n->flags |= NUM;
--- 60,67 ----
  	} else {
  		errno = 0;
  		n->numbr = (AWKNUM) strtod(n->stptr, &ptr);
! 		/* the following >= should be ==, but for SunOS 3.5 strtod() */
! 		if (errno == 0 && ptr >= n->stptr + n->stlen)
  			n->flags |= NUMERIC;
  	}
  	n->flags |= NUM;
diff -cr patch.0/patchlevel.h ./patchlevel.h
*** patch.0/patchlevel.h	Thu Oct 12 16:27:30 1989
--- ./patchlevel.h	Tue Oct 31 16:48:17 1989
***************
*** 1,1 ****
! #define PATCHLEVEL	0
--- 1,1 ----
! #define PATCHLEVEL	1
diff -cr patch.0/pc.d/Makefile.pc ./pc.d/Makefile.pc
*** patch.0/pc.d/Makefile.pc	Tue Nov  7 10:18:45 1989
--- ./pc.d/Makefile.pc	Fri Nov 10 11:42:19 1989
***************
*** 0 ****
--- 1,282 ----
+ # Makefile for GNU Awk.
+ #
+ # Copyright (C) 1986, 1988, 1989 the Free Software Foundation, Inc.
+ # 
+ # This file is part of GAWK, the GNU implementation of the
+ # AWK Progamming Language.
+ # 
+ # GAWK is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU General Public License as published by
+ # the Free Software Foundation; either version 1, or (at your option)
+ # any later version.
+ # 
+ # GAWK is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ # GNU General Public License for more details.
+ # 
+ # You should have received a copy of the GNU General Public License
+ # along with GAWK; see the file COPYING.  If not, write to
+ # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ 
+ # User tunable macros
+ 
+ # CFLAGS: options to the C compiler
+ #
+ #	-O	optimize
+ #	-g	include dbx/sdb info
+ #	-gg	include gdb debugging info; only for GCC (deprecated)
+ #	-pg	include new (gmon) profiling info
+ #	-p	include old style profiling info (System V)
+ #
+ #	To port GAWK, examine and adjust the following flags carefully.
+ #	In addition, you will have to look at alloca below.
+ #	The intent (eventual) is to not penalize the most-standard-conforming
+ #	systems with a lot of #define's.
+ #
+ #	-DBCOPY_MISSING		- bcopy() et al. are missing; will replace
+ #				  with a #define'd memcpy() et al. -- use at
+ #				  your own risk (should really use a memmove())
+ #	-DSPRINTF_INT		- sprintf() returns int (most USG systems)
+ #	-DBLKSIZE_MISSING	- st_blksize missing from stat() structure
+ #				  (most USG systems)
+ #	-DBSDSTDIO		- has a BSD internally-compatible stdio
+ #	-DDOPRNT_MISSING	- lacks doprnt() routine
+ #	-DDUP2_MISSING		- lacks dup2() system call (S5Rn, n < 4)
+ #	-DGCVT_MISSING		- lacks gcvt() routine
+ #	-DGETOPT_MISSING	- lacks getopt() routine
+ #	-DMEMCMP_MISSING	- lacks memcmp() routine
+ #	-DMEMCPY_MISSING	- lacks memcpy() routine
+ #	-DMEMSET_MISSING	- lacks memset() routine
+ #	-DRANDOM_MISSING	- lacks random() routine
+ #	-DSTRCASE_MISSING	- lacks strcasecmp() routine
+ #	-DSTRCHR_MISSING	- lacks strchr() and strrchr() routines
+ #	-DSTRERROR_MISSING	- lacks (ANSI C) strerror() routine
+ #	-DSTRTOD_MISSING	- lacks strtod() routine
+ #	-DTMPNAM_MISSING	- lacks or deficient tmpnam() routine
+ #	-DVPRINTF_MISSING	- lacks vprintf and associated routines
+ #	-DSIGTYPE=int		- signal routines return int (default void)
+ 
+ # Sun running SunOS 4.x
+ # MISSING = -DSTRERROR_MISSING -DSTRCASE_MISSING
+ 
+ # SGI Personal Iris (Sys V derived)
+ # MISSING = -DSPRINTF_INT -DBLKSIZE_MISSING -DSTRERROR_MISSING -DRANDOM_MISSING
+ 
+ # VAX running Ultrix 3.x
+ # MISSING = -DSTRERROR_MISSING
+ 
+ # A generic 4.2 BSD machine
+ # (eliminate GETOPT_MISSING for 4.3 release)
+ # (eliminate STRCASE_MISSING and TMPNAM_MISSING for Tahoe release)
+ # MISSING = -DBSDSTDIO -DMEMCMP_MISSING -DMEMCPY_MISSING -DMEMSET_MISSING \
+ #	-DSTRERROR_MISSING -DSTRTOD_MISSING -DVPRINTF_MISSING \
+ #	-DSTRCASE_MISSING -DTMPNAM_MISSING \
+ #	-DGETOPT_MISSING -DSTRCHR_MISSING -DSIGTYPE=int
+ 
+ # On Amdahl UTS, a SysVr2-derived system
+ # MISSING = -DBCOPY_MISSING -DSPRINTF_INT -DRANDOM_MISSING -DSTRERROR_MISSING \
+ #	-DSTRCASE_MISSING -DDUP2_MISSING # -DBLKSIZE_MISSING ??????
+ 
+ # Comment out the next line if you don't have gcc.
+ # Also choose just one of -g and -O.
+ # CC=		 gcc
+ # for DOS
+ CC= cl
+ POPEN = popen.o
+ 
+ # for DOS, most of the missing symbols are defined in MISSING.C in order to
+ # get around the command line length limitations
+ MISSING = -DSPRINTF_INT -DBLKSIZE_MISSING -DBCOPY_MISSING
+ LINKFLAGS= /MAP /CO /FAR /PACKC /NOE /NOIG /st:0x1800
+ 
+ # also give suffixes and explicit rule for DOS
+ .SUFFIXES : .o .c
+ .c.o:
+ 	$(CC) -c $(CFLAGS) -Ipc.d -W2 -AL -Fo$*.o $<
+ 	
+ OPTIMIZE=	-Od -Zi
+ PROFILE=	#-pg
+ DEBUG=		#-DDEBUG #-DMEMDEBUG #-DFUNC_TRACE #-DMPROF
+ DEBUGGER=	#-g -Bstatic
+ WARN=		#-W -Wunused -Wimplicit -Wreturn-type -Wcomment	# for gcc only
+ 
+ # Parser to use on grammar -- if you don't have bison use the first one
+ #PARSER = yacc
+ PARSER = bison
+ 
+ # ALLOCA
+ #	Set equal to alloca.o if your system is S5 and you don't have
+ #	alloca. Uncomment one of the rules below to make alloca.o from
+ #	either alloca.s or alloca.c.
+ ALLOCA= #alloca.o
+ 
+ #
+ # With the exception of the alloca rule referred to above, you shouldn't
+ # need to customize this file below this point.
+ #
+ 
+ FLAGS= $(MISSING) $(DEBUG)
+ CFLAGS= $(FLAGS) $(DEBUGGER) $(PROFILE) $(OPTIMIZE) $(WARN)
+ 
+ # object files
+ O1 = main.o eval.o builtin.o msg.o debug.o io.o field.o array.o node.o
+ O2 = version.o missing.o $(POPEN)
+ 
+ AWKOBJS = $(O1) $(O2)
+ 
+ 
+ # for unix
+ # AWKTAB = awk.tab.o
+ # for dos
+ AWKTAB = awk_tab.o
+ 
+ 
+ 
+ ALLOBJS = $(AWKOBJS) $(AWKTAB)
+ 
+ # GNUOBJS
+ #	GNU stuff that gawk uses as library routines.
+ GNUOBJS= regex.o $(ALLOCA)
+ 
+ # source and documentation files
+ SRC =	main.c eval.c builtin.c msg.c \
+ 	debug.c io.c field.c array.c node.c missing.c
+ 
+ ALLSRC= $(SRC) awk.tab.c
+ 
+ AWKSRC= awk.h awk.y $(ALLSRC) version.sh patchlevel.h
+ 
+ GNUSRC = alloca.c alloca.s regex.c regex.h
+ 
+ COPIES = missing.d/dup2.c missing.d/gcvt.c missing.d/getopt.c \
+ 	missing.d/memcmp.c missing.d/memcpy.c missing.d/memset.c \
+ 	missing.d/random.c missing.d/strcase.c missing.d/strchr.c \
+ 	missing.d/strerror.c missing.d/strtod.c missing.d/tmpnam.c \
+ 	missing.d/vprintf.c
+ 
+ SUPPORT = support/texindex.c support/texinfo.tex
+ 
+ DOCS= gawk.1 gawk.texinfo
+ 
+ INFOFILES= gawk-info gawk-info-1 gawk-info-2 gawk-info-3 gawk-info-4 \
+ 	   gawk-info-5 gawk-info-6 gawk.aux gawk.cp gawk.cps gawk.fn \
+ 	   gawk.fns gawk.ky gawk.kys gawk.pg gawk.pgs gawk.toc \
+ 	   gawk.tp gawk.tps gawk.vr gawk.vrs
+ 
+ MISC = CHANGES COPYING FUTURES Makefile PROBLEMS README
+ 
+ PCSTUFF= pc.d/Makefile.pc pc.d/popen.c pc.d/popen.h
+ 
+ ALLDOC= gawk.dvi $(INFOFILES)
+ 
+ ALLFILES= $(AWKSRC) $(GNUSRC) $(COPIES) $(MISC) $(DOCS) $(ALLDOC) $(PCSTUFF) $(SUPPORT)
+ 
+ # Release of gawk.  There can be no leading or trailing white space here!
+ REL=2.11
+ # for unix
+ # GAWK = gawk
+ # for DOS
+ GAWK = gawk.exe
+ $(GAWK) : $(ALLOBJS) $(GNUOBJS) names.lnk
+ 	link @names.lnk
+ 
+ #GNULIB = ..\lib\lgnu.lib 
+ GNULIB = 
+ names.lnk : makefile
+ 	echo $(O1) + > $@
+ 	echo $(O2) + >> $@
+ 	echo $(AWKTAB) + >> $@
+ 	echo $(GNUOBJS) >> $@
+ 	echo $(GAWK) >> $@
+ 	echo gawk.map >> $@
+ 	echo $(GNULIB) $(LINKFLAGS) >> $@
+ 
+ popen.o : pc.d\popen.c
+ 	$(CC) -c $(CFLAGS) -Ipc.d -W2 -AL -Fo$*.o pc.d\popen.c
+ 
+ # rules to build gawk
+ #$(GAWK) : $(ALLOBJS) $(GNUOBJS)
+ #	$(CC) -o gawk $(CFLAGS) $(ALLOBJS) $(GNUOBJS) -lm
+ 
+ $(AWKOBJS): awk.h
+ 
+ main.o: patchlevel.h
+ 
+ #awk.tab.o: awk.h awk.tab.c
+ #
+ #awk.tab.c: awk.y
+ #	$(PARSER) -v awk.y
+ #	-mv -f y.tab.c awk.tab.c
+ 
+ # for dos
+ awk_tab.o : awk.y awk.h
+ 	bison -y awk.y
+ 	$(CC) -c $(CFLAGS) -Ipc.d -W2 -AL -Fo$@ y_tab.c
+ 	@-rm y_tab.c
+ 
+ version.c: version.sh
+ 	sh version.sh $(REL) > version.c
+ 
+ # Alloca: uncomment this if your system (notably System V boxen)
+ # does not have alloca in /lib/libc.a
+ #
+ #alloca.o: alloca.s
+ #	/lib/cpp < alloca.s | sed '/^#/d' > t.s
+ #	as t.s -o alloca.o
+ #	rm t.s
+ 
+ # If your machine is not supported by the assembly version of alloca.s,
+ # use the C version instead.  This uses the default rules to make alloca.o.
+ #
+ #alloca.o: alloca.c
+ 
+ # auxiliary rules for release maintenance
+ lint: $(ALLSRC)
+ 	lint -hcbax $(FLAGS) $(ALLSRC)
+ 
+ xref:
+ 	cxref -c $(FLAGS) $(ALLSRC) | grep -v '	/' >xref
+ 
+ clean:
+ 	rm -f gawk *.o core awk.output awk.tab.c gmon.out make.out version.c
+ 
+ clobber: clean
+ 	rm -f $(ALLDOC) gawk.log
+ 
+ gawk.dvi: gawk.texinfo
+ 	tex gawk.texinfo ; texindex gawk.??
+ 	tex gawk.texinfo ; texindex gawk.??
+ 	tex gawk.texinfo
+ 
+ $(INFOFILES): gawk.texinfo
+ 	makeinfo gawk.texinfo
+ 
+ srcrelease: $(AWKSRC) $(GNUSRC) $(DOCS) $(MISC) $(COPIES) $(PCSTUFF) $(SUPPORT)
+ 	-mkdir gawk-$(REL)
+ 	cp -p $(AWKSRC) $(GNUSRC) $(DOCS) $(MISC) gawk-$(REL)
+ 	-mkdir gawk-$(REL)/missing.d
+ 	cp -p $(COPIES) gawk-$(REL)/missing.d
+ 	-mkdir gawk-$(REL)/pc.d
+ 	cp -p $(PCSTUFF) gawk-$(REL)/pc.d
+ 	-mkdir gawk-$(REL)/support
+ 	cp -p $(SUPPORT) gawk-$(REL)/support
+ 	tar -cf - gawk-$(REL) | compress > gawk-$(REL).tar.Z
+ 
+ docrelease: $(ALLDOC)
+ 	-mkdir gawk-$(REL)-doc
+ 	cp -p $(INFOFILES) gawk.dvi gawk-$(REL)-doc
+ 	nroff -man gawk.1 > gawk-$(REL)-doc/gawk.1.pr
+ 	tar -cf - gawk-$(REL)-doc | compress > gawk-doc-$(REL).tar.Z
+ 
+ psrelease: docrelease
+ 	-mkdir gawk-postscript
+ 	dvi2ps gawk.dvi > gawk-postscript/gawk.postscript
+ 	psroff -t -man gawk.1 > gawk-postscript/gawk.1.ps
+ 	tar -cf - gawk-postscript | compress > gawk.postscript.tar.Z
+ 
+ release: srcrelease docrelease psrelease
+ 	rm -fr gawk-postscript gawk-$(REL) gawk-$(REL)-doc
+ 
+ diff:
+ 	for i in RCS/*; do rcsdiff -c -b $$i > `basename $$i ,v`.diff; done
diff -cr patch.0/version.sh ./version.sh
*** patch.0/version.sh	Thu Oct 12 16:47:10 1989
--- ./version.sh	Thu Nov  9 20:51:34 1989
***************
*** 11,17 ****
  RELEASE="$1"
  
  cat << EOF
! char *version_string = "@(#)Gnu Awk (gawk) ${RELEASE}-BETA" + 4;
  
  /* 1.02		fixed /= += *= etc to return the new Left Hand Side instead
  		of the Right Hand Side */
--- 11,17 ----
  RELEASE="$1"
  
  cat << EOF
! char *version_string = "@(#)Gnu Awk (gawk) ${RELEASE}";
  
  /* 1.02		fixed /= += *= etc to return the new Left Hand Side instead
  		of the Right Hand Side */
--
Arnold Robbins -- Emory Information Technology Division | Laundry increases
DOMAIN: arnold@emoryu1.cc.emory.edu			| exponentially in the
UUCP: gatech!emoryu1!arnold  PHONE: +1 404 727-7636	| number of children.
BITNET: arnold@emoryu1	     FAX:   +1 404 727-2599	|   -- Miriam Hartholz