#!/bin/sh # This is patch 6 to gawk 2.15. # Change to the gawk 2.15.5 distribution directory, and sh this file. # Running it through patch is not enough; files and/or directories # must be created or removed first. # # Make sure that the patch program is in your search path. rm -f awktab.c echo 0 | tr -d '\012' > test/nonl.awk patch -p1 << \EOF diff -crN gawk-2.15.5/ACKNOWLEDGMENT gawk-2.15.6/ACKNOWLEDGMENT *** gawk-2.15.5/ACKNOWLEDGMENT Sun May 15 11:27:11 1994 --- gawk-2.15.6/ACKNOWLEDGMENT Sat Feb 18 23:03:55 1995 *************** *** 3,23 **** and fixes and suggestions. Unfortunately, we have not been organized enough to keep track of all the names -- for that we apologize. ! Another group of people have assisted even more by porting Gawk to new ! platforms and providing a great deal of feedback. They are: - Hal Peterson (Cray) - Pat Rankin (VMS) - Michal Jaegermann (Atari, NeXT, DEC 3100) Mike Lijewski (IBM RS6000) - Scott Deifik (MSDOS 2.14 and 2.15) Kent Williams (MSDOS 2.11) Conrad Kwok (MSDOS earlier versions) Scott Garfinkle (MSDOS earlier versions) Kai Uwe Rommel (OS/2) Darrel Hankerson (OS/2) Mark Moraes (Code Center, Purify) Kaveh Ghazi (Lots of Unix variants) Last, but far from least, we would like to thank Brian Kernighan who has helped to clear up many dark corners of the language and provided a --- 3,32 ---- and fixes and suggestions. Unfortunately, we have not been organized enough to keep track of all the names -- for that we apologize. ! The following people were involved in porting gawk to different platforms. Mike Lijewski (IBM RS6000) Kent Williams (MSDOS 2.11) Conrad Kwok (MSDOS earlier versions) Scott Garfinkle (MSDOS earlier versions) + + This group of people comprise the "GAWK crack portability team", who + test the pre-releases and ensure portability of gawk. + + Hal Peterson (Cray) + Pat Rankin (VMS) + Michal Jaegermann + (Atari, NeXT, DEC 3100) + Scott Deifik (MSDOS 2.14 and 2.15) Kai Uwe Rommel (OS/2) Darrel Hankerson (OS/2) Mark Moraes (Code Center, Purify) Kaveh Ghazi (Lots of Unix variants) + + Michal, Scott and Darrel go out of their way to make sure that gawk + works on non-32 bit systems, and keep me on track where portability is + concerned. Indeed, all of these folks are incredibly helpful; gawk would + not be the fine program it is now without them. Last, but far from least, we would like to thank Brian Kernighan who has helped to clear up many dark corners of the language and provided a diff -crN gawk-2.15.5/FUTURES gawk-2.15.6/FUTURES *** gawk-2.15.5/FUTURES Thu May 19 00:37:45 1994 --- gawk-2.15.6/FUTURES Thu Feb 23 22:09:28 1995 *************** *** 16,23 **** any value makes it work, not just numeric non-zero make it apply to *all* string comparisons - x Fix FILENAME to have an initial value of "", not "-" - In 2.17 ======= x Allow RS to be a regexp. --- 16,21 ---- diff -crN gawk-2.15.5/Makefile.in gawk-2.15.6/Makefile.in *** gawk-2.15.5/Makefile.in Wed Dec 29 10:25:34 1993 --- gawk-2.15.6/Makefile.in Mon Mar 6 06:44:35 1995 *************** *** 1,6 **** # Makefile for GNU Awk. # ! # Copyright (C) 1986, 1988-1993 the Free Software Foundation, Inc. # # This file is part of GAWK, the GNU implementation of the # AWK Progamming Language. --- 1,6 ---- # Makefile for GNU Awk. # ! # Copyright (C) 1986, 1988-1995 the Free Software Foundation, Inc. # # This file is part of GAWK, the GNU implementation of the # AWK Progamming Language. *************** *** 83,89 **** ##MAKE_Apollo## LIBS = -A sys,any # SGI IRIX 4.0.5 cc flags ! ##MAKE_SGI## VFLAGS = -cckr ##MAKE_NeXT## VFLAGS = -DGFMT_WORKAROUND --- 83,90 ---- ##MAKE_Apollo## LIBS = -A sys,any # SGI IRIX 4.0.5 cc flags ! ##MAKE_SGI## VFLAGS = -cckr -signed ! ##MAKE_SGI_GCC## VFLAGS = -fsigned-char ##MAKE_NeXT## VFLAGS = -DGFMT_WORKAROUND *************** *** 151,157 **** awktab.c: awk.y $(PARSER) -v awk.y ! ##MAKE_VMS-Posix## mv ytab.c awktab.c ##MAKE_VMS-Posix## dummy.awk_tab.target: sed '/^extern char .malloc(), .realloc();$$/d' y.tab.c >awktab.c rm y.tab.c --- 152,158 ---- awktab.c: awk.y $(PARSER) -v awk.y ! ##MAKE_VMS-Posix## sed '/^\#module/d' ytab.c >awktab.c && rm ytab.c ##MAKE_VMS-Posix## dummy.awk_tab.target: sed '/^extern char .malloc(), .realloc();$$/d' y.tab.c >awktab.c rm y.tab.c *************** *** 164,170 **** @echo or copy config.in to config.h and edit it.; exit 1 install: gawk gawk.info ! cp gawk $(bindir) && chmod 755 $(bindir)/gawk cp gawk.1 $(mandir)/gawk$(manext) && chmod 644 $(mandir)/gawk$(manext) cp gawk.info* $(infodir) && chmod 644 $(infodir)/gawk.info* --- 165,171 ---- @echo or copy config.in to config.h and edit it.; exit 1 install: gawk gawk.info ! cp gawk $(bindir)/gawk && chmod 755 $(bindir)/gawk cp gawk.1 $(mandir)/gawk$(manext) && chmod 644 $(mandir)/gawk$(manext) cp gawk.info* $(infodir) && chmod 644 $(infodir)/gawk.info* diff -crN gawk-2.15.5/NEWS gawk-2.15.6/NEWS *** gawk-2.15.5/NEWS Thu May 19 01:12:01 1994 --- gawk-2.15.6/NEWS Thu Mar 9 11:51:01 1995 *************** *** 1,3 **** --- 1,111 ---- + Changes from 2.15.5 to 2.15.6 + ----------------------------- + + Copyrights updated on all changed files. + + test directory enhanced with four new tests. + + Gawk now generates a warning for \x without following hexadecimal digits. + In this case, it returns 'x', not \0. + + Several fixes in main.c related to variable initialization: + CONVFMT has a default value + resetup is called before initializing variables + the varinit table fixed up a bit (see the comments) + + gawk.1 updated with new BUG REPORTS section. + + A plain `print' inside a BEGIN or END now generates a lint warning (awk.y). + + Small fix in iop.c:get_a_record to avoid reading uninitialized memory. + + awk.y:yylex now does a better job of handling things if the source file + does not end in a newline. Probably there is more work to be done. + + Memory leaks fixed in awk.y, particularly in cases of duplicate function + parameters. Also, calling a function doesn't leak memory during parsing. + + Empty function bodies are now allowed (awk.y). + + Gawk now detects duplicate parameter names in functions (awk.y). + + New function `error' in msg.c added for use from awk.y. + + eval.c:r_get_lhs now checks if its argument is a parameter on the stack, + and pulls down the real variable. This catches more 'using an array as + a scalar' kinds of errors. + + main.c recovers C alloca space after parsing, this is important for + bison-based parsers. re.c recovers C alloca space after doing an research. + [Changes from Pat Rankin] + + builtin.c now declares the random() related functions based on + RANDOM_MISSING from config.h. [Suggested by Pat Rankin] + + awk.h now handles alloca correctly for HP-UX. [Kaveh Ghazi] + + regex.h and config/cray60 updated for Unicos 8.0. [Hal Peterson] + + Fixed re.c and dfa.c so that gawk no longer leaks memory when using + lots of dynamic regexps. + + Removed dependency on signed chars from `idx' variable in awk.h. Gawk + now passes its test suite if compiled with `gcc -fno-signed-char'. + + Fixed warning on close in io.c to go under lint control. Too many people + have complained about the spurious message, particularly when closing a + child pipeline early. + + Gawk now correctly handles RS = "" when input is from a terminal + (iop.c:get_a_record). + + Config file added for GNU. + + gawk 'BEGIN { exit 1 } ; END { exit }' now exits 1, as it should + (eval.c:interpret). + + sub and gsub now follow posix, \ escapes both & and \. Each \ must + be doubled initially in the program to get it into the string. + Thanks to Mike Brennan for pointing this out (builtin.c:sub_common). + + If FS is "", gawk behaves like mawk and nawk, making the whole record be $1. + Yet Another Dark Corner. Sigh (field.c:def_parse_field). + + Gawk now correctly recomputes string values for numbers if CONVFMT has + changed (awk.h:force_string, node.c:r_force_string). + + A regexp of the form `/* this looks like a comment but is not */' will + now generate a warning from --lint (awk.y). + + Gawk will no longer core dump if given an empty input file (awk.y:get_src_buf, + iop.c:optimal_bufsize). + + A printf format of the form %lf is handled correctly. The `l' generates + a lint warning (builtin.c:format_tree) [Thanks to Mark Moraes]. + + Lynxos config file added. + + `continue' outside a loop treated as `next' only in compatibility mode, + instead of by default; recent att nawk chokes on this now. `break' + outside a loop now treated as `next' in compatibility mode (eval.c). + + Bug fix in string concatenation, an arbitrary number of expressions + are allowed (eval.c). + + $1 += $2 now works correctly (eval.c). + + Changing IGNORECASE no longer resets field-splitting to FS if it was + using FIELDWIDTHS (eval.c, field.c). + + Major enhancement: $0 and NF for last record read are now preserved + into the END rule (io.c). + + Regexp fixes: + /./ now matches a newline (regex.h) + ^ and $ match beginning and end of string only, not any embedded + newlines (re.c) + regex.c should compile and work ok on 64-bit mips/sgi machines + Changes from 2.15.4 to 2.15.5 ----------------------------- diff -crN gawk-2.15.5/README.FIRST gawk-2.15.6/README.FIRST *** gawk-2.15.5/README.FIRST Wed Dec 31 19:00:00 1969 --- gawk-2.15.6/README.FIRST Sat Feb 18 23:08:33 1995 *************** *** 0 **** --- 1,21 ---- + Sat Feb 18 23:07:55 EST 1995 + + Starting with 2.15.6, gawk will preserve the value of NF and $0 for + the last record read into the END rule(s). This is important to you + if your program uses + + print + + in an END rule to mean + + print "" + + (i.e., print nothing). Examine your awk programs carefully to make sure + that they use `print ""' instead of `print', otherwise you will get + strange results. + + If you send me email about this, without having read this + file, I will yell at you. + + Arnold Robbins + arnold@skeeve.atl.ga.us diff -crN gawk-2.15.5/README.pc gawk-2.15.6/README.pc *** gawk-2.15.5/README.pc Thu Nov 25 10:35:15 1993 --- gawk-2.15.6/README.pc Tue Feb 21 09:14:25 1995 *************** *** 1,7 **** This is the README for GNU awk 2.15 under OS/2 and MS-DOS. Gawk has been compiled and tested under OS/2 1.x--2.x and MS-DOS ! using MSC 5.1, MSC 6.00A, and EMX/gcc 0.8g. Compiling for DOS from a DOS (or OS/2) host --- 1,7 ---- This is the README for GNU awk 2.15 under OS/2 and MS-DOS. Gawk has been compiled and tested under OS/2 1.x--2.x and MS-DOS ! using MSC 5.1, MSC 6.00A, and EMX/gcc 0.8[gh]. Compiling for DOS from a DOS (or OS/2) host *************** *** 10,16 **** Move the stuff in the pc directory to the directory with the rest of the gawk sources. The files Makefile.emx (for EMX/gcc) and Makefile.msc (for MSC 5.1 or 6.00A) should work with any Unix-like ! make, including Ndmake 4.5 and dmake 3.8. An alternative makegawk.bat file exists for compiling with MSC 5.1 or 6.00A. You may need to put CRs at the end of each line in the --- 10,16 ---- Move the stuff in the pc directory to the directory with the rest of the gawk sources. The files Makefile.emx (for EMX/gcc) and Makefile.msc (for MSC 5.1 or 6.00A) should work with any Unix-like ! make, including Ndmake 4.5 and dmake. An alternative makegawk.bat file exists for compiling with MSC 5.1 or 6.00A. You may need to put CRs at the end of each line in the *************** *** 31,37 **** Compiling for OS/2 or DOS from an OS/2 host ------------------------------------------- ! Move the files in the pc dirctory to the directory with the rest of the gawk sources. Makefile.os2 has been tested with dmake 3.8 and GNU make 3.68. Enter "make -f Makefile.os2" to see a list of targets. As an example, an OS/2 and DOS 32-bit executable using --- 31,37 ---- Compiling for OS/2 or DOS from an OS/2 host ------------------------------------------- ! Move the files in the pc directory to the directory with the rest of the gawk sources. Makefile.os2 has been tested with dmake 3.8 and GNU make 3.68. Enter "make -f Makefile.os2" to see a list of targets. As an example, an OS/2 and DOS 32-bit executable using *************** *** 40,67 **** If using MSC 5.1, you will also have to copy the Microsoft library routine setargv.obj to the gawk directory for the link to work. - Notes ----- 1. The usual shells for OS/2 and DOS (command.com for DOS and cmd.exe for OS/2) do not handle command-lines very well. Stewartson's sh (OS/2 ! and DOS) and GNU bash (OS/2 2.x) are good choices. Stewartson's shell ! 2.2 is in beta (as of 17-Sep-93). Earlier versions can be found at ! ! ftp.informatik.tu-muenchen.de:pub/comp/os/os2/shells/sh164-2.zip ! oak.oakland.edu:pub/msdos/sysutl/ms_sh21b.zip ! ftp-os2.cdrom.com:pub/os2/all/unix/shells/ms_sh21c.zip ! OS/2 HPFS users should obtain ms_sh21c.zip over ms_sh21b.zip. ! The Korn shell (ksh) may be another possibility: ! ftp.informatik.tu-muenchen.de:pub/comp/os/os2/shells/ksh48.zip ! Bash for OS/2 2.x can be found at ! ftp.informatik.tu-muenchen.de:pub/comp/os/os2/shells/gnu/gnubash.zip ! ftp-os2.cdrom.com:pub/os2/2_x/unix/shells/bash.zip 2. Stewartson's shell contains sources for a setargv-replacement --- 40,79 ---- If using MSC 5.1, you will also have to copy the Microsoft library routine setargv.obj to the gawk directory for the link to work. Notes ----- 1. The usual shells for OS/2 and DOS (command.com for DOS and cmd.exe for OS/2) do not handle command-lines very well. Stewartson's sh (OS/2 ! and DOS) is a good choice, and can be found at: ! oak.oakland.edu:SimTel/msdos/sysutil/ms_sh23[bs].zip ! ftp-os2.cdrom.com:pub/os2/16bit/unix/ms_sh23[bs].zip ! ftp.leo.org:pub/comp/os/os2/shells/ms_sh23b.zip ! An earlier version can be found at ! ftp.leo.org:pub/comp/os/os2/shells/sh164-2.zip ! The Korn shell (ksh) may be another possibility: ! ! ftp-os2.cdrom.com:pub/os2/32bit/unix/ksh49.zip ! ftp.leo.org:pub/comp/os/os2/shells/ksh513rt.zip ! ! Bash (OS/2 2.x) should be a good choice; however, there has been some ! trouble getting a solid version for OS/2. As of Feb-95, there are two ! bash ports, available in: ! ! ftp.leo.org:pub/comp/os/os2/shells/gnu/gnubash.zip ! ftp.leo.org:pub/comp/os/os2/shells/gnu/bash-112.zip ! ftp-os2.cdrom.com:pub/os2/32bit/unix/bash_112.zip ! ! Hamilton's C Shell is another possibility, available for a number of ! platforms. A demo is available at ftp.leo.org. ! ! The site ftp.leo.org (ftp.informatik.tu-muenchen.de) is maintained ! by Kai Uwe Rommel (rommel@leo.org), and is also accessible at ! http://www.leo.org/archiv/os2/ via WWW. 2. Stewartson's shell contains sources for a setargv-replacement *************** *** 70,106 **** 3. dmake is by Dennis Vadura (dvadura@watdragon.uwaterloo.ca), CS Dept., ! University of Waterloo. An OS/2 and DOS version can be found at ! ftp.informatik.tu-muenchen.de:pub/comp/os/os2/devtools/dmake38.zip ! ftp-os2.cdrom.com:pub/os2/all/program/dmake38x.zip Ndmake is by D.G. Kneller. This ShareWare program was later released as Opus Make (which is available for OS/2 and DOS). Ndmake 4.5 is available at ! oak.oakland.edu:pub/msdos/c/ndmake45.zip GNU make is from the FSF. An OS/2 2.x version can be found at ! ftp.informatik.tu-muenchen.de:pub/comp/os/os2/devtools/gnumake.zip ! ! The "lookup" feature of ncftp reports: ! ! ncftp>lookup ftp.informatik.tu-muenchen.de ! hpsystem2.informatik.tu-muenchen.de 131.159.0.198 ! ! ncftp>lookup ftp-os2.cdrom.com ! wcarchive.cdrom.com 192.153.46.2 ! ! ncftp>lookup oak.oakland.edu ! rigel.acs.oakland.edu 141.210.10.117 4. Known bugs. The MSC 5.1 bound version has not received extensive testing. When running under OS/2 2.1, there is a bug which may be related to the 20-file limit. It can be observed in the "manyfiles" test of test/Makefile. This does not occur when running under DOS. ---- --- 82,111 ---- 3. dmake is by Dennis Vadura (dvadura@watdragon.uwaterloo.ca), CS Dept., ! University of Waterloo. OS/2 and DOS versions can be found at ! ftp.leo.org:pub/comp/os/os2/devtools/utils/dmake38.zip ! ftp.leo.org:pub/comp/os/os2/devtools/utils/dmake40os2.zip ! ftp-os2.cdrom.com:pub/os2/16bit/program/dmake38x.zip Ndmake is by D.G. Kneller. This ShareWare program was later released as Opus Make (which is available for OS/2 and DOS). Ndmake 4.5 is available at ! oak.oakland.edu:SimTel/msdos/c/ndmake45.zip GNU make is from the FSF. An OS/2 2.x version can be found at ! ftp.leo.org:pub/comp/os/os2/devtools/gnu/gnumake.zip 4. Known bugs. The MSC 5.1 bound version has not received extensive testing. When running under OS/2 2.1, there is a bug which may be related to the 20-file limit. It can be observed in the "manyfiles" test of test/Makefile. This does not occur when running under DOS. + + The 16-bit DOS version can exhaust memory on scripts such as Henry + Spencer's "awf". Use the 32-bit version if possible. ---- diff -crN gawk-2.15.5/README.yacc gawk-2.15.6/README.yacc *** gawk-2.15.5/README.yacc Wed Dec 31 19:00:00 1969 --- gawk-2.15.6/README.yacc Sat Jan 28 22:09:17 1995 *************** *** 0 **** --- 1,7 ---- + Sat Jan 28 22:07:17 EST 1995 + + Some older versions of yacc (notably Ultrix's) have limits on the depth + of the parse stack. This only shows up when gawk is dealing with deeply + nested control structures, such as those in `awf'. + + The problem goes away if you use either bison or Berkeley yacc. diff -crN gawk-2.15.5/awk.h gawk-2.15.6/awk.h *** gawk-2.15.5/awk.h Wed May 11 22:28:46 1994 --- gawk-2.15.6/awk.h Thu Mar 9 11:26:41 1995 *************** *** 3,9 **** */ /* ! * Copyright (C) 1986, 1988, 1989, 1991, 1992, 1993 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. --- 3,9 ---- */ /* ! * Copyright (C) 1986, 1988, 1989, 1991-1995 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. *************** *** 116,122 **** --- 116,126 ---- #if defined(_MSC_VER) #include #else + #ifdef __hpux + void *alloca (); + #else extern char *alloca(); + #endif /* __hpux */ #endif /* _MSC_VER */ #endif #endif /* sparc */ *************** *** 365,371 **** char *sp; size_t slen; unsigned char sref; ! char idx; } val; struct { struct exp_node *next; --- 369,375 ---- char *sp; size_t slen; unsigned char sref; ! int idx; } val; struct { struct exp_node *next; *************** *** 632,638 **** #else /* not MSDOS */ #define force_number(n) (_t = (n),(_t->flags & NUM) ? _t->numbr : r_force_number(_t)) #endif /* MSDOS */ ! #define force_string(s) (_t = (s),(_t->flags & STR) ? _t : r_force_string(_t)) #endif /* not DEBUG */ #define STREQ(a,b) (*(a) == *(b) && strcmp((a), (b)) == 0) --- 636,642 ---- #else /* not MSDOS */ #define force_number(n) (_t = (n),(_t->flags & NUM) ? _t->numbr : r_force_number(_t)) #endif /* MSDOS */ ! #define force_string(s) (_t = (s),((_t->flags & STR) && (_t->stfmt == -1 || _t->stfmt == CONVFMTidx))? _t : r_force_string(_t)) #endif /* not DEBUG */ #define STREQ(a,b) (*(a) == *(b) && strcmp((a), (b)) == 0) *************** *** 700,705 **** --- 704,710 ---- extern NODE **get_field P((int num, Func_ptr *assign)); extern NODE *do_split P((NODE *tree)); extern void set_FS P((void)); + extern void set_FS_if_not_FIELDWIDTHS P((void)); extern void set_RS P((void)); extern void set_FIELDWIDTHS P((void)); /* io.c */ *************** *** 728,737 **** --- 733,744 ---- extern void err P((const char *s, const char *emsg, va_list argp)); #if _MSC_VER == 510 extern void msg P((va_list va_alist, ...)); + extern void error P((va_list va_alist, ...)); extern void warning P((va_list va_alist, ...)); extern void fatal P((va_list va_alist, ...)); #else extern void msg (); + extern void error (); extern void warning (); extern void fatal (); #endif diff -crN gawk-2.15.5/awk.y gawk-2.15.6/awk.y *** gawk-2.15.5/awk.y Wed May 11 22:35:16 1994 --- gawk-2.15.6/awk.y Thu Mar 9 11:26:55 1995 *************** *** 3,9 **** */ /* ! * Copyright (C) 1986, 1988, 1989, 1991, 1992, 1993 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. --- 3,9 ---- */ /* ! * Copyright (C) 1986, 1988, 1989, 1991-1995 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. *************** *** 43,48 **** --- 43,49 ---- static void pop_params P((NODE *params)); static NODE *make_param P((char *name)); static NODE *mk_rexp P((NODE *exp)); + static int dup_parms P((NODE *func)); static int want_assign; /* lexical scanning kludge */ static int want_regexp; /* lexical scanning kludge */ *************** *** 264,269 **** --- 265,273 ---- { $$ = append_right(make_param($3), $5); can_return = 1; + /* check for duplicate parameter names */ + if (dup_parms($$)) + errcount++; } ; *************** *** 273,278 **** --- 277,287 ---- $$ = $2; can_return = 0; } + | l_brace r_brace opt_semi opt_nls + { + $$ = node((NODE *) NULL, Node_K_return, (NODE *) NULL); + can_return = 0; + } ; *************** *** 373,385 **** { $$ = node ($3, $1, $5); } | print opt_rexpression_list output_redir statement_term { ! if ($1 == Node_K_print && $2 == NULL) $2 = node(node(make_number(0.0), Node_field_spec, (NODE *) NULL), Node_expression_list, (NODE *) NULL); $$ = node ($2, $1, $3); } | LEX_NEXT opt_exp statement_term --- 382,403 ---- { $$ = node ($3, $1, $5); } | print opt_rexpression_list output_redir statement_term { ! if ($1 == Node_K_print && $2 == NULL) { ! static int warned = 0; ! $2 = node(node(make_number(0.0), Node_field_spec, (NODE *) NULL), Node_expression_list, (NODE *) NULL); + if (do_lint && ! io_allowed && ! warned) { + warned = 1; + warning( + "plain `print' in BEGIN or END rule should probably be `print \"\"'"); + } + } + $$ = node ($2, $1, $3); } | LEX_NEXT opt_exp statement_term *************** *** 394,405 **** * the source line */ errcount++; ! msg("`next file' is a gawk extension"); } if (! io_allowed) { /* same thing */ errcount++; ! msg("`next file' used in BEGIN or END action"); } type = Node_K_nextfile; } else { --- 412,423 ---- * the source line */ errcount++; ! error("`next file' is a gawk extension"); } if (! io_allowed) { /* same thing */ errcount++; ! error("`next file' used in BEGIN or END action"); } type = Node_K_nextfile; } else { *************** *** 427,433 **** * the source line */ errcount++; ! msg("`delete array' is a gawk extension"); } $$ = node (variable($2,1), Node_K_delete, (NODE *) NULL); } --- 445,451 ---- * the source line */ errcount++; ! error("`delete array' is a gawk extension"); } $$ = node (variable($2,1), Node_K_delete, (NODE *) NULL); } *************** *** 596,602 **** $$ = node ($1, $2, mk_rexp($3)); } | regexp ! { $$ = $1; } | '!' regexp %prec UNARY { $$ = node(node(make_number(0.0), --- 614,628 ---- $$ = node ($1, $2, mk_rexp($3)); } | regexp ! { ! $$ = $1; ! if (do_lint && tokstart[0] == '*') { ! /* possible C comment */ ! int n = strlen(tokstart) - 1; ! if (tokstart[n] == '*') ! warning("regexp looks like a C comment, but is not"); ! } ! } | '!' regexp %prec UNARY { $$ = node(node(make_number(0.0), *************** *** 700,705 **** --- 726,732 ---- | FUNC_CALL '(' opt_expression_list r_paren { $$ = node ($3, Node_func_call, make_string($1, strlen($1))); + free($1); } | variable | INCREMENT variable *************** *** 1014,1022 **** if (n == 0) { samefile = 0; nextfile++; ! *lexeme = '\0'; len = 0; ! return get_src_buf(); } lexptr = buf + SLOP; lexend = lexptr + n; --- 1041,1050 ---- if (n == 0) { samefile = 0; nextfile++; ! if (lexeme) ! *lexeme = '\0'; len = 0; ! goto again; } lexptr = buf + SLOP; lexend = lexptr + n; *************** *** 1045,1056 **** #if DEBUG char nextc() { if (lexptr && lexptr < lexend) ! return *lexptr++; else if (get_src_buf()) ! return *lexptr++; else ! return '\0'; } #else #define nextc() ((lexptr && lexptr < lexend) ? \ --- 1073,1088 ---- #if DEBUG char nextc() { + int c; + if (lexptr && lexptr < lexend) ! c = *lexptr++; else if (get_src_buf()) ! c = *lexptr++; else ! c = '\0'; ! ! return c; } #else #define nextc() ((lexptr && lexptr < lexend) ? \ *************** *** 1074,1082 **** int low, mid, high; static int did_newline = 0; char *tokkey; ! if (!nextc()) return 0; pushback(); #ifdef OS2 /* --- 1106,1124 ---- int low, mid, high; static int did_newline = 0; char *tokkey; + static int lasttok = 0, eof_warned = 0; ! if (!nextc()) { ! if (lasttok != NEWLINE) { ! lasttok = NEWLINE; ! if (do_lint && ! eof_warned) { ! warning("source file does not end in newline"); ! eof_warned = 1; ! } ! return NEWLINE; /* fake it */ ! } return 0; + } pushback(); #ifdef OS2 /* *************** *** 1119,1125 **** pushback(); tokadd('\0'); yylval.sval = tokstart; ! return REGEXP; case '\n': pushback(); yyerror("unterminated regexp"); --- 1161,1167 ---- pushback(); tokadd('\0'); yylval.sval = tokstart; ! return lasttok = REGEXP; case '\n': pushback(); yyerror("unterminated regexp"); *************** *** 1140,1158 **** switch (c) { case 0: return 0; case '\n': sourceline++; ! return NEWLINE; case '#': /* it's a comment */ while ((c = nextc()) != '\n') { ! if (c == '\0') return 0; } sourceline++; ! return NEWLINE; case '\\': #ifdef RELAXED_CONTINUATION --- 1182,1218 ---- switch (c) { case 0: + if (lasttok != NEWLINE) { + lasttok = NEWLINE; + if (do_lint && ! eof_warned) { + warning("source file does not end in newline"); + eof_warned = 1; + } + return NEWLINE; /* fake it */ + } return 0; case '\n': sourceline++; ! return lasttok = NEWLINE; case '#': /* it's a comment */ while ((c = nextc()) != '\n') { ! if (c == '\0') { ! if (lasttok != NEWLINE) { ! lasttok = NEWLINE; ! if (do_lint && ! eof_warned) { ! warning( ! "source file does not end in newline"); ! eof_warned = 1; ! } ! return NEWLINE; /* fake it */ ! } return 0; + } } sourceline++; ! return lasttok = NEWLINE; case '\\': #ifdef RELAXED_CONTINUATION *************** *** 1182,1188 **** case '$': want_assign = 1; ! return '$'; case ')': case ']': --- 1242,1248 ---- case '$': want_assign = 1; ! return lasttok = '$'; case ')': case ']': *************** *** 1193,1207 **** case '?': case '{': case ',': ! return c; case '*': if ((c = nextc()) == '=') { yylval.nodetypeval = Node_assign_times; ! return ASSIGNOP; } else if (do_posix) { pushback(); ! return '*'; } else if (c == '*') { /* make ** and **= aliases for ^ and ^= */ static int did_warn_op = 0, did_warn_assgn = 0; --- 1253,1267 ---- case '?': case '{': case ',': ! return lasttok = c; case '*': if ((c = nextc()) == '=') { yylval.nodetypeval = Node_assign_times; ! return lasttok = ASSIGNOP; } else if (do_posix) { pushback(); ! return lasttok = '*'; } else if (c == '*') { /* make ** and **= aliases for ^ and ^= */ static int did_warn_op = 0, did_warn_assgn = 0; *************** *** 1212,1247 **** warning("**= is not allowed by POSIX"); } yylval.nodetypeval = Node_assign_exp; ! return ASSIGNOP; } else { pushback(); if (do_lint && ! did_warn_op) { did_warn_op = 1; warning("** is not allowed by POSIX"); } ! return '^'; } } pushback(); ! return '*'; case '/': if (want_assign) { if (nextc() == '=') { yylval.nodetypeval = Node_assign_quotient; ! return ASSIGNOP; } pushback(); } ! return '/'; case '%': if (nextc() == '=') { yylval.nodetypeval = Node_assign_mod; ! return ASSIGNOP; } pushback(); ! return '%'; case '^': { --- 1272,1307 ---- warning("**= is not allowed by POSIX"); } yylval.nodetypeval = Node_assign_exp; ! return lasttok = ASSIGNOP; } else { pushback(); if (do_lint && ! did_warn_op) { did_warn_op = 1; warning("** is not allowed by POSIX"); } ! return lasttok = '^'; } } pushback(); ! return lasttok = '*'; case '/': if (want_assign) { if (nextc() == '=') { yylval.nodetypeval = Node_assign_quotient; ! return lasttok = ASSIGNOP; } pushback(); } ! return lasttok = '/'; case '%': if (nextc() == '=') { yylval.nodetypeval = Node_assign_mod; ! return lasttok = ASSIGNOP; } pushback(); ! return lasttok = '%'; case '^': { *************** *** 1254,1326 **** warning("operator `^=' is not supported in old awk"); } yylval.nodetypeval = Node_assign_exp; ! return ASSIGNOP; } pushback(); if (do_lint && ! did_warn_op) { did_warn_op = 1; warning("operator `^' is not supported in old awk"); } ! return '^'; } case '+': if ((c = nextc()) == '=') { yylval.nodetypeval = Node_assign_plus; ! return ASSIGNOP; } if (c == '+') ! return INCREMENT; pushback(); ! return '+'; case '!': if ((c = nextc()) == '=') { yylval.nodetypeval = Node_notequal; ! return RELOP; } if (c == '~') { yylval.nodetypeval = Node_nomatch; want_assign = 0; ! return MATCHOP; } pushback(); ! return '!'; case '<': if (nextc() == '=') { yylval.nodetypeval = Node_leq; ! return RELOP; } yylval.nodetypeval = Node_less; pushback(); ! return '<'; case '=': if (nextc() == '=') { yylval.nodetypeval = Node_equal; ! return RELOP; } yylval.nodetypeval = Node_assign; pushback(); ! return ASSIGNOP; case '>': if ((c = nextc()) == '=') { yylval.nodetypeval = Node_geq; ! return RELOP; } else if (c == '>') { yylval.nodetypeval = Node_redirect_append; ! return APPEND_OP; } yylval.nodetypeval = Node_greater; pushback(); ! return '>'; case '~': yylval.nodetypeval = Node_match; want_assign = 0; ! return MATCHOP; case '}': /* --- 1314,1386 ---- warning("operator `^=' is not supported in old awk"); } yylval.nodetypeval = Node_assign_exp; ! return lasttok = ASSIGNOP; } pushback(); if (do_lint && ! did_warn_op) { did_warn_op = 1; warning("operator `^' is not supported in old awk"); } ! return lasttok = '^'; } case '+': if ((c = nextc()) == '=') { yylval.nodetypeval = Node_assign_plus; ! return lasttok = ASSIGNOP; } if (c == '+') ! return lasttok = INCREMENT; pushback(); ! return lasttok = '+'; case '!': if ((c = nextc()) == '=') { yylval.nodetypeval = Node_notequal; ! return lasttok = RELOP; } if (c == '~') { yylval.nodetypeval = Node_nomatch; want_assign = 0; ! return lasttok = MATCHOP; } pushback(); ! return lasttok = '!'; case '<': if (nextc() == '=') { yylval.nodetypeval = Node_leq; ! return lasttok = RELOP; } yylval.nodetypeval = Node_less; pushback(); ! return lasttok = '<'; case '=': if (nextc() == '=') { yylval.nodetypeval = Node_equal; ! return lasttok = RELOP; } yylval.nodetypeval = Node_assign; pushback(); ! return lasttok = ASSIGNOP; case '>': if ((c = nextc()) == '=') { yylval.nodetypeval = Node_geq; ! return lasttok = RELOP; } else if (c == '>') { yylval.nodetypeval = Node_redirect_append; ! return lasttok = APPEND_OP; } yylval.nodetypeval = Node_greater; pushback(); ! return lasttok = '>'; case '~': yylval.nodetypeval = Node_match; want_assign = 0; ! return lasttok = MATCHOP; case '}': /* *************** *** 1329,1339 **** */ if (did_newline) { did_newline = 0; ! return c; } did_newline++; --lexptr; /* pick up } next time */ ! return NEWLINE; case '"': esc_seen = 0; --- 1389,1399 ---- */ if (did_newline) { did_newline = 0; ! return lasttok = c; } did_newline++; --lexptr; /* pick up } next time */ ! return lasttok = NEWLINE; case '"': esc_seen = 0; *************** *** 1360,1382 **** yylval.nodeval = make_str_node(tokstart, tok - tokstart, esc_seen ? SCAN : 0); yylval.nodeval->flags |= PERM; ! return YSTRING; case '-': if ((c = nextc()) == '=') { yylval.nodetypeval = Node_assign_minus; ! return ASSIGNOP; } if (c == '-') ! return DECREMENT; pushback(); ! return '-'; case '.': c = nextc(); pushback(); if (!isdigit(c)) ! return '.'; else c = '.'; /* FALL THROUGH */ case '0': --- 1420,1442 ---- yylval.nodeval = make_str_node(tokstart, tok - tokstart, esc_seen ? SCAN : 0); yylval.nodeval->flags |= PERM; ! return lasttok = YSTRING; case '-': if ((c = nextc()) == '=') { yylval.nodetypeval = Node_assign_minus; ! return lasttok = ASSIGNOP; } if (c == '-') ! return lasttok = DECREMENT; pushback(); ! return lasttok = '-'; case '.': c = nextc(); pushback(); if (!isdigit(c)) ! return lasttok = '.'; else c = '.'; /* FALL THROUGH */ case '0': *************** *** 1432,1441 **** break; c = nextc(); } ! pushback(); yylval.nodeval = make_number(atof(tokstart)); yylval.nodeval->flags |= PERM; ! return YNUMBER; case '&': if ((c = nextc()) == '&') { --- 1492,1507 ---- break; c = nextc(); } ! if (c != 0) ! pushback(); ! else if (do_lint && ! eof_warned) { ! warning("source file does not end in newline"); ! eof_warned = 1; ! } ! tokadd('\0'); yylval.nodeval = make_number(atof(tokstart)); yylval.nodeval->flags |= PERM; ! return lasttok = YNUMBER; case '&': if ((c = nextc()) == '&') { *************** *** 1458,1467 **** } } want_assign = 0; ! return LEX_AND; } pushback(); ! return '&'; case '|': if ((c = nextc()) == '|') { --- 1524,1533 ---- } } want_assign = 0; ! return lasttok = LEX_AND; } pushback(); ! return lasttok = '&'; case '|': if ((c = nextc()) == '|') { *************** *** 1484,1493 **** } } want_assign = 0; ! return LEX_OR; } pushback(); ! return '|'; } if (c != '_' && ! isalpha(c)) --- 1550,1559 ---- } } want_assign = 0; ! return lasttok = LEX_OR; } pushback(); ! return lasttok = '|'; } if (c != '_' && ! isalpha(c)) *************** *** 1502,1508 **** tokadd('\0'); emalloc(tokkey, char *, tok - tokstart, "yylex"); memcpy(tokkey, tokstart, tok - tokstart); ! pushback(); /* See if it is a special token. */ low = 0; --- 1568,1579 ---- tokadd('\0'); emalloc(tokkey, char *, tok - tokstart, "yylex"); memcpy(tokkey, tokstart, tok - tokstart); ! if (c != 0) ! pushback(); ! else if (do_lint && ! eof_warned) { ! warning("source file does not end in newline"); ! eof_warned = 1; ! } /* See if it is a special token. */ low = 0; *************** *** 1541,1556 **** yylval.nodetypeval = tokentab[mid].value; free(tokkey); ! return tokentab[mid].class; } } yylval.sval = tokkey; if (*lexptr == '(') ! return FUNC_CALL; else { want_assign = 1; ! return NAME; } } --- 1612,1627 ---- yylval.nodetypeval = tokentab[mid].value; free(tokkey); ! return lasttok = tokentab[mid].class; } } yylval.sval = tokkey; if (*lexptr == '(') ! return lasttok = FUNC_CALL; else { want_assign = 1; ! return lasttok = NAME; } } *************** *** 1758,1763 **** --- 1829,1873 ---- return oldlist; } + /* return 1 if there are duplicate parameters, 0 means all ok */ + static int + dup_parms(func) + NODE *func; + { + register NODE *np; + char *fname, **names; + int count, i, j, dups; + NODE *params; + + fname = func->param; + count = func->param_cnt; + params = func->rnode; + + if (count == 0) /* no args, no problem */ + return 0; + + emalloc(names, char **, count * sizeof(char *), "dup_parms"); + + i = 0; + for (np = params; np != NULL; np = np->rnode) + names[i++] = np->param; + + dups = 0; + for (i = 1; i < count; i++) { + for (j = 0; j < i; j++) { + if (strcmp(names[i], names[j]) == 0) { + dups++; + error( + "function `%s': parameter #%d, `%s', duplicates parameter #%d", + fname, i+1, names[j], j+1); + } + } + } + + free(names); + return (dups > 0); + } + /* * check if name is already installed; if so, it had better have Null value, * in which case def is added as the value. Otherwise, install name with def *************** *** 1803,1816 **** } } static void pop_params(params) NODE *params; { ! register NODE *np; ! ! for (np = params; np != NULL; np = np->rnode) ! pop_var(np, 1); } static NODE * --- 1913,1930 ---- } } + /* + * pop parameters out of the symbol table. do this in reverse order to + * avoid reading freed memory if there were duplicated parameters. + */ static void pop_params(params) NODE *params; { ! if (params == NULL) ! return; ! pop_params(params->rnode); ! pop_var(params, 1); } static NODE * *************** *** 1827,1833 **** return (install(name, r)); } ! /* Name points to a variable name. Make sure its in the symbol table */ NODE * variable(name, can_free) char *name; --- 1941,1947 ---- return (install(name, r)); } ! /* Name points to a variable name. Make sure it's in the symbol table */ NODE * variable(name, can_free) char *name; diff -crN gawk-2.15.5/builtin.c gawk-2.15.6/builtin.c *** gawk-2.15.5/builtin.c Thu May 19 00:34:01 1994 --- gawk-2.15.6/builtin.c Thu Mar 9 11:27:08 1995 *************** *** 3,9 **** */ /* ! * Copyright (C) 1986, 1988, 1989, 1991, 1992, 1993 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. --- 3,9 ---- */ /* ! * Copyright (C) 1986, 1988, 1989, 1991-1995 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. *************** *** 29,35 **** #ifndef SRANDOM_PROTO extern void srandom P((unsigned int seed)); #endif ! #ifndef linux extern char *initstate P((unsigned seed, char *state, int n)); extern char *setstate P((char *state)); extern long random P((void)); --- 29,35 ---- #ifndef SRANDOM_PROTO extern void srandom P((unsigned int seed)); #endif ! #if defined(RANDOM_MISSING) extern char *initstate P((unsigned seed, char *state, int n)); extern char *setstate P((char *state)); extern long random P((void)); *************** *** 441,448 **** case 'l': if (big) break; big++; ! goto check_pos; case 'c': parse_next_arg(); if (arg->flags & NUMBER) { --- 441,458 ---- case 'l': if (big) break; + else { + static int warned = 0; + + if (do_lint && ! warned) { + warning("`l' is meaningless in awk formats; ignored"); + warned++; + } + if (do_posix) + fatal("'l' is not permitted in POSIX awk formats"); + } big++; ! goto retry; case 'c': parse_next_arg(); if (arg->flags & NUMBER) { *************** *** 1076,1082 **** if (*scan == '&') { repllen--; ampersands++; ! } else if (*scan == '\\' && *(scan+1) == '&') { repllen--; scan++; } --- 1086,1093 ---- if (*scan == '&') { repllen--; ampersands++; ! } else if (*scan == '\\' ! && (*(scan+1) == '&' || *(scan+1) == '\\')) { repllen--; scan++; } *************** *** 1095,1101 **** len = matchstart - text + repllen + ampersands * (matchend - matchstart); sofar = bp - buf; ! while ((long)(buflen - sofar - len - 1) < 0) { buflen *= 2; erealloc(buf, char *, buflen, "do_sub"); bp = buf + sofar; --- 1106,1112 ---- len = matchstart - text + repllen + ampersands * (matchend - matchstart); sofar = bp - buf; ! while (buflen < (sofar + len + 1)) { buflen *= 2; erealloc(buf, char *, buflen, "do_sub"); bp = buf + sofar; *************** *** 1106,1112 **** if (*scan == '&') for (cp = matchstart; cp < matchend; cp++) *bp++ = *cp; ! else if (*scan == '\\' && *(scan+1) == '&') { scan++; *bp++ = *scan; } else --- 1117,1124 ---- if (*scan == '&') for (cp = matchstart; cp < matchend; cp++) *bp++ = *cp; ! else if (*scan == '\\' ! && (*(scan+1) == '&' || *(scan+1) == '\\')) { scan++; *bp++ = *scan; } else diff -crN gawk-2.15.5/config/cray60 gawk-2.15.6/config/cray60 *** gawk-2.15.5/config/cray60 Mon May 9 22:44:10 1994 --- gawk-2.15.6/config/cray60 Sat Feb 18 22:54:52 1995 *************** *** 1,7 **** ! Cray Research system running Unicos 6.0 SIGTYPE void RANDOM_MISSING 1 STDC_HEADERS 1 CHAR_UNSIGNED 1 GETPGRP_NOARG 1 MAKE_ALLOCA_C --- 1,8 ---- ! Cray Research system running Unicos 6.0 or later SIGTYPE void RANDOM_MISSING 1 STDC_HEADERS 1 + SRANDOM_PROTO 1 CHAR_UNSIGNED 1 GETPGRP_NOARG 1 MAKE_ALLOCA_C diff -crN gawk-2.15.5/config/gnu gawk-2.15.6/config/gnu *** gawk-2.15.5/config/gnu Wed Dec 31 19:00:00 1969 --- gawk-2.15.6/config/gnu Mon Dec 19 06:58:23 1994 *************** *** 0 **** --- 1,6 ---- + For the GNU operating system. + + SIGTYPE void + HAVE_UNDERSCORE_SETJMP 1 + STDC_HEADERS 1 + GETPGRP_NOARG 1 diff -crN gawk-2.15.5/config/lynxos gawk-2.15.6/config/lynxos *** gawk-2.15.5/config/lynxos Wed Dec 31 19:00:00 1969 --- gawk-2.15.6/config/lynxos Sun Nov 20 10:07:17 1994 *************** *** 0 **** --- 1,10 ---- + For Lynx version 2.1 + SIGTYPE int + STDC_HEADERS 1 + HAVE_STRING_H 1 + STRCASE_MISSING 1 + STRERROR_MISSING 1 + STRFTIME_MISSING 1 + TZNAME_MISSING 1 + TZSET_MISSING 1 + TM_ZONE_MISSING 1 diff -crN gawk-2.15.5/config/sgi405 gawk-2.15.6/config/sgi405 *** gawk-2.15.5/config/sgi405 Fri Apr 29 06:49:21 1994 --- gawk-2.15.6/config/sgi405 Sun Feb 12 11:28:28 1995 *************** *** 2,4 **** --- 2,5 ---- BLKSIZE_MISSING 1 STDC_HEADERS 1 GETPGRP_NOARG 1 + MAKE_SGI_GCC diff -crN gawk-2.15.5/config/vms-posix gawk-2.15.6/config/vms-posix *** gawk-2.15.5/config/vms-posix Tue Dec 7 23:14:30 1993 --- gawk-2.15.6/config/vms-posix Mon Mar 6 06:46:19 1995 *************** *** 8,13 **** --- 8,14 ---- MAKE_CC #define DEFAULT_FILETYPE ".awk" #define getopt gnu_getopt + #define optopt gnu_optopt #define opterr gnu_opterr #define regcomp gnu_regcomp #define regexec gnu_regexec diff -crN gawk-2.15.5/dfa.c gawk-2.15.6/dfa.c *** gawk-2.15.5/dfa.c Sun Apr 17 17:14:23 1994 --- gawk-2.15.6/dfa.c Tue Feb 14 22:51:34 1995 *************** *** 2035,2040 **** --- 2035,2041 ---- if (d->realtrans) free((ptr_t) d->realtrans); if (d->fails) free((ptr_t) d->fails); if (d->newlines) free((ptr_t) d->newlines); + if (d->success) free((ptr_t) d->success); for (dm = d->musts; dm; dm = ndm) { ndm = dm->next; diff -crN gawk-2.15.5/eval.c gawk-2.15.6/eval.c *** gawk-2.15.5/eval.c Tue May 10 21:58:13 1994 --- gawk-2.15.6/eval.c Thu Mar 9 11:27:27 1995 *************** *** 3,9 **** */ /* ! * Copyright (C) 1986, 1988, 1989, 1991, 1992, 1993 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. --- 3,9 ---- */ /* ! * Copyright (C) 1986, 1988, 1989, 1991-1995 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. *************** *** 288,304 **** } case Node_K_break: ! if (loop_tag_valid == 0) ! fatal("unexpected break"); ! longjmp(loop_tag, TAG_BREAK); break; case Node_K_continue: if (loop_tag_valid == 0) { /* ! * AT&T nawk treats continue outside of loops like ! * next. Allow it if not posix, and complain if ! * lint. */ static int warned = 0; --- 288,318 ---- } case Node_K_break: ! if (loop_tag_valid == 0) { ! /* ! * Old AT&T nawk treats break outside of loops like ! * next. New ones catch it at parse time. Allow it if ! * do_unix is on, and complain if lint. ! */ ! static int warned = 0; ! ! if (do_lint && ! warned) { ! warning("use of `break' outside of loop is not portable"); ! warned = 1; ! } ! if (! do_unix) ! fatal("use of `break' outside of loop is not allowed"); ! longjmp(rule_tag, TAG_CONTINUE); ! } else ! longjmp(loop_tag, TAG_BREAK); break; case Node_K_continue: if (loop_tag_valid == 0) { /* ! * Old AT&T nawk treats continue outside of loops like ! * next. New ones catch it at parse time. Allow it if ! * do_unix is on, and complain if lint. */ static int warned = 0; *************** *** 306,312 **** warning("use of `continue' outside of loop is not portable"); warned = 1; } ! if (do_posix) fatal("use of `continue' outside of loop is not allowed"); longjmp(rule_tag, TAG_CONTINUE); } else --- 320,326 ---- warning("use of `continue' outside of loop is not portable"); warned = 1; } ! if (! do_unix) fatal("use of `continue' outside of loop is not allowed"); longjmp(rule_tag, TAG_CONTINUE); } else *************** *** 345,355 **** * are not done. So we immediately break out of the main loop. */ exiting = 1; ! if (tree) { t = tree_eval(tree->lnode); exit_val = (int) force_number(t); } - free_temp(t); longjmp(rule_tag, TAG_BREAK); break; --- 359,369 ---- * are not done. So we immediately break out of the main loop. */ exiting = 1; ! if (tree->lnode) { t = tree_eval(tree->lnode); exit_val = (int) force_number(t); + free_temp(t); } longjmp(rule_tag, TAG_BREAK); break; *************** *** 499,512 **** case Node_concat: { ! #define STACKSIZE 10 ! NODE *treelist[STACKSIZE+1]; ! NODE *strlist[STACKSIZE+1]; register NODE **treep; register NODE **strp; register size_t len; char *str; register char *dest; /* * This is an efficiency hack for multiple adjacent string --- 513,527 ---- case Node_concat: { ! NODE **treelist; ! NODE **strlist; ! NODE *save_tree; register NODE **treep; register NODE **strp; register size_t len; char *str; register char *dest; + int count; /* * This is an efficiency hack for multiple adjacent string *************** *** 516,527 **** * descend to lowest (first) node, accumulating nodes * to evaluate to strings as we go. */ treep = treelist; ! while (tree->type == Node_concat) { *treep++ = tree->rnode; tree = tree->lnode; - if (treep == &treelist[STACKSIZE]) - break; } *treep = tree; /* --- 531,556 ---- * descend to lowest (first) node, accumulating nodes * to evaluate to strings as we go. */ + + /* + * But first, no arbitrary limits. Count the number of + * nodes and malloc the treelist and strlist arrays. + * There will be count + 1 items to concatenate. We + * also leave room for an extra pointer at the end to + * use as a sentinel. Thus, start count at 2. + */ + save_tree = tree; + for (count = 2; tree && tree->type == Node_concat; tree = tree->lnode) + count++; + tree = save_tree; + emalloc(treelist, NODE **, sizeof(NODE *) * count, "tree_eval"); + emalloc(strlist, NODE **, sizeof(NODE *) * count, "tree_eval"); + + /* Now, here we go. */ treep = treelist; ! while (tree && tree->type == Node_concat) { *treep++ = tree->rnode; tree = tree->lnode; } *treep = tree; /* *************** *** 549,554 **** --- 578,586 ---- } r = make_str_node(str, len, ALREADY_MALLOCED); r->flags |= TEMP; + + free(strlist); + free(treelist); } return r; *************** *** 793,798 **** --- 825,838 ---- tmp = tree_eval(tree->rnode); rval = force_number(tmp); free_temp(tmp); + + /* + * Do this again; the lhs and the rhs could both be fields. + * Accessing the rhs could cause the lhs to have moved around. + * (Yet another special case. Gack.) + */ + lhs = get_lhs(tree->lnode, &after_assign); + unref(*lhs); switch(tree->type) { case Node_assign_exp: *************** *** 1027,1032 **** --- 1067,1075 ---- register NODE **aptr = NULL; register NODE *n; + if (ptr->type == Node_param_list) + ptr = stack_ptr[ptr->param_cnt]; + switch (ptr->type) { case Node_var_array: fatal("attempt to use array `%s' in a scalar context", ptr->vname); *************** *** 1186,1192 **** warning("IGNORECASE not supported in compatibility mode"); } IGNORECASE = (force_number(IGNORECASE_node->var_value) != 0.0); ! set_FS(); } void --- 1229,1235 ---- warning("IGNORECASE not supported in compatibility mode"); } IGNORECASE = (force_number(IGNORECASE_node->var_value) != 0.0); ! set_FS_if_not_FIELDWIDTHS(); } void diff -crN gawk-2.15.5/field.c gawk-2.15.6/field.c *** gawk-2.15.5/field.c Wed May 18 07:26:41 1994 --- gawk-2.15.6/field.c Thu Mar 9 11:27:41 1995 *************** *** 3,9 **** */ /* ! * Copyright (C) 1986, 1988, 1989, 1991, 1992, 1993 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. --- 3,9 ---- */ /* ! * Copyright (C) 1986, 1988, 1989, 1991-1995 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. *************** *** 298,303 **** --- 298,313 ---- if (len == 0) return nf; + /* + * Nasty special case. If FS set to "", return whole record + * as first field. This is not worth a separate function. + */ + if (fs->stlen == 0) { + (*set)(++nf, *buf, len, n); + *buf += len; + return nf; + } + /* before doing anything save the char at *end */ sav = *end; /* because it will be destroyed now: */ *************** *** 675,678 **** --- 685,695 ---- scan = end; } FIELDWIDTHS[i] = -1; + } + + void + set_FS_if_not_FIELDWIDTHS() + { + if (parse_field != fw_parse_field) + set_FS(); } diff -crN gawk-2.15.5/gawk.1 gawk-2.15.6/gawk.1 *** gawk-2.15.5/gawk.1 Mon Apr 18 18:04:03 1994 --- gawk-2.15.6/gawk.1 Thu Jan 5 14:26:24 1995 *************** *** 1,7 **** .ds PX \s-1POSIX\s+1 .ds UX \s-1UNIX\s+1 .ds AN \s-1ANSI\s+1 ! .TH GAWK 1 "Apr 18 1994" "Free Software Foundation" "Utility Commands" .SH NAME gawk \- pattern scanning and processing language .SH SYNOPSIS --- 1,7 ---- .ds PX \s-1POSIX\s+1 .ds UX \s-1UNIX\s+1 .ds AN \s-1ANSI\s+1 ! .TH GAWK 1 "Nov 24 1994" "Free Software Foundation" "Utility Commands" .SH NAME gawk \- pattern scanning and processing language .SH SYNOPSIS *************** *** 1868,1876 **** .B "\-W lint" is specified on the command line. .PP ! The other feature is the use of the .B continue ! statement outside the body of a .BR while , .BR for , or --- 1868,1878 ---- .B "\-W lint" is specified on the command line. .PP ! The other feature is the use of either the .B continue ! or the ! .B break ! statements outside the body of a .BR while , .BR for , or *************** *** 1881,1888 **** statement. .I Gawk will support this usage if ! .B "\-W posix" ! has not been specified. .SH ENVIRONMENT VARIABLES If .B POSIXLY_CORRECT --- 1883,1890 ---- statement. .I Gawk will support this usage if ! .B "\-W compat" ! has been specified. .SH ENVIRONMENT VARIABLES If .B POSIXLY_CORRECT *************** *** 1937,1943 **** and .B \-e options of the 2.11 version are no longer recognized. ! This fact will not even be documented in the manual page for version 2.16. .SH AUTHORS The original version of \*(UX .I awk --- 1939,1946 ---- and .B \-e options of the 2.11 version are no longer recognized. ! This fact will not even be documented in the manual page for the next ! major version. .SH AUTHORS The original version of \*(UX .I awk *************** *** 1957,1968 **** --- 1960,1993 ---- .I gawk compatible with the new version of \*(UX .IR awk . + Arnold Robbins is the current maintainer. .PP The initial DOS port was done by Conrad Kwok and Scott Garfinkle. Scott Deifik is the current DOS maintainer. Pat Rankin did the port to VMS, and Michal Jaegermann did the port to the Atari ST. The port to OS/2 was done by Kai Uwe Rommel, with contributions and help from Darrel Hankerson. + .SH BUG REPORTS + If you find a bug in + .IR gawk , + please send electronic mail to + .BR bug-gnu-utils@prep.ai.mit.edu , + .I with + a carbon copy to + .BR arnold@gnu.ai.mit.edu . + Please include your operating system and its revision, the version of + .IR gawk , + what C compiler you used to compile it, and a test program + and data that are as small as possible for reproducing the problem. + .PP + Before sending a bug report, please do two things. First, verify that + you have the latest version of + .IR gawk . + Many bugs (usually subtle ones) are fixed at each release, and if + your's is out of date, the problem may already have been solved. + Second, please read this man page and the reference manual carefully to + be sure that what you think is a bug really is, instead of just a quirk + in the language. .SH ACKNOWLEDGEMENTS Brian Kernighan of Bell Labs provided valuable assistance during testing and debugging. diff -crN gawk-2.15.5/io.c gawk-2.15.6/io.c *** gawk-2.15.5/io.c Wed May 11 22:50:41 1994 --- gawk-2.15.6/io.c Thu Mar 9 11:28:01 1995 *************** *** 3,9 **** */ /* ! * Copyright (C) 1986, 1988, 1989, 1991, 1992, 1993 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. --- 3,9 ---- */ /* ! * Copyright (C) 1986, 1988, 1989, 1991-1995 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. *************** *** 75,81 **** #include "popen.h" #define popen(c,m) os_popen(c,m) #define pclose(f) os_pclose(f) ! #elif defined (OS2) /* OS/2, but not family mode */ #if defined (_MSC_VER) #define popen(c,m) _popen(c,m) #define pclose(f) _pclose(f) --- 75,82 ---- #include "popen.h" #define popen(c,m) os_popen(c,m) #define pclose(f) os_pclose(f) ! #else ! #if defined (OS2) /* OS/2, but not family mode */ #if defined (_MSC_VER) #define popen(c,m) _popen(c,m) #define pclose(f) _pclose(f) *************** *** 83,88 **** --- 84,90 ---- #else extern FILE *popen(); #endif + #endif static struct redirect *red_head = NULL; *************** *** 188,197 **** cnt = 0; retval = 1; } else { ! NR += 1; ! FNR += 1; } - set_record(begin, cnt, 1); return retval; } --- 190,199 ---- cnt = 0; retval = 1; } else { ! NR += 1; ! FNR += 1; ! set_record(begin, cnt, 1); } return retval; } *************** *** 524,531 **** if (status) { char *s = strerror(errno); ! warning("failure status (%d) on %s close of \"%s\" (%s)", ! status, what, rp->value, s); if (! do_unix) { /* set ERRNO too so that program can get at it */ --- 526,538 ---- if (status) { char *s = strerror(errno); ! /* ! * Too many people have complained about this. ! * As of 2.15.6, it is now under lint control. ! */ ! if (do_lint) ! warning("failure status (%d) on %s close of \"%s\" (%s)", ! status, what, rp->value, s); if (! do_unix) { /* set ERRNO too so that program can get at it */ *************** *** 646,652 **** const char *name, *mode; { int openfd = INVALID_HANDLE; ! const char *cp, *ptr; int flag = 0; struct stat buf; extern double strtod(); --- 653,660 ---- const char *name, *mode; { int openfd = INVALID_HANDLE; ! const char *cp; ! char *ptr; int flag = 0; struct stat buf; extern double strtod(); *************** *** 806,812 **** char tbuf[BUFSIZ], *cp; int i; #if defined(NGROUPS_MAX) && NGROUPS_MAX > 0 ! #if defined(atarist) || defined(__svr4__) || defined(__osf__) gid_t groupset[NGROUPS_MAX]; #else int groupset[NGROUPS_MAX]; --- 814,820 ---- char tbuf[BUFSIZ], *cp; int i; #if defined(NGROUPS_MAX) && NGROUPS_MAX > 0 ! #if defined(atarist) || defined(__svr4__) || defined(__osf__) || defined(__bsdi__) gid_t groupset[NGROUPS_MAX]; #else int groupset[NGROUPS_MAX]; diff -crN gawk-2.15.5/iop.c gawk-2.15.6/iop.c *** gawk-2.15.5/iop.c Sat May 14 23:59:58 1994 --- gawk-2.15.6/iop.c Thu Mar 9 11:33:55 1995 *************** *** 3,9 **** */ /* ! * Copyright (C) 1986, 1988, 1989, 1991, 1992, 1993 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. --- 3,9 ---- */ /* ! * Copyright (C) 1986, 1988, 1989, 1991-1995 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. *************** *** 96,104 **** #endif if (fstat(fd, &stb) == -1) fatal("can't stat fd %d (%s)", fd, strerror(errno)); ! if (lseek(fd, (off_t)0, 0) == -1) return DEFBLKSIZE; ! return ((int) (stb.st_size < DEFBLKSIZE ? stb.st_size : DEFBLKSIZE)); #endif /*! TEST */ #endif /*! VMS */ } --- 96,106 ---- #endif if (fstat(fd, &stb) == -1) fatal("can't stat fd %d (%s)", fd, strerror(errno)); ! if (lseek(fd, (off_t)0, 0) == -1) /* not a regular file */ return DEFBLKSIZE; ! if (stb.st_size > 0 && stb.st_size < DEFBLKSIZE) /* small file */ ! return (stb.st_size); ! return (DEFBLKSIZE); #endif /*! TEST */ #endif /*! VMS */ } *************** *** 249,254 **** --- 251,257 ---- continue; } else eat_whitespace = 0; + start = bp; /* skip leading white space */ } if (saw_newline && *bp == rs) { bp++; *************** *** 284,290 **** *bp = '\0'; if (grRS == 0) { /* there could be more newlines left, clean 'em out now */ ! while (*(iop->off) == rs && iop->off <= iop->end) (iop->off)++; if (*--bp == rs) --- 287,293 ---- *bp = '\0'; if (grRS == 0) { /* there could be more newlines left, clean 'em out now */ ! while (iop->off <= iop->end && *(iop->off) == rs) (iop->off)++; if (*--bp == rs) diff -crN gawk-2.15.5/main.c gawk-2.15.6/main.c *** gawk-2.15.5/main.c Sun May 1 18:38:49 1994 --- gawk-2.15.6/main.c Thu Mar 9 11:28:15 1995 *************** *** 3,9 **** */ /* ! * Copyright (C) 1986, 1988, 1989, 1991, 1992, 1993 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. --- 3,9 ---- */ /* ! * Copyright (C) 1986, 1988, 1989, 1991-1995 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. *************** *** 23,30 **** * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - #include "getopt.h" #include "awk.h" #include "patchlevel.h" static void usage P((int exitval)); --- 23,30 ---- * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "awk.h" + #include "getopt.h" #include "patchlevel.h" static void usage P((int exitval)); *************** *** 63,74 **** char *OFS; char *ORS; char *OFMT; - char *CONVFMT; /* ! * The parse tree and field nodes are stored here. Parse_end is a dummy item ! * used to free up unneeded fields without freeing the program being run */ int errcount = 0; /* error counter, used by yyerror() */ /* The global null string */ --- 63,77 ---- char *OFS; char *ORS; char *OFMT; /* ! * CONVFMT is a convenience pointer for the current number to string format. ! * We must supply an initial value to avoid recursion problems of ! * set_CONVFMT -> fmt_index -> r_force_string: gets NULL CONVFMT ! * Fun, fun, fun, fun. */ + char *CONVFMT = "%.6g"; + int errcount = 0; /* error counter, used by yyerror() */ /* The global null string */ *************** *** 90,96 **** extern int yydebug; #endif ! struct src *srcfiles = NULL; /* source file name(s) */ int numfiles = -1; /* how many source files */ int do_unix = 0; /* turn off gnu extensions */ --- 93,99 ---- extern int yydebug; #endif ! struct src *srcfiles = NULL; /* source file name(s) */ int numfiles = -1; /* how many source files */ int do_unix = 0; /* turn off gnu extensions */ *************** *** 105,110 **** --- 108,114 ---- extern char *version_string; /* current version, for printing */ + /* The parse tree is stored here. */ NODE *expression_value; static struct option optab[] = { *************** *** 173,178 **** --- 177,189 ---- Nnull_string->type = Node_val; Nnull_string->flags = (PERM|STR|STRING|NUM|NUMBER); + /* + * Tell the regex routines how they should work. + * Do this before initializing variables, since + * they could want to do a regexp compile. + */ + resetup(); + /* Set up the special variables */ /* * Note that this must be done BEFORE arg parsing else -F *************** *** 184,192 **** emalloc(srcfiles, struct src *, argc * sizeof(struct src), "main"); memset(srcfiles, '\0', argc * sizeof(struct src)); - /* Tell the regex routines how they should work. . . */ - resetup(); - /* we do error messages ourselves on invalid options */ opterr = 0; --- 195,200 ---- *************** *** 347,352 **** --- 355,362 ---- /* Read in the program */ if (yyparse() || errcount) exit(1); + /* recover any space from C based alloca */ + (void) alloca(0); /* Set up the field variables */ init_fields(); *************** *** 494,499 **** --- 504,513 ---- /* * Set all the special variables to their initial values. + * Note that some of the variables that have set_FOO routines should + * *N*O*T* have those routines called upon initialization, and thus + * they have NULL entries in that field. This is notably true of FS + * and IGNORECASE. */ struct varinit { NODE **spec; *************** *** 504,521 **** Func_ptr assign; }; static struct varinit varinit[] = { {&NF_node, "NF", Node_NF, 0, -1, set_NF }, {&FIELDWIDTHS_node, "FIELDWIDTHS", Node_FIELDWIDTHS, "", 0, 0 }, {&NR_node, "NR", Node_NR, 0, 0, set_NR }, {&FNR_node, "FNR", Node_FNR, 0, 0, set_FNR }, {&FS_node, "FS", Node_FS, " ", 0, 0 }, {&RS_node, "RS", Node_RS, "\n", 0, set_RS }, ! {&IGNORECASE_node, "IGNORECASE", Node_IGNORECASE, 0, 0, set_IGNORECASE }, {&FILENAME_node, "FILENAME", Node_var, "", 0, 0 }, {&OFS_node, "OFS", Node_OFS, " ", 0, set_OFS }, {&ORS_node, "ORS", Node_ORS, "\n", 0, set_ORS }, {&OFMT_node, "OFMT", Node_OFMT, "%.6g", 0, set_OFMT }, - {&CONVFMT_node, "CONVFMT", Node_CONVFMT, "%.6g", 0, set_CONVFMT }, {&RLENGTH_node, "RLENGTH", Node_var, 0, 0, 0 }, {&RSTART_node, "RSTART", Node_var, 0, 0, 0 }, {&SUBSEP_node, "SUBSEP", Node_var, "\034", 0, 0 }, --- 518,535 ---- Func_ptr assign; }; static struct varinit varinit[] = { + {&CONVFMT_node, "CONVFMT", Node_CONVFMT, "%.6g", 0, set_CONVFMT }, {&NF_node, "NF", Node_NF, 0, -1, set_NF }, {&FIELDWIDTHS_node, "FIELDWIDTHS", Node_FIELDWIDTHS, "", 0, 0 }, {&NR_node, "NR", Node_NR, 0, 0, set_NR }, {&FNR_node, "FNR", Node_FNR, 0, 0, set_FNR }, {&FS_node, "FS", Node_FS, " ", 0, 0 }, {&RS_node, "RS", Node_RS, "\n", 0, set_RS }, ! {&IGNORECASE_node, "IGNORECASE", Node_IGNORECASE, 0, 0, 0 }, {&FILENAME_node, "FILENAME", Node_var, "", 0, 0 }, {&OFS_node, "OFS", Node_OFS, " ", 0, set_OFS }, {&ORS_node, "ORS", Node_ORS, "\n", 0, set_ORS }, {&OFMT_node, "OFMT", Node_OFMT, "%.6g", 0, set_OFMT }, {&RLENGTH_node, "RLENGTH", Node_var, 0, 0, 0 }, {&RSTART_node, "RSTART", Node_var, 0, 0, 0 }, {&SUBSEP_node, "SUBSEP", Node_var, "\034", 0, 0 }, diff -crN gawk-2.15.5/msg.c gawk-2.15.6/msg.c *** gawk-2.15.5/msg.c Mon May 2 06:06:39 1994 --- gawk-2.15.6/msg.c Thu Mar 9 11:28:24 1995 *************** *** 3,9 **** */ /* ! * Copyright (C) 1986, 1988, 1989, 1991, 1992, 1993 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. --- 3,9 ---- */ /* ! * Copyright (C) 1986, 1988, 1989, 1991-1995 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. *************** *** 85,90 **** --- 85,104 ---- va_start(args); mesg = va_arg(args, char *); err("warning: ", mesg, args); + va_end(args); + } + + /*VARARGS0*/ + void + error(va_alist) + va_dcl + { + va_list args; + char *mesg; + + va_start(args); + mesg = va_arg(args, char *); + err("error: ", mesg, args); va_end(args); } diff -crN gawk-2.15.5/node.c gawk-2.15.6/node.c *** gawk-2.15.5/node.c Wed May 11 23:38:45 1994 --- gawk-2.15.6/node.c Thu Mar 9 11:28:35 1995 *************** *** 3,9 **** */ /* ! * Copyright (C) 1986, 1988, 1989, 1991, 1992, 1993 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. --- 3,9 ---- */ /* ! * Copyright (C) 1986, 1988, 1989, 1991-1995 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. *************** *** 127,133 **** #ifdef DEBUG if (s == NULL) cant_happen(); if (s->type != Node_val) cant_happen(); ! if (s->flags & STR) return s; if (!(s->flags & NUM)) cant_happen(); if (s->stref != 0) ; /*cant_happen();*/ #endif --- 127,133 ---- #ifdef DEBUG if (s == NULL) cant_happen(); if (s->type != Node_val) cant_happen(); ! if ((s->flags & STR) && (s->stfmt == -1 || s->stfmt == CONVFMTidx)) return s; if (!(s->flags & NUM)) cant_happen(); if (s->stref != 0) ; /*cant_happen();*/ #endif *************** *** 441,446 **** --- 441,450 ---- } if (do_posix) return ('x'); + if (! isxdigit((*string_ptr)[1])) { + warning("no hex digits in \\x escape sequence"); + return ('x'); + } i = 0; while (1) { if (isxdigit((c = *(*string_ptr)++))) { diff -crN gawk-2.15.5/patchlevel.h gawk-2.15.6/patchlevel.h *** gawk-2.15.5/patchlevel.h Sun Feb 13 21:55:40 1994 --- gawk-2.15.6/patchlevel.h Thu Mar 9 06:41:45 1995 *************** *** 1 **** ! #define PATCHLEVEL 5 --- 1 ---- ! #define PATCHLEVEL 6 diff -crN gawk-2.15.5/re.c gawk-2.15.6/re.c *** gawk-2.15.5/re.c Sat Jan 15 22:32:28 1994 --- gawk-2.15.6/re.c Thu Mar 9 11:28:44 1995 *************** *** 3,9 **** */ /* ! * Copyright (C) 1991, 1992, 1993 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. --- 3,9 ---- */ /* ! * Copyright (C) 1991-1995 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. *************** *** 101,106 **** --- 101,109 ---- len = dest - temp; if ((rerr = re_compile_pattern(temp, len, &(rp->pat))) != NULL) fatal("%s: /%s/", rerr, temp); + + /* gack. this must be done *after* re_compile_pattern */ + rp->pat.newline_anchor = 0; /* don't get \n in middle of string */ if (dfa && !ignorecase) { dfacomp(temp, len, &(rp->dfareg), 1); rp->dfa = 1; *************** *** 136,145 **** str[start+len] = save; } if (ret) { ! if (need_start || rp->dfa == 0) ! return re_search(&(rp->pat), str, start+len, start, ! len, &(rp->regs)); ! else return 1; } else return -1; --- 139,151 ---- str[start+len] = save; } if (ret) { ! if (need_start || rp->dfa == 0) { ! int result = re_search(&(rp->pat), str, start+len, ! start, len, &(rp->regs)); ! /* recover any space from C based alloca */ ! (void) alloca(0); ! return result; ! } else return 1; } else return -1; *************** *** 151,156 **** --- 157,166 ---- { free(rp->pat.buffer); free(rp->pat.fastmap); + if (rp->regs.start) + free(rp->regs.start); + if (rp->regs.end) + free(rp->regs.end); if (rp->dfa) dfafree(&(rp->dfareg)); free(rp); diff -crN gawk-2.15.5/regex.c gawk-2.15.6/regex.c *** gawk-2.15.5/regex.c Tue Jan 11 06:34:34 1994 --- gawk-2.15.6/regex.c Thu Mar 9 11:29:01 1995 *************** *** 3,9 **** (Implements POSIX draft P10003.2/D11.2, except for internationalization features.) ! Copyright (C) 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by --- 3,9 ---- (Implements POSIX draft P10003.2/D11.2, except for internationalization features.) ! Copyright (C) 1993-1995 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by *************** *** 817,822 **** --- 817,829 ---- } } + void + printchar (c) + int c; + { + putc(c, stderr); + } + #else /* not DEBUG */ #undef assert *************** *** 3162,3168 **** (FIRST_STRING_P (ptr) ? (ptr) - string1 : (ptr) - string2 + size1) /* Registers are set to a sentinel when they haven't yet matched. */ ! #define REG_UNSET_VALUE ((char *) -1) #define REG_UNSET(e) ((e) == REG_UNSET_VALUE) --- 3169,3176 ---- (FIRST_STRING_P (ptr) ? (ptr) - string1 : (ptr) - string2 + size1) /* Registers are set to a sentinel when they haven't yet matched. */ ! static char reg_unset_dummy; ! #define REG_UNSET_VALUE (®_unset_dummy) #define REG_UNSET(e) ((e) == REG_UNSET_VALUE) diff -crN gawk-2.15.5/regex.h gawk-2.15.6/regex.h *** gawk-2.15.5/regex.h Fri Nov 26 13:37:12 1993 --- gawk-2.15.6/regex.h Thu Mar 9 11:29:15 1995 *************** *** 1,7 **** /* Definitions for data structures and routines for the regular expression library, version 0.12. ! Copyright (C) 1985, 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by --- 1,7 ---- /* Definitions for data structures and routines for the regular expression library, version 0.12. ! Copyright (C) 1985, 1989, 1990-1995 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by *************** *** 157,162 **** --- 157,163 ---- (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ | RE_NO_BK_PARENS | RE_NO_BK_REFS \ | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \ + | RE_DOT_NEWLINE \ | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS) #define RE_SYNTAX_GNU_AWK \ *************** *** 480,488 **** --- 481,491 ---- _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs, unsigned num_regs, regoff_t *starts, regoff_t *ends)); + #ifndef _CRAY /* 4.2 bsd compatibility. */ extern char *re_comp _RE_ARGS ((const char *)); extern int re_exec _RE_ARGS ((const char *)); + #endif /* POSIX compatibility. */ extern int regcomp _RE_ARGS ((regex_t *preg, const char *pattern, int cflags)); diff -crN gawk-2.15.5/test/Makefile gawk-2.15.6/test/Makefile *** gawk-2.15.5/test/Makefile Tue May 10 22:57:41 1994 --- gawk-2.15.6/test/Makefile Thu Mar 9 11:30:07 1995 *************** *** 1,10 **** SHELL = /bin/sh bigtest: basic poundbang gawk.extensions basic: msg swaplns messages argarray longwrds \ getline fstabplus compare arrayref rs fsrs rand \ ! fsbs negexp asgext anchgsub splitargv awkpath nfset reparse gawk.extensions: fieldwdth ignrcase posix manyfiles igncfs argtest \ badargs --- 1,32 ---- + # Makefile for GNU Awk test suite. + # + # Copyright (C) 1988-1995 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 2 of the License, 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + SHELL = /bin/sh bigtest: basic poundbang gawk.extensions basic: msg swaplns messages argarray longwrds \ getline fstabplus compare arrayref rs fsrs rand \ ! fsbs negexp asgext anchgsub splitargv awkpath nfset reparse \ ! convfmt arrayparm paramdup nonl gawk.extensions: fieldwdth ignrcase posix manyfiles igncfs argtest \ badargs *************** *** 28,34 **** messages:: @../gawk -f messages.awk >out2 2>out3 ! { cmp out1.good out1 && cmp out2.good out2 && cmp out3.good out3 && rm -f out1 out2 out3; } || { test -c /dev/stdout && echo IT IS OK THAT THIS TEST FAILED; } argarray:: @TEST=test echo just a test | ../gawk -f argarray.awk argarray.awk - >tmp --- 50,56 ---- messages:: @../gawk -f messages.awk >out2 2>out3 ! { cmp out1.good out1 && cmp out2.good out2 && cmp out3.good out3 && rm -f out1 out2 out3; } || { test -d /dev/fd && echo IT IS OK THAT THIS TEST FAILED; } argarray:: @TEST=test echo just a test | ../gawk -f argarray.awk argarray.awk - >tmp *************** *** 139,146 **** cmp argtest.good tmp && rm -f tmp badargs:: ! @-../gawk -f 2>&1 | grep -v patchlevel > tmp cmp badargs.good tmp && rm -f tmp clean: rm -fr tmp core junk --- 161,184 ---- cmp argtest.good tmp && rm -f tmp badargs:: ! @-../gawk -f 2>&1 | grep -v patchlevel >tmp cmp badargs.good tmp && rm -f tmp + + convfmt:: + @../gawk -f convfmt.awk >tmp + cmp convfmt.good tmp && rm -f tmp + + arrayparm:: + @-../gawk -f arrayparm.awk >tmp 2>&1 + cmp arrayparm.good tmp && rm -f tmp + + paramdup:: + @-../gawk -f paramdup.awk >tmp 2>&1 + cmp paramdup.good tmp && rm -f tmp + + nonl:: + @-../gawk --lint -f nonl.awk /dev/null >tmp 2>&1 + cmp nonl.good tmp && rm -f tmp clean: rm -fr tmp core junk diff -crN gawk-2.15.5/test/arrayparm.awk gawk-2.15.6/test/arrayparm.awk *** gawk-2.15.5/test/arrayparm.awk Wed Dec 31 19:00:00 1969 --- gawk-2.15.6/test/arrayparm.awk Thu Feb 23 22:18:20 1995 *************** *** 0 **** --- 1,21 ---- + # + # Test program from: + # + # Date: Tue, 21 Feb 95 16:09:29 EST + # From: emory!blackhawk.com!aaron (Aaron Sosnick) + # + BEGIN { + foo[1]=1; + foo[2]=2; + bug1(foo); + } + function bug1(i) { + for (i in foo) { + bug2(i); + delete foo[i]; + print i,1,bot[1]; + } + } + function bug2(arg) { + bot[arg]=arg; + } diff -crN gawk-2.15.5/test/arrayparm.good gawk-2.15.6/test/arrayparm.good *** gawk-2.15.5/test/arrayparm.good Wed Dec 31 19:00:00 1969 --- gawk-2.15.6/test/arrayparm.good Sun Feb 26 07:25:34 1995 *************** *** 0 **** --- 1 ---- + gawk: arrayparm.awk:18: fatal: attempt to use array `foo' in a scalar context diff -crN gawk-2.15.5/test/convfmt.awk gawk-2.15.6/test/convfmt.awk *** gawk-2.15.5/test/convfmt.awk Wed Dec 31 19:00:00 1969 --- gawk-2.15.6/test/convfmt.awk Thu Nov 24 06:47:08 1994 *************** *** 0 **** --- 1,10 ---- + BEGIN { + CONVFMT = "%2.2f" + a = 123.456 + b = a "" # give `a' string value also + printf "a = %s\n", a + CONVFMT = "%.6g" + printf "a = %s\n", a + a += 0 # make `a' numeric only again + printf "a = %s\n", a # use `a' as string + } diff -crN gawk-2.15.5/test/convfmt.good gawk-2.15.6/test/convfmt.good *** gawk-2.15.5/test/convfmt.good Wed Dec 31 19:00:00 1969 --- gawk-2.15.6/test/convfmt.good Thu Nov 24 06:47:22 1994 *************** *** 0 **** --- 1,3 ---- + a = 123.46 + a = 123.456 + a = 123.456 diff -crN gawk-2.15.5/test/nonl.good gawk-2.15.6/test/nonl.good *** gawk-2.15.5/test/nonl.good Wed Dec 31 19:00:00 1969 --- gawk-2.15.6/test/nonl.good Sun Mar 5 10:47:33 1995 *************** *** 0 **** --- 1 ---- + gawk: nonl.awk:1: warning: source file does not end in newline diff -crN gawk-2.15.5/test/paramdup.awk gawk-2.15.6/test/paramdup.awk *** gawk-2.15.5/test/paramdup.awk Wed Dec 31 19:00:00 1969 --- gawk-2.15.6/test/paramdup.awk Thu Feb 23 22:20:39 1995 *************** *** 0 **** --- 1,8 ---- + BEGIN { foo(0, 1, 2) } + + function foo(a, b, c, b, a) + { + print "a =", a + print "b =", b + print "c =", c + } diff -crN gawk-2.15.5/test/paramdup.good gawk-2.15.6/test/paramdup.good *** gawk-2.15.5/test/paramdup.good Wed Dec 31 19:00:00 1969 --- gawk-2.15.6/test/paramdup.good Thu Feb 23 22:37:17 1995 *************** *** 0 **** --- 1,2 ---- + gawk: paramdup.awk:4: error: function `foo': parameter #4, `b', duplicates parameter #2 + gawk: paramdup.awk:4: error: function `foo': parameter #5, `a', duplicates parameter #1 diff -crN gawk-2.15.5/vms/descrip.mms gawk-2.15.6/vms/descrip.mms *** gawk-2.15.5/vms/descrip.mms Tue Mar 8 06:46:29 1994 --- gawk-2.15.6/vms/descrip.mms Thu Jan 5 12:28:07 1995 *************** *** 109,115 **** # Release of gawk REL=2.15 ! PATCHLVL=5 # dummy target to allow building "gawk" in addition to explicit "gawk.exe" gawk : gawk.exe --- 109,115 ---- # Release of gawk REL=2.15 ! PATCHLVL=6 # dummy target to allow building "gawk" in addition to explicit "gawk.exe" gawk : gawk.exe diff -crN gawk-2.15.5/vms/gawk.hlp gawk-2.15.6/vms/gawk.hlp *** gawk-2.15.5/vms/gawk.hlp Mon Jul 6 11:11:16 1992 --- gawk-2.15.6/vms/gawk.hlp Thu Jan 5 12:30:12 1995 *************** *** 2,7 **** --- 2,8 ---- ! Pat Rankin, Jun'90 ! revised, Jun'91 ! revised, Jul'92 + ! revised, Jan'95 ! Online help for GAWK. ! 1 GAWK *************** *** 89,94 **** --- 90,96 ---- >$vfile create 'vfile' as 'stdout', using RMS attributes appropriate for a standard text file (variable length records with implied carriage control) + >+bfile create 'bfile' as 'stdout' using binary mode 2>&1 route error messages into the regular output stream 1>&2 send output data to the error destination <>$' isn't supported. + Ditto for binary output; '>>+' isn't supported. 4 RS_peculiarities Changing the record separator to something other than newline ('\n') will produce anomalous results for ordinary files. For example, *************** *** 1139,1144 **** --- 1146,1163 ---- failure. The final exit status will be 1 (VMS success) if 0 is used, or even (VMS non-success) if non-zero is used. 3 changes + Changes between version 2.15.6 and 2.14 + + General + Many obscure bugs fixed + `delete' may operate on an entire array + ARGIND and ERRNO builtin variables added + + VMS-specific + `>+ file' binary-mode output redirection added + /variable=(foo=42) fixed + Floating point number formatting improved + 3 prior_changes Changes between version 2.14 and 2.13.2: General *************** *** 1153,1159 **** Disk I/O throughput enhanced Pipe emulation improved and incorrect interaction with user-mode redefinition of SYS$OUTPUT eliminated ! 3 prior_changes Changes between version 2.13 and 2.11.1: (2.12 was not released) General --- 1172,1178 ---- Disk I/O throughput enhanced Pipe emulation improved and incorrect interaction with user-mode redefinition of SYS$OUTPUT eliminated ! Changes between version 2.13 and 2.11.1: (2.12 was not released) General diff -crN gawk-2.15.5/vms/vms_args.c gawk-2.15.6/vms/vms_args.c *** gawk-2.15.5/vms/vms_args.c Tue Jan 4 16:18:33 1994 --- gawk-2.15.6/vms/vms_args.c Thu Mar 2 02:30:55 1995 *************** *** 4,10 **** */ /* ! * Copyright (C) 1991-1993 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. --- 4,10 ---- */ /* ! * Copyright (C) 1991-1995 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. *************** *** 39,44 **** --- 39,46 ---- * >$vfile - create 'vfile' as 'stdout', using rms attributes * appropriate for a standard text file (variable length * records with implied carriage control) + * >+vfile - create 'vfile' as 'stdout' in binary mode (using + * variable length records with implied carriage control) * 2>&1 - special case: direct error messages into output file * 1>&2 - special case: direct output data to error destination * <' or '>>'), sharing is disallowed * (for performance reasons). + * + * Sep'94, gawk 2.15.6 [pr] + * Add '>+' to force binary mode output, to enable better control + * for the user when the output destination is a mailbox or socket. + * (ORS = "\r\n" for tcp/ip.) Contributed by Per Steinar Iversen. */ #include "awk.h" /* really "../awk.h" */ *************** *** 158,163 **** --- 165,173 ---- else if (*p == '$') /* '>$' => kludge for record format */ rms_rfm = "rfm=var", rms_shr = "shr=get,upi", rms_mrs = "mrs=32767", p++; + else if (*p == '+') /* '>+' => kludge for binary output */ + out_mode = "wb", rms_rfm = "rfm=var", + rms_mrs = "mrs=32767", p++; else /* '>' => create */ {} /* use default values initialized prior to loop */ p = skipblanks(p); *************** *** 244,284 **** /*[ catch 22: we'll also redirect errors encountered doing out ]*/ if (f_err) { /* define logical name but don't open file */ int len = strlen(f_err); ! if (strncasecmp(f_err, "SYS$OUTPUT", len) == 0 ! && (f_err[len] == ':' || f_err[len] == '\0')) err_to_out_redirect = 1; else (void) vms_define("SYS$ERROR", f_err); } /* do stdin before stdout, so if we bomb we won't make empty output file */ if (f_in) { /* [re]open file and define logical name */ ! stdin = freopen(f_in, "r", stdin, ! "ctx=rec", "shr=get,put,del,upd", ! "mrs=32767", "mbc=32", "mbf=2"); ! if (stdin != NULL) (void) vms_define("SYS$INPUT", f_in); else fatal("<%s (%s)", f_in, strerror(errno)); } if (f_out) { ! stdout = freopen(f_out, out_mode, stdout, ! rms_rfm, rms_shr, rms_mrs, ! "rat=cr", "mbc=32", "mbf=2"); ! if (stdout != NULL) (void) vms_define("SYS$OUTPUT", f_out); else fatal(">%s%s (%s)", (*out_mode == 'a' ? ">" : ""), f_out, strerror(errno)); } if (err_to_out_redirect) { /* special case for ``2>&1'' construct */ - (void) fclose(stderr); (void) dup2(1, 2); /* make file 2 (stderr) share file 1 (stdout) */ - stderr = stdout; (void) vms_define("SYS$ERROR", "SYS$OUTPUT:"); } else if (out_to_err_redirect) { /* ``1>&2'' */ - (void) fclose(stdout); (void) dup2(2, 1); /* make file 1 (stdout) share file 2 (stderr) */ - stdout = stderr; (void) vms_define("SYS$OUTPUT", "SYS$ERROR:"); } --- 254,288 ---- /*[ catch 22: we'll also redirect errors encountered doing out ]*/ if (f_err) { /* define logical name but don't open file */ int len = strlen(f_err); ! if (len >= (sizeof "SYS$OUTPUT" - sizeof "") ! && strncasecmp(f_err, "SYS$OUTPUT:", len) == 0) err_to_out_redirect = 1; else (void) vms_define("SYS$ERROR", f_err); } /* do stdin before stdout, so if we bomb we won't make empty output file */ if (f_in) { /* [re]open file and define logical name */ ! if (freopen(f_in, "r", stdin, ! "ctx=rec", "shr=get,put,del,upd", ! "mrs=32767", "mbc=32", "mbf=2")) (void) vms_define("SYS$INPUT", f_in); else fatal("<%s (%s)", f_in, strerror(errno)); } if (f_out) { ! if (freopen(f_out, out_mode, stdout, ! rms_rfm, rms_shr, rms_mrs, ! "rat=cr", "mbc=32", "mbf=2")) (void) vms_define("SYS$OUTPUT", f_out); else fatal(">%s%s (%s)", (*out_mode == 'a' ? ">" : ""), f_out, strerror(errno)); } if (err_to_out_redirect) { /* special case for ``2>&1'' construct */ (void) dup2(1, 2); /* make file 2 (stderr) share file 1 (stdout) */ (void) vms_define("SYS$ERROR", "SYS$OUTPUT:"); } else if (out_to_err_redirect) { /* ``1>&2'' */ (void) dup2(2, 1); /* make file 1 (stdout) share file 2 (stderr) */ (void) vms_define("SYS$OUTPUT", "SYS$ERROR:"); } diff -crN gawk-2.15.5/vms/vms_fwrite.c gawk-2.15.6/vms/vms_fwrite.c *** gawk-2.15.5/vms/vms_fwrite.c Wed Dec 29 10:41:29 1993 --- gawk-2.15.6/vms/vms_fwrite.c Thu Jan 5 12:31:04 1995 *************** *** 3,9 **** */ /* ! * Copyright (C) 1991-1993 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. --- 3,9 ---- */ /* ! * Copyright (C) 1991-1995 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. *************** *** 69,75 **** short chan; int file_num, result; ! if (!file || !*file) return 0 * (errno = EBADF); /* kludge alert! */ else if (file == prev_file) file_num = prev_file_num; --- 69,77 ---- short chan; int file_num, result; ! if (!size || !number) ! return 0; ! else if (!file || !*file) return 0 * (errno = EBADF); /* kludge alert! */ else if (file == prev_file) file_num = prev_file_num; diff -crN gawk-2.15.5/vms/vmsbuild.com gawk-2.15.6/vms/vmsbuild.com *** gawk-2.15.5/vms/vmsbuild.com Sat Feb 19 22:56:10 1994 --- gawk-2.15.6/vms/vmsbuild.com Thu Jan 5 12:28:07 1995 *************** *** 5,11 **** $! gawk 2.15 revised, Oct'93 $! $ REL = "2.15" !release version number ! $ PATCHLVL = "5" $! $! [ remove "/optimize=noinline" for VAX C V2.x or DEC C ] $! [ add "/standard=VAXC" for DEC C and "/g_float" for Alpha ] --- 5,11 ---- $! gawk 2.15 revised, Oct'93 $! $ REL = "2.15" !release version number ! $ PATCHLVL = "6" $! $! [ remove "/optimize=noinline" for VAX C V2.x or DEC C ] $! [ add "/standard=VAXC" for DEC C and "/g_float" for Alpha ] EOF