# This is patch 5 to gawk 2.15. # Change to the gawk 2.15.4 distribution directory, and sh this file. # Running it through patch is not enough; files and/or directories # must be removed first. # # Make sure that the patch program is in your search path. rm -fr awktab.c patch -p1 << \EOF diff -crN gawk-2.15.4/ACKNOWLEDGMENT gawk-2.15.5/ACKNOWLEDGMENT *** gawk-2.15.4/ACKNOWLEDGMENT Sun Nov 7 10:09:13 1993 --- gawk-2.15.5/ACKNOWLEDGMENT Sun May 15 11:27:11 1994 *************** *** 8,14 **** 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) --- 8,14 ---- 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) *************** *** 16,21 **** --- 16,23 ---- 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 diff -crN gawk-2.15.4/FUTURES gawk-2.15.5/FUTURES *** gawk-2.15.4/FUTURES Wed May 19 11:24:32 1993 --- gawk-2.15.5/FUTURES Thu May 19 00:37:45 1994 *************** *** 1,14 **** This file lists future projects and enhancements for gawk. Items are listed in roughly the order they will be done for a given release. This file is ! mainly for use by the developers to help keep themselves on track, please don't bug us too much about schedules or what all this really means. For 2.16 ======== ! David: ! Move to autoconf-based configure system. ! Allow RS to be a regexp. RT variable to hold text of record terminator --- 1,26 ---- This file lists future projects and enhancements for gawk. Items are listed in roughly the order they will be done for a given release. This file is ! mainly for use by the developer(s) to help keep themselves on track, please don't bug us too much about schedules or what all this really means. + (An `x' indicates that some progress has been made, but that the feature is + not complete yet.) + For 2.16 ======== ! x Move to autoconf-based configure system. ! ! x Research awk `fflush' function. ! ! x Generalize IGNORECASE ! 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. RT variable to hold text of record terminator *************** *** 16,61 **** Feedback alloca.s changes to FSF ! Extensible hashing in memory of awk arrays ! Split() with null string as third arg to split up strings ! ! Analogously, setting FS="" would split the input record into individual characters. ! Arnold: ! Generalize IGNORECASE ! any value makes it work, not just numeric non-zero ! make it apply to *all* string comparisons ! ! Fix FILENAME to have an initial value of "", not "-" ! ! Clean up code by isolating system-specific functions in separate files. Undertake significant directory reorganization. ! Extensive manual cleanup: Use of texinfo 2.0 features Lots more examples Document all of the above. ! In 2.17 ! ======= ! David: ! ! Incorporate newer dfa.c and regex.c (go to POSIX regexps) Make regex + dfa less dependant on gawk header file includes - General sub functions: - edit(line, pat, sub) and gedit(line, pat, sub) - that return the substituted strings and allow \1 etc. in the sub string. - - Arnold: - DBM storage of awk arrays. Try to allow multiple dbm packages - - ? Have strftime() pay attention to the value of ENVIRON["TZ"] - Additional manual features: Document posix regexps Document use of dbm arrays --- 28,51 ---- Feedback alloca.s changes to FSF ! x Split() with null string as third arg to split up strings ! x Analogously, setting FS="" would split the input record into individual characters. ! x Clean up code by isolating system-specific functions in separate files. Undertake significant directory reorganization. ! x Extensive manual cleanup: Use of texinfo 2.0 features Lots more examples Document all of the above. ! x Go to POSIX regexps Make regex + dfa less dependant on gawk header file includes Additional manual features: Document posix regexps Document use of dbm arrays *************** *** 67,85 **** For 2.18 ======== ! Arnold: Add chdir and stat built-in functions. Add function pointers as valid variable types. Add an `ftw' built-in function that takes a function pointer. - David: - Do an optimization pass over parse tree? ! For 2.19 or later: ================== Add variables similar to C's __FILE__ and __LINE__ for better diagnostics from within awk programs. --- 57,82 ---- For 2.18 ======== + DBM storage of awk arrays. Try to allow multiple dbm packages ! General sub functions: ! edit(line, pat, sub) and gedit(line, pat, sub) ! that return the substituted strings and allow \1 etc. in the sub ! string. ! ! ? Have strftime() pay attention to the value of ENVIRON["TZ"] ! ! For 2.19 ! ======== Add chdir and stat built-in functions. Add function pointers as valid variable types. Add an `ftw' built-in function that takes a function pointer. Do an optimization pass over parse tree? ! For 2.20 or later: ================== Add variables similar to C's __FILE__ and __LINE__ for better diagnostics from within awk programs. *************** *** 101,107 **** Do a reference card ! Allow OFMT to be other than a floating point format. Allow redefining of builtin functions? --- 98,104 ---- Do a reference card ! Allow OFMT and CONVFMT to be other than a floating point format. Allow redefining of builtin functions? diff -crN gawk-2.15.4/LIMITATIONS gawk-2.15.5/LIMITATIONS *** gawk-2.15.4/LIMITATIONS Thu Jun 18 20:50:38 1992 --- gawk-2.15.5/LIMITATIONS Tue May 10 21:55:51 1994 *************** *** 12,14 **** --- 12,16 ---- # of pipe redirections: min(# of processes per user, # of open files) double-precision floating point Length of source line: unlimited + Number of input records in one file: MAX_LONG + Number of input records total: MAX_LONG diff -crN gawk-2.15.4/Makefile.bsd44 gawk-2.15.5/Makefile.bsd44 *** gawk-2.15.4/Makefile.bsd44 Tue Jun 1 14:55:04 1993 --- gawk-2.15.5/Makefile.bsd44 Wed May 18 06:43:31 1994 *************** *** 10,14 **** CLEANFILES+=awk.c y.tab.h awk.0 awk.0: gawk.1 ! nroff -man gawk.1 > awk.0 .include --- 10,14 ---- CLEANFILES+=awk.c y.tab.h awk.0 awk.0: gawk.1 ! nroff -man gawk.1 > awk.0 .include diff -crN gawk-2.15.4/NEWS gawk-2.15.5/NEWS *** gawk-2.15.4/NEWS Sat Jan 15 22:37:42 1994 --- gawk-2.15.5/NEWS Thu May 19 01:12:01 1994 *************** *** 1,3 **** --- 1,91 ---- + Changes from 2.15.4 to 2.15.5 + ----------------------------- + + FUTURES file updated and re-arranged some with more rational schedule. + + Many prototypes handled better for ANSI C in protos.h. + + getopt.c updated somewhat. + + test/Makefile now removes junk directory, `bardargtest' renamed `badargs.' + + Bug fix in iop.c for RS = "". Eat trailing newlines off of record separator. + + Bug fix in Makefile.bsd44, use leading tab in actions. + + Fix in field.c:set_FS for FS == "\\" and IGNORECASE != 0. + + Config files updated or added: + cray60, DEC OSF/1 2.0, Utek, sgi405, next21, next30, atari/config.h, + sco. + + Fix in io.c for ENFILE as well as EMFILE, update decl of groupset to + include OSF/1. + + Rationalized printing as integers if numbers are outside the range of a long. + Changes to node.c:force_string and builtin.c. + + Made internal NF, NR, and FNR variables longs instead of ints. + + Add LIMITS_H_MISSING stuff to config.in and awk.h, and default defs for + INT_MAX and LONG_MAX, if no limits.h file. Add a standard decl of + the time() function for __STDC__. From ghazi@noc.rutgers.edu. + + Fix tree_eval in awk.h and r_tree_eval in eval.c to deal better with + function parameters, particularly ones that are arrays. + + Fix eval.c to print out array names of arrays used in scalar contexts. + + Fix eval.c in interpret to zero out source and sourceline initially. This + does a better job of providing source file and line number information. + + Fix to re_parse_field in field.c to not use isspace when RS = "", but rather + to explicitly look for blank and tab. + + Fix to sc_parse_field in field.c to catch the case of the FS character at the + end of a record. + + Lots of miscellanious bug fixes for memory leaks, courtesy Mark Moraes, + also fixes for arrays. + + io.c fixed to warn about lack of explicit closes if --lint. + + Updated missing/strftime.c to match posted strftime 6.2. + + Bug fix in builtin.c, in case of non-match in sub_common. + + Updated constant used for division in builtin.c:do_rand for DEC Alpha + and CRAY Y-MP. + + POSIXLY_CORRECT in the environment turns on --posix (fixed in main.c). + + Updated srandom prototype and calls in builtin.c. + + Fix awk.y to enforce posix semantics of unary +: result is numeric. + + Fix array.c to not rearrange the hash chain upon finding an index in + the array. This messed things up in cases like: + for (index1 in array) { + blah + if (index2 in array) # blew away the for + stuff + } + + Fixed spelling errors in the man page. + + Fixes in awk.y so that + gawk '' /path/to/file + will work without core dumping or finding parse errors. + + Fix main.c so that --lint will fuss about an empty program. + Yet another fix for argument parsing in the case of unrecognized options. + + Bug fix in dfa.c to not attempt to free null pointers. + + Bug fix in builtin.c to only use DEFAULT_G_PRECISION for %g or %G. + + Bug fix in field.c to achieve call by value semantics for split. + Changes from 2.15.3 to 2.15.4 ----------------------------- *************** *** 26,32 **** Bug fix in argument handling. `gawk -X' now notices there was no program. Additional bug fixes to make --compat and --lint work again. ! Many changes for 16-bit cleanliness. Add explicit alloca(0) in io.c to recover space from C alloca. --- 114,120 ---- Bug fix in argument handling. `gawk -X' now notices there was no program. Additional bug fixes to make --compat and --lint work again. ! Many changes for systems where sizeof(int) != sizeof(void *). Add explicit alloca(0) in io.c to recover space from C alloca. *************** *** 64,70 **** Changes for BSD44: in io.c and Makefile.bsd44. ! All directories in the distribution are now writeable. Separated LDFLAGS and CFLAGS in Makefile. CFLAGS can now be overridden by user. --- 152,158 ---- Changes for BSD44: in io.c and Makefile.bsd44. ! All directories in the distribution are now writable. Separated LDFLAGS and CFLAGS in Makefile. CFLAGS can now be overridden by user. *************** *** 258,264 **** Allow continue outside of a loop, unless in strict posix mode. Lint option will issue warning. ! New missing/strftime.c. There has been one chage that affects gawk. Posix now defines a %V conversion so the vms conversion has been changed to %v. If this version is used with gawk -Wlint and they use %V in a call to strftime, they'll get a warning. --- 346,352 ---- Allow continue outside of a loop, unless in strict posix mode. Lint option will issue warning. ! New missing/strftime.c. There has been one change that affects gawk. Posix now defines a %V conversion so the vms conversion has been changed to %v. If this version is used with gawk -Wlint and they use %V in a call to strftime, they'll get a warning. *************** *** 286,292 **** Fixed premature freeing in construct "$0 = $0". Removed the call to wait_any() in gawk_popen(), since on at least some systems, ! if gawk's input was from a pipe, the predecssor process in the pipe was a child of gawk and this caused a deadlock. Regexp can (once again) match a newline, if given explicitly. --- 374,380 ---- Fixed premature freeing in construct "$0 = $0". Removed the call to wait_any() in gawk_popen(), since on at least some systems, ! if gawk's input was from a pipe, the predecessor process in the pipe was a child of gawk and this caused a deadlock. Regexp can (once again) match a newline, if given explicitly. *************** *** 312,318 **** Fixed several bugs in [g]sub() for no match found or the match is 0-length. ! Fixed bug where in gsub() a pattern anchorred at the beginning would still substitute throughout the string. make test does not assume the . is in PATH. --- 400,406 ---- Fixed several bugs in [g]sub() for no match found or the match is 0-length. ! Fixed bug where in gsub() a pattern anchored at the beginning would still substitute throughout the string. make test does not assume the . is in PATH. *************** *** 332,338 **** Fixed coredump on access to $0 inside BEGIN block. Fixed treatment of RS = "". It now parses the fields correctly and strips ! leading whitspace from a record if FS is a space. Fixed faking of /dev/stdin. --- 420,426 ---- Fixed coredump on access to $0 inside BEGIN block. Fixed treatment of RS = "". It now parses the fields correctly and strips ! leading whitespace from a record if FS is a space. Fixed faking of /dev/stdin. *************** *** 376,382 **** Added config/apollo, config/msc60, config/cray2-50, config/interactive2.2 ! sgi33.cc added for compilation using cc ratther than gcc. Ultrix41 now propagates to config.h properly -- as part of a general mechanism in configure for kludges -- #define anything from a config file --- 464,470 ---- Added config/apollo, config/msc60, config/cray2-50, config/interactive2.2 ! sgi33.cc added for compilation using cc rather than gcc. Ultrix41 now propagates to config.h properly -- as part of a general mechanism in configure for kludges -- #define anything from a config file *************** *** 697,703 **** Changes from 2.12.22 to 2.12.23 ------------------------------- ! Accidently left config/cray2-60 out of last patch. Added some missing dependencies to Makefile. --- 785,791 ---- Changes from 2.12.22 to 2.12.23 ------------------------------- ! Accidentally left config/cray2-60 out of last patch. Added some missing dependencies to Makefile. *************** *** 847,853 **** ------------------------------- Changed config/* to a condensed form that can be used with mkconf to generate ! a config.h from config.h-dist -- much easier to maintain. Please chaeck carefully against what you had before for a particular system and report any problems. vms.h remains separate since the stuff at the bottom didn't quite fit the mkconf model -- hopefully cleared up later. --- 935,941 ---- ------------------------------- Changed config/* to a condensed form that can be used with mkconf to generate ! a config.h from config.h-dist -- much easier to maintain. Please check carefully against what you had before for a particular system and report any problems. vms.h remains separate since the stuff at the bottom didn't quite fit the mkconf model -- hopefully cleared up later. *************** *** 1199,1205 **** Went from "beta" to production status!!! Now flushes stdout before closing pipes or redirected files to ! synchonize output. MS-DOS changes added in. --- 1287,1293 ---- Went from "beta" to production status!!! Now flushes stdout before closing pipes or redirected files to ! synchronize output. MS-DOS changes added in. *************** *** 1314,1320 **** Fixed an obscure bug to do with redirection. Intermingled ">" and ">>" redirects did not output in a predictable order. ! Improved handling of output bufferring: now all print[f]s redirected to a tty or pipe are flushed immediately and non-redirected output to a tty is flushed before the next input record is read. --- 1402,1408 ---- Fixed an obscure bug to do with redirection. Intermingled ">" and ">>" redirects did not output in a predictable order. ! Improved handling of output buffering: now all print[f]s redirected to a tty or pipe are flushed immediately and non-redirected output to a tty is flushed before the next input record is read. diff -crN gawk-2.15.4/PORTS gawk-2.15.5/PORTS *** gawk-2.15.4/PORTS Wed May 5 19:49:13 1993 --- gawk-2.15.5/PORTS Thu May 19 00:34:40 1994 *************** *** 18,32 **** MSDOS - Microsoft C 5.1, compiles and runs very simple testing BSD 4.4alpha ! From: ghazi@caip.rutgers.edu (Kaveh R. Ghazi): arch configured as: ---- -------------- Hpux 9.0 hpux8x NeXTStep 2.0 next20 ! Sgi Irix 4.0.5 (/bin/cc) sgi405.cc (new file) Stardent Titan 1500 OSv2.5 sysv3 Stardent Vistra (i860) SVR4 sysv4 ! SunOS 4.1.2 sunos41 Tektronix XD88 (UTekV 3.2e) sysv3 Ultrix 4.2 ultrix41 --- 18,35 ---- MSDOS - Microsoft C 5.1, compiles and runs very simple testing BSD 4.4alpha ! From: ghazi@noc.rutgers.edu (Kaveh R. Ghazi): arch configured as: ---- -------------- + Dec Alpha OSF 1.3 osf1 Hpux 9.0 hpux8x NeXTStep 2.0 next20 ! Sgi Irix 4.0.5 (/bin/cc) sgi405.cc Stardent Titan 1500 OSv2.5 sysv3 Stardent Vistra (i860) SVR4 sysv4 ! Solaris 2.3 solaris2.cc ! SunOS 4.1.3 sunos41 Tektronix XD88 (UTekV 3.2e) sysv3 + Tektronix 4300 (UTek 4.0) utek Ultrix 4.2 ultrix41 diff -crN gawk-2.15.4/README gawk-2.15.5/README *** gawk-2.15.4/README Wed Dec 29 10:54:41 1993 --- gawk-2.15.5/README Wed May 11 23:22:16 1994 *************** *** 1,8 **** README: ! This is GNU Awk 2.15. It should be upwardly compatible with the ! System V Release 4 awk. It is almost completely compliant with draft 11.3 ! of POSIX 1003.2. This release adds new features -- see NEWS for details. --- 1,7 ---- README: ! This is GNU Awk 2.15. It should be upwardly compatible with the System ! V Release 4 awk. It is almost completely compliant with POSIX 1003.2. This release adds new features -- see NEWS for details. *************** *** 28,34 **** Check whether there is a system-specific README file for your system. ! A quick overview of the installation process is in the file INSTALLATION. Makefile.in may need some tailoring. The only changes necessary should be to change installation targets or to change compiler flags. --- 27,33 ---- Check whether there is a system-specific README file for your system. ! A quick overview of the installation process is in the file INSTALL. Makefile.in may need some tailoring. The only changes necessary should be to change installation targets or to change compiler flags. diff -crN gawk-2.15.4/README.atari gawk-2.15.5/README.atari *** gawk-2.15.4/README.atari Thu Oct 21 22:51:34 1993 --- gawk-2.15.5/README.atari Sun May 15 00:06:15 1994 *************** *** 15,21 **** Nearly all of these test do not require any adjustments to run, but a modified test suite with a driving Makefile (for gulam) is available ! on a request from Michal Jaegermann, ntomczak@vm.ucs.ualberta.ca, via e-mail. TOS and MiNT --- 15,21 ---- Nearly all of these test do not require any adjustments to run, but a modified test suite with a driving Makefile (for gulam) is available ! on a request from Michal Jaegermann, michal@gortel.phys.ualberta.ca, via e-mail. TOS and MiNT diff -crN gawk-2.15.4/README.hpux8x gawk-2.15.5/README.hpux8x *** gawk-2.15.4/README.hpux8x Wed Dec 29 10:58:33 1993 --- gawk-2.15.5/README.hpux8x Sun Jan 30 23:31:00 1994 *************** *** 11,13 **** --- 11,18 ---- hp's C compiler, it does fine. If you compile with cc and it fails, then let me hear about it please. If you compile with gcc and then complain to me, I'm going to fuss at you for not reading the documenation. (:-) + ------------------------------------ + + January 1994 - arnold@skeeve.atl.ga.us + + I'm told that with gcc 2.5.8, gawk now compiles. diff -crN gawk-2.15.4/README.sgi gawk-2.15.5/README.sgi *** gawk-2.15.4/README.sgi Thu Jan 20 22:19:21 1994 --- gawk-2.15.5/README.sgi Fri Apr 29 06:45:32 1994 *************** *** 1,7 **** ! January 1994 ! I have reports that gawk fails to pass its tests when compiled with gcc on ! the IRIX, through gcc 2.5.7. Therefore you should probably try compiling ! with cc. If gawk compiled with cc fails to pass its `make test', then I want ! to hear about it. Otherwise I will fuss at you for not reading the ! documentation. --- 1,5 ---- ! April 1994 ! I'm told that gawk now compiles on the SGI with gcc without problems. ! The main issue was apparently the use of CHAR_UNSIGNED in regex.c, and ! the current regex.c now manages to figure it out on its own. diff -crN gawk-2.15.4/array.c gawk-2.15.5/array.c *** gawk-2.15.4/array.c Sat Jan 15 22:41:42 1994 --- gawk-2.15.5/array.c Sun Apr 17 17:14:25 1994 *************** *** 111,116 **** --- 111,117 ---- free(symbol->var_array); symbol->var_array = NULL; symbol->array_size = symbol->table_size = 0; + symbol->flags &= ~ARRAYMAXED; } /* *************** *** 229,239 **** --- 230,248 ---- for (bucket = symbol->var_array[hash1]; bucket; bucket = bucket->ahnext) { if (cmp_nodes(bucket->ahname, subs) == 0) { + #if 0 + /* + * Disable this code for now. It screws things up if we have + * a ``for (iggy in foo)'' in progress. Interestingly enough, + * this was not a problem in 2.15.3, only in 2.15.4. I'm not + * sure why it works in 2.15.3. + */ if (prev) { /* move found to front of chain */ prev->ahnext = bucket->ahnext; bucket->ahnext = symbol->var_array[hash1]; symbol->var_array[hash1] = bucket; } + #endif return bucket; } else prev = bucket; /* save previous list entry */ *************** *** 284,289 **** --- 293,299 ---- if (symbol->var_array == 0) { symbol->type = Node_var_array; symbol->array_size = symbol->table_size = 0; /* sanity */ + symbol->flags &= ~ARRAYMAXED; grow_table(symbol); hash1 = hash(subs->stptr, subs->stlen, (unsigned long) symbol->array_size); *************** *** 368,374 **** memset(symbol->var_array, '\0', sizeof(NODE *) * symbol->array_size); symbol->table_size = symbol->array_size = 0; ! free(symbol->var_array); symbol->var_array = NULL; } } --- 378,385 ---- memset(symbol->var_array, '\0', sizeof(NODE *) * symbol->array_size); symbol->table_size = symbol->array_size = 0; ! symbol->flags &= ~ARRAYMAXED; ! free((char *) symbol->var_array); symbol->var_array = NULL; } } *************** *** 378,409 **** NODE *symbol; struct search *lookat; { ! if (symbol->var_array == NULL) { ! lookat->retval = NULL; ! return; ! } ! lookat->arr_ptr = symbol->var_array; ! lookat->arr_end = lookat->arr_ptr + symbol->array_size; ! lookat->bucket = symbol->var_array[0]; ! assoc_next(lookat); } void assoc_next(lookat) struct search *lookat; { ! while (lookat->arr_ptr < lookat->arr_end) { ! if (lookat->bucket != 0) { ! lookat->retval = lookat->bucket->ahname; ! lookat->bucket = lookat->bucket->ahnext; return; } - lookat->arr_ptr++; - if (lookat->arr_ptr < lookat->arr_end) - lookat->bucket = *(lookat->arr_ptr); - else - lookat->retval = NULL; } return; } --- 389,442 ---- NODE *symbol; struct search *lookat; { ! lookat->sym = symbol; ! lookat->idx = 0; ! lookat->bucket = NULL; ! lookat->retval = NULL; ! if (symbol->var_array != NULL) ! assoc_next(lookat); } void assoc_next(lookat) struct search *lookat; { ! register NODE *symbol = lookat->sym; ! ! if (symbol == NULL) ! fatal("null symbol in assoc_next"); ! if (symbol->var_array == NULL || lookat->idx > symbol->array_size) { ! lookat->retval = NULL; ! return; ! } ! /* ! * This is theoretically unsafe. The element bucket might have ! * been freed if the body of the scan did a delete on the next ! * element of the bucket. The only way to do that is by array ! * reference, which is unlikely. Basically, if the user is doing ! * anything other than an operation on the current element of an ! * assoc array while walking through it sequentially, all bets are ! * off. (The safe way is to register all search structs on an ! * array with the array, and update all of them on a delete or ! * insert) ! */ ! if (lookat->bucket != NULL) { ! lookat->retval = lookat->bucket->ahname; ! lookat->bucket = lookat->bucket->ahnext; ! return; ! } ! for (; lookat->idx < symbol->array_size; lookat->idx++) { ! NODE *bucket; ! ! if ((bucket = symbol->var_array[lookat->idx]) != NULL) { ! lookat->retval = bucket->ahname; ! lookat->bucket = bucket->ahnext; ! lookat->idx++; return; } } + lookat->retval = NULL; + lookat->bucket = NULL; return; } diff -crN gawk-2.15.4/atari/config.h gawk-2.15.5/atari/config.h *** gawk-2.15.4/atari/config.h Wed Dec 8 23:06:29 1993 --- gawk-2.15.5/atari/config.h Fri Apr 29 06:51:48 1994 *************** *** 11,55 **** #define SZTC (size_t) #define INTC (int) ! #define HAVE_STRING_H 1 /* have */ ! #ifdef HAVE_STRING_H ! #undef NEED_MEMORY_H /* need to declare memcpy() et al. */ ! #endif ! ! #define STDC_HEADERS 1 /* have the usual ANSI header files */ ! #undef HAVE_UNISTD_H /* have */ ! #undef HAVE_ALLOCA_H /* have -- only used if bison is used */ ! #undef HAVE_SIGNUM_H /* have */ ! #undef REGEX_MALLOC /* don't use alloca in regex.c */ ! ! #define HAVE_VPRINTF 1 /* have vprintf() */ ! ! #define HAVE_RANDOM 1 /* have random(), or using missing/random.c */ ! ! #define HAVE_STRCHR 1 /* have strchr() and strrchr() */ ! #ifndef HAVE_STRCHR ! #ifdef HAVE_RINDEX /* use index() and rindex() if present */ ! #define strchr index ! #define strrchr rindex ! #endif ! #endif ! ! #define HAVE_FMOD 1 /* have fmod(), otherwise use modf() */ ! ! #define HAVE_MEMCPY 1 /* have memcpy() et al. */ ! ! #define HAVE_ST_BLKSIZE 1 /* have st_blksize member in the stat(2) structure */ ! ! #define HAVE_STRFTIME 1 ! ! #define HAVE_STRINGIZE 1 /* have ANSI "stringizing" capability */ #undef __CHAR_UNSIGNED__ /* default char is signed */ - #define RETSIGTYPE void /* type used in signal() */ - #define SPRINTF_RET int /* type returned by sprintf() */ - - #undef _ALL_SOURCE /* on AIX, used to get some BSD functions */ /* * srandom already has a prototype defined - don't redefine it */ --- 11,21 ---- #define SZTC (size_t) #define INTC (int) ! #define STDC_HEADERS 1 /* have the usual ANSI header files */ ! #undef REGEX_MALLOC /* use alloca in regex.c */ #undef __CHAR_UNSIGNED__ /* default char is signed */ /* * srandom already has a prototype defined - don't redefine it */ diff -crN gawk-2.15.4/awk.h gawk-2.15.5/awk.h *** gawk-2.15.4/awk.h Tue Jan 4 16:27:48 1994 --- gawk-2.15.5/awk.h Wed May 11 22:28:46 1994 *************** *** 24,31 **** --- 24,35 ---- */ /* ------------------------------ Includes ------------------------------ */ + #include "config.h" + #include + #ifndef LIMITS_H_MISSING #include + #endif #include #include #include *************** *** 53,60 **** #include - #include "config.h" - #ifdef __STDC__ #define P(s) s #define MALLOC_ARG_T size_t --- 57,62 ---- *************** *** 154,160 **** extern int pclose P((FILE *)); extern void vms_arg_fixup P((int *,char ***)); /* some things not in STDC_HEADERS */ ! extern int gnu_strftime P((char *,size_t,const char *,const struct tm *)); extern int unlink P((const char *)); extern int getopt P((int,char **,char *)); extern int isatty P((int)); --- 156,162 ---- extern int pclose P((FILE *)); extern void vms_arg_fixup P((int *,char ***)); /* some things not in STDC_HEADERS */ ! extern size_t gnu_strftime P((char *,size_t,const char *,const struct tm *)); extern int unlink P((const char *)); extern int getopt P((int,char **,char *)); extern int isatty P((int)); *************** *** 196,216 **** #define ENVSEP ':' #endif ! #define DEFAULT_G_PRECISION 6 ! ! /* semi-temporary hack, mostly to gracefully handle VMS */ ! #ifdef GFMT_WORKAROUND ! extern void sgfmt P((char *, const char *, int, int, int, double)); /* builtin.c */ ! ! /* Partial fix, to handle the most common case. */ ! #define NUMTOSTR(str, format, num) \ ! if (strcmp((format), "%.6g") == 0 || strcmp((format), "%g") == 0) \ ! sgfmt(str, "%*.*g", 0, 1, DEFAULT_G_PRECISION, num); \ ! else \ ! (void) sprintf(str, format, num) /* NOTE: no semi-colon! */ ! #else ! #define NUMTOSTR(str, format, num) (void) sprintf(str, format, num) ! #endif /* GFMT_WORKAROUND */ /* ------------------ Constants, Structures, Typedefs ------------------ */ #define AWKNUM double --- 198,204 ---- #define ENVSEP ':' #endif ! extern double double_to_int P((double d)); /* ------------------ Constants, Structures, Typedefs ------------------ */ #define AWKNUM double *************** *** 460,467 **** /* for "for(iggy in foo) {" */ struct search { ! NODE **arr_ptr; ! NODE **arr_end; NODE *bucket; NODE *retval; }; --- 448,455 ---- /* for "for(iggy in foo) {" */ struct search { ! NODE *sym; ! size_t idx; NODE *bucket; NODE *retval; }; *************** *** 519,531 **** /* Return means return from a function call; leave value in ret_node */ #define TAG_RETURN 3 #define HUGE INT_MAX /* -------------------------- External variables -------------------------- */ /* gawk builtin variables */ ! extern int NF; ! extern int NR; ! extern int FNR; extern int IGNORECASE; extern char *RS; extern char *OFS; --- 507,531 ---- /* Return means return from a function call; leave value in ret_node */ #define TAG_RETURN 3 + #ifndef INT_MAX + #define INT_MAX (~(1 << (sizeof (int) * 8 - 1))) + #endif + #ifndef LONG_MAX + #define LONG_MAX (~(1 << (sizeof (long) * 8 - 1))) + #endif + #ifndef ULONG_MAX + #define ULONG_MAX (~(unsigned long)0) + #endif + #ifndef LONG_MIN + #define LONG_MIN (-LONG_MAX - 1) + #endif #define HUGE INT_MAX /* -------------------------- External variables -------------------------- */ /* gawk builtin variables */ ! extern long NF; ! extern long NR; ! extern long FNR; extern int IGNORECASE; extern char *RS; extern char *OFS; *************** *** 583,594 **** #else #define get_lhs(p, a) ((p)->type == Node_var ? (&(p)->var_value) : \ r_get_lhs((p), (a))) ! #define tree_eval(t) (_t = (t),(_t) == NULL ? Nnull_string : \ ! ((_t)->type == Node_val ? (_t) : \ ! ((_t)->type == Node_var ? (_t)->var_value : \ ! ((_t)->type == Node_param_list ? \ ! (stack_ptr[(_t)->param_cnt])->var_value : \ ! r_tree_eval((_t)))))) #endif #define make_number(x) mk_number((x), (unsigned int)(MALLOC|NUM|NUMBER)) --- 583,593 ---- #else #define get_lhs(p, a) ((p)->type == Node_var ? (&(p)->var_value) : \ r_get_lhs((p), (a))) ! #define tree_eval(t) (_t = (t),_t == NULL ? Nnull_string : \ ! (_t->type == Node_param_list ? r_tree_eval(_t) : \ ! (_t->type == Node_val ? _t : \ ! (_t->type == Node_var ? _t->var_value : \ ! r_tree_eval(_t))))) #endif #define make_number(x) mk_number((x), (unsigned int)(MALLOC|NUM|NUMBER)) diff -crN gawk-2.15.4/awk.y gawk-2.15.5/awk.y *** gawk-2.15.4/awk.y Tue Jan 4 16:18:18 1994 --- gawk-2.15.5/awk.y Wed May 11 22:35:16 1994 *************** *** 163,168 **** --- 163,169 ---- } | error { $$ = NULL; } | program error { $$ = NULL; } + | /* empty */ { $$ = NULL; } ; rule *************** *** 718,724 **** $$ = node ($2, Node_unary_minus, (NODE *)NULL); } | '+' simp_exp %prec UNARY ! { $$ = $2; } ; opt_variable --- 719,729 ---- $$ = node ($2, Node_unary_minus, (NODE *)NULL); } | '+' simp_exp %prec UNARY ! { ! /* was: $$ = $2 */ ! /* POSIX semantics: force a conversion to numeric type */ ! $$ = node (make_number(0.0), Node_plus, $2); ! } ; opt_variable *************** *** 852,858 **** errcount++; /* Find the current line in the input file */ ! if (lexptr) { if (!thisline) { cp = lexeme; if (*cp == '\n') { --- 857,863 ---- errcount++; /* Find the current line in the input file */ ! if (lexptr && lexeme) { if (!thisline) { cp = lexeme; if (*cp == '\n') { *************** *** 860,866 **** mesg = "unexpected newline"; } for ( ; cp != lexptr_begin && *cp != '\n'; --cp) ! ; if (*cp == '\n') cp++; thisline = cp; --- 865,871 ---- mesg = "unexpected newline"; } for ( ; cp != lexptr_begin && *cp != '\n'; --cp) ! continue; if (*cp == '\n') cp++; thisline = cp; *************** *** 908,919 **** --- 913,934 ---- static int did_newline = 0; # define SLOP 128 /* enough space to hold most source lines */ + again: if (nextfile > numfiles) return NULL; if (srcfiles[nextfile].stype == CMDLINE) { if (len == 0) { len = strlen(srcfiles[nextfile].val); + if (len == 0) { + /* + * Yet Another Special case: + * gawk '' /path/name + * Sigh. + */ + ++nextfile; + goto again; + } sourceline = 1; lexptr = lexptr_begin = srcfiles[nextfile].val; lexend = lexptr + len; *************** *** 999,1004 **** --- 1014,1020 ---- if (n == 0) { samefile = 0; nextfile++; + *lexeme = '\0'; len = 0; return get_src_buf(); } *************** *** 1115,1121 **** } retry: while ((c = nextc()) == ' ' || c == '\t') ! ; lexeme = lexptr ? lexptr - 1 : lexptr; thisline = NULL; --- 1131,1137 ---- } retry: while ((c = nextc()) == ' ' || c == '\t') ! continue; lexeme = lexptr ? lexptr - 1 : lexptr; thisline = NULL; *************** *** 1430,1436 **** break; if (c == '#') { while ((c = nextc()) != '\n' && c != '\0') ! ; if (c == '\0') break; } --- 1446,1452 ---- break; if (c == '#') { while ((c = nextc()) != '\n' && c != '\0') ! continue; if (c == '\0') break; } *************** *** 1456,1462 **** break; if (c == '#') { while ((c = nextc()) != '\n' && c != '\0') ! ; if (c == '\0') break; } --- 1472,1478 ---- break; if (c == '#') { while ((c = nextc()) != '\n' && c != '\0') ! continue; if (c == '\0') break; } *************** *** 1524,1529 **** --- 1540,1546 ---- else yylval.nodetypeval = tokentab[mid].value; + free(tokkey); return tokentab[mid].class; } } diff -crN gawk-2.15.4/builtin.c gawk-2.15.5/builtin.c *** gawk-2.15.4/builtin.c Fri Jan 7 14:24:48 1994 --- gawk-2.15.5/builtin.c Thu May 19 00:34:01 1994 *************** *** 27,33 **** #include "awk.h" #ifndef SRANDOM_PROTO ! extern void srandom P((int seed)); #endif #ifndef linux extern char *initstate P((unsigned seed, char *state, int n)); --- 27,33 ---- #include "awk.h" #ifndef SRANDOM_PROTO ! extern void srandom P((unsigned int seed)); #endif #ifndef linux extern char *initstate P((unsigned seed, char *state, int n)); *************** *** 39,44 **** --- 39,45 ---- extern int output_is_tty; static NODE *sub_common P((NODE *tree, int global)); + NODE *format_tree P((const char *, int, NODE *)); #ifdef _CRAY /* Work around a problem in conversion of doubles to exact integers. */ *************** *** 58,63 **** --- 59,83 ---- #define Ceil(n) ceil(n) #endif + #define DEFAULT_G_PRECISION 6 + + #ifdef GFMT_WORKAROUND + /* semi-temporary hack, mostly to gracefully handle VMS */ + static void sgfmt P((char *buf, const char *format, int alt, + int fwidth, int precision, double value)); + #endif /* GFMT_WORKAROUND */ + + /* + * On the alpha, LONG_MAX is too big for doing rand(). + * On the Cray (Y-MP, anyway), ints and longs are 64 bits, but + * random() does things in terms of 32 bits. So we have to chop + * LONG_MAX down. + */ + #if (defined(__alpha) && defined(__osf__)) || defined(_CRAY) + #define GAWK_RANDOM_MAX (LONG_MAX & 0x7fffffff) + #else + #define GAWK_RANDOM_MAX LONG_MAX + #endif static void efwrite P((const void *ptr, size_t size, size_t count, FILE *fp, const char *from, struct redirect *rp,int flush)); *************** *** 159,179 **** return tmp_number((AWKNUM) ret); } NODE * do_int(tree) NODE *tree; { NODE *tmp; - double floor P((double)); - double ceil P((double)); double d; tmp = tree_eval(tree->lnode); d = force_number(tmp); ! if (d >= 0) ! d = Floor(d); ! else ! d = Ceil(d); free_temp(tmp); return tmp_number((AWKNUM) d); } --- 179,208 ---- return tmp_number((AWKNUM) ret); } + double + double_to_int(d) + double d; + { + double floor P((double)); + double ceil P((double)); + + if (d >= 0) + d = Floor(d); + else + d = Ceil(d); + return d; + } + NODE * do_int(tree) NODE *tree; { NODE *tmp; double d; tmp = tree_eval(tree->lnode); d = force_number(tmp); ! d = double_to_int(d); free_temp(tmp); return tmp_number((AWKNUM) d); } *************** *** 211,231 **** } /* ! * do_sprintf does the sprintf function. It is one of the uglier parts of ! * gawk. Thanks to Michal Jaegerman for taming this beast and making it ! * compatible with ANSI C. */ NODE * ! do_sprintf(tree) ! NODE *tree; { /* copy 'l' bytes from 's' to 'obufout' checking for space in the process */ /* difference of pointers should be of ptrdiff_t type, but let us be kind */ #define bchunk(s,l) if(l) {\ while((l)>ofre) {\ long olen = obufout - obuf;\ ! erealloc(obuf, char *, osiz*2, "do_sprintf");\ ofre+=osiz;\ osiz*=2;\ obufout = obuf + olen;\ --- 240,266 ---- } /* ! * format_tree() formats nodes of a tree, starting with a left node, ! * and accordingly to a fmt_string providing a format like in ! * printf family from C library. Returns a string node which value ! * is a formatted string. Called by sprintf function. ! * ! * It is one of the uglier parts of gawk. Thanks to Michal Jaegermann ! * for taming this beast and making it compatible with ANSI C. */ NODE * ! format_tree(fmt_string, n0, carg) ! const char *fmt_string; ! int n0; ! register NODE *carg; { /* copy 'l' bytes from 's' to 'obufout' checking for space in the process */ /* difference of pointers should be of ptrdiff_t type, but let us be kind */ #define bchunk(s,l) if(l) {\ while((l)>ofre) {\ long olen = obufout - obuf;\ ! erealloc(obuf, char *, osiz*2, "format_tree");\ ofre+=osiz;\ osiz*=2;\ obufout = obuf + olen;\ *************** *** 238,244 **** #define bchunk_one(s) {\ if(ofre <= 0) {\ long olen = obufout - obuf;\ ! erealloc(obuf, char *, osiz*2, "do_sprintf");\ ofre+=osiz;\ osiz*=2;\ obufout = obuf + olen;\ --- 273,279 ---- #define bchunk_one(s) {\ if(ofre <= 0) {\ long olen = obufout - obuf;\ ! erealloc(obuf, char *, osiz*2, "format_tree");\ ofre+=osiz;\ osiz*=2;\ obufout = obuf + olen;\ *************** *** 249,255 **** /* Is there space for something L big in the buffer? */ #define chksize(l) if((l)>ofre) {\ ! erealloc(obuf, char *, osiz*2, "do_sprintf");\ ofre+=osiz;\ osiz*=2;\ } --- 284,292 ---- /* Is there space for something L big in the buffer? */ #define chksize(l) if((l)>ofre) {\ ! long olen = obufout - obuf;\ ! erealloc(obuf, char *, osiz*2, "format_tree");\ ! obufout = obuf + olen;\ ofre+=osiz;\ osiz*=2;\ } *************** *** 271,283 **** char *obuf, *obufout; size_t osiz, ofre; char *chbuf; ! char *s0, *s1; int cs1; ! int n0; ! NODE *sfmt, *arg; ! register NODE *carg; long fw, prec; ! int lj, alt, big; long *cur; long val; #ifdef sun386 /* Can't cast unsigned (int/long) from ptr->value */ --- 308,318 ---- char *obuf, *obufout; size_t osiz, ofre; char *chbuf; ! const char *s0, *s1; int cs1; ! NODE *arg; long fw, prec; ! int lj, alt, big, have_prec; long *cur; long val; #ifdef sun386 /* Can't cast unsigned (int/long) from ptr->value */ *************** *** 285,291 **** #endif unsigned long uval; int sgn; ! int base; char cpbuf[30]; /* if we have numbers bigger than 30 */ char *cend = &cpbuf[30];/* chars, we lose, but seems unlikely */ char *cp; --- 320,326 ---- #endif unsigned long uval; int sgn; ! int base = 0; char cpbuf[30]; /* if we have numbers bigger than 30 */ char *cend = &cpbuf[30];/* chars, we lose, but seems unlikely */ char *cp; *************** *** 295,311 **** size_t len; static char sp[] = " "; static char zero_string[] = "0"; ! static char lchbuf[] = "0123456789abcdefx"; ! static char Uchbuf[] = "0123456789ABCDEFX"; ! emalloc(obuf, char *, 120, "do_sprintf"); obufout = obuf; osiz = 120; ofre = osiz - 1; ! sfmt = tree_eval(tree->lnode); ! sfmt = force_string(sfmt); ! carg = tree->rnode; ! for (s0 = s1 = sfmt->stptr, n0 = sfmt->stlen; n0-- > 0;) { if (*s1 != '%') { s1++; continue; --- 330,345 ---- size_t len; static char sp[] = " "; static char zero_string[] = "0"; ! static char lchbuf[] = "0123456789abcdef"; ! static char Uchbuf[] = "0123456789ABCDEF"; ! emalloc(obuf, char *, 120, "format_tree"); obufout = obuf; osiz = 120; ofre = osiz - 1; ! ! s0 = s1 = fmt_string; ! while (n0-- > 0) { if (*s1 != '%') { s1++; continue; *************** *** 315,328 **** --- 349,369 ---- cur = &fw; fw = 0; prec = 0; + have_prec = 0; lj = alt = big = 0; fill = sp; cp = cend; + chbuf = lchbuf; s1++; retry: --n0; switch (cs1 = *s1++) { + case (-1): /* dummy case to allow for checking */ + check_pos: + if (cur != &fw) + break; /* reject as a valid format */ + goto retry; case '%': bchunk_one("%"); s0 = s1; *************** *** 345,361 **** if (cur == 0) /* goto lose; */ break; ! if (prec >= 0) /* this happens only when we have */ ! /* a negative precision */ *cur = cs1 - '0'; while (n0 > 0 && *s1 >= '0' && *s1 <= '9') { --n0; *cur = *cur * 10 + *s1++ - '0'; } ! if (prec < 0) { /* negative precision is discarded */ ! prec = 0; cur = 0; - } goto retry; case '*': if (cur == 0) --- 386,404 ---- if (cur == 0) /* goto lose; */ break; ! if (prec >= 0) *cur = cs1 - '0'; + /* with a negative precision *cur is already set */ + /* to -1, so it will remain negative, but we have */ + /* to "eat" precision digits in any case */ while (n0 > 0 && *s1 >= '0' && *s1 <= '9') { --n0; *cur = *cur * 10 + *s1++ - '0'; } ! if (prec < 0) /* negative precision is discarded */ ! have_prec = 0; ! if (cur == &prec) cur = 0; goto retry; case '*': if (cur == 0) *************** *** 364,402 **** parse_next_arg(); *cur = force_number(arg); free_temp(arg); goto retry; case ' ': /* print ' ' or '-' */ /* 'space' flag is ignored */ /* if '+' already present */ if (signchar != 0) ! goto retry; /* FALL THROUGH */ case '+': /* print '+' or '-' */ signchar = cs1; ! goto retry; case '-': if (cur == &prec) { prec = -1; goto retry; } fill = sp; /* if left justified then other */ lj++; /* filling is ignored */ ! goto retry; case '.': if (cur != &fw) break; cur = ≺ goto retry; case '#': - if (cur != &fw) - break; alt++; ! goto retry; case 'l': if (big) break; big++; ! goto retry; case 'c': parse_next_arg(); if (arg->flags & NUMBER) { --- 407,448 ---- parse_next_arg(); *cur = force_number(arg); free_temp(arg); + if (cur == &prec) + cur = 0; goto retry; case ' ': /* print ' ' or '-' */ /* 'space' flag is ignored */ /* if '+' already present */ if (signchar != 0) ! goto check_pos; /* FALL THROUGH */ case '+': /* print '+' or '-' */ signchar = cs1; ! goto check_pos; case '-': + if (prec < 0) + break; if (cur == &prec) { prec = -1; goto retry; } fill = sp; /* if left justified then other */ lj++; /* filling is ignored */ ! goto check_pos; case '.': if (cur != &fw) break; cur = ≺ + have_prec++; goto retry; case '#': alt++; ! goto check_pos; case 'l': if (big) break; big++; ! goto check_pos; case 'c': parse_next_arg(); if (arg->flags & NUMBER) { *************** *** 411,417 **** cp = cpbuf; goto pr_tail; } ! if (prec == 0) prec = 1; else if (prec > arg->stlen) prec = arg->stlen; --- 457,463 ---- cp = cpbuf; goto pr_tail; } ! if (have_prec == 0) prec = 1; else if (prec > arg->stlen) prec = arg->stlen; *************** *** 420,447 **** case 's': parse_next_arg(); arg = force_string(arg); ! if (prec == 0 || prec > arg->stlen) prec = arg->stlen; cp = arg->stptr; goto pr_tail; case 'd': case 'i': parse_next_arg(); ! val = (long) force_number(arg); if (val < 0) { sgn = 1; ! val = -val; ! } else sgn = 0; do { ! *--cp = '0' + val % 10; ! val /= 10; ! } while (val); if (sgn) *--cp = '-'; else if (signchar) *--cp = signchar; ! if (prec != 0) /* ignore '0' flag if */ fill = sp; /* precision given */ if (prec > fw) fw = prec; --- 466,506 ---- case 's': parse_next_arg(); arg = force_string(arg); ! if (have_prec == 0 || prec > arg->stlen) prec = arg->stlen; cp = arg->stptr; goto pr_tail; case 'd': case 'i': parse_next_arg(); ! tmpval = force_number(arg); ! if (tmpval > LONG_MAX || tmpval < LONG_MIN) { ! /* out of range - emergency use of %g format */ ! cs1 = 'g'; ! goto format_float; ! } ! val = (long) tmpval; ! if (val < 0) { sgn = 1; ! if (val > LONG_MIN) ! uval = (unsigned long) -val; ! else ! uval = (unsigned long)(-(LONG_MIN + 1)) ! + (unsigned long)1; ! } else { sgn = 0; + uval = (unsigned long) val; + } do { ! *--cp = (char) ('0' + uval % 10); ! uval /= 10; ! } while (uval); if (sgn) *--cp = '-'; else if (signchar) *--cp = signchar; ! if (have_prec != 0) /* ignore '0' flag if */ fill = sp; /* precision given */ if (prec > fw) fw = prec; *************** *** 454,477 **** fw--; } goto pr_tail; - case 'u': - base = 10; - goto pr_unsigned; - case 'o': - base = 8; - goto pr_unsigned; case 'X': case 'x': ! base = 16; ! pr_unsigned: ! if (cs1 == 'X') ! chbuf = Uchbuf; ! else ! chbuf = lchbuf; ! if (prec != 0) /* ignore '0' flag if */ ! fill = sp; /* precision given */ parse_next_arg(); ! uval = (unsigned long) force_number(arg); do { *--cp = chbuf[uval % base]; uval /= base; --- 513,536 ---- fw--; } goto pr_tail; case 'X': + chbuf = Uchbuf; /* FALL THROUGH */ case 'x': ! base += 6; /* FALL THROUGH */ ! case 'u': ! base += 2; /* FALL THROUGH */ ! case 'o': ! base += 8; parse_next_arg(); ! tmpval = force_number(arg); ! if (tmpval > ULONG_MAX || tmpval < LONG_MIN) { ! /* out of range - emergency use of %g format */ ! cs1 = 'g'; ! goto format_float; ! } ! uval = (unsigned long)tmpval; ! if (have_prec != 0) /* ignore '0' flag if */ ! fill = sp; /* precision given */ do { *--cp = chbuf[uval % base]; uval /= base; *************** *** 488,493 **** --- 547,553 ---- } else if (base == 8) *--cp = '0'; } + base = 0; prec = cend - cp; pr_tail: if (! lj) { *************** *** 504,517 **** s0 = s1; free_temp(arg); break; case 'e': case 'f': - case 'g': case 'E': - case 'G': parse_next_arg(); tmpval = force_number(arg); free_temp(arg); chksize(fw + prec + 9); /* 9==slop */ cp = cpbuf; --- 564,580 ---- s0 = s1; free_temp(arg); break; + case 'g': + case 'G': case 'e': case 'f': case 'E': parse_next_arg(); tmpval = force_number(arg); + format_float: free_temp(arg); + if (have_prec == 0) + prec = DEFAULT_G_PRECISION; chksize(fw + prec + 9); /* 9==slop */ cp = cpbuf; *************** *** 527,540 **** cp = strcpy(cp, "*.*") + 3; *cp++ = cs1; *cp = '\0'; - if (prec <= 0) - prec = DEFAULT_G_PRECISION; #ifndef GFMT_WORKAROUND (void) sprintf(obufout, cpbuf, (int) fw, (int) prec, (double) tmpval); #else /* GFMT_WORKAROUND */ if (cs1 == 'g' || cs1 == 'G') ! (void) sgfmt(obufout, cpbuf, (int) alt, (int) fw, (int) prec, (double) tmpval); else (void) sprintf(obufout, cpbuf, --- 590,601 ---- cp = strcpy(cp, "*.*") + 3; *cp++ = cs1; *cp = '\0'; #ifndef GFMT_WORKAROUND (void) sprintf(obufout, cpbuf, (int) fw, (int) prec, (double) tmpval); #else /* GFMT_WORKAROUND */ if (cs1 == 'g' || cs1 == 'G') ! sgfmt(obufout, cpbuf, (int) alt, (int) fw, (int) prec, (double) tmpval); else (void) sprintf(obufout, cpbuf, *************** *** 551,569 **** if (toofew) fatal("%s\n\t%s\n\t%*s%s", "not enough arguments to satisfy format string", ! sfmt->stptr, s1 - sfmt->stptr - 2, "", "^ ran out for this one" ); } if (do_lint && carg != NULL) warning("too many arguments supplied for format string"); bchunk(s0, s1 - s0); - free_temp(sfmt); r = make_str_node(obuf, obufout - obuf, ALREADY_MALLOCED); r->flags |= TEMP; return r; } void do_printf(tree) register NODE *tree; --- 612,642 ---- if (toofew) fatal("%s\n\t%s\n\t%*s%s", "not enough arguments to satisfy format string", ! fmt_string, s1 - fmt_string - 2, "", "^ ran out for this one" ); } if (do_lint && carg != NULL) warning("too many arguments supplied for format string"); bchunk(s0, s1 - s0); r = make_str_node(obuf, obufout - obuf, ALREADY_MALLOCED); r->flags |= TEMP; return r; } + NODE * + do_sprintf(tree) + NODE *tree; + { + NODE *r; + NODE *sfmt = force_string(tree_eval(tree->lnode)); + + r = format_tree(sfmt->stptr, sfmt->stlen, tree->rnode); + free_temp(sfmt); + return r; + } + + void do_printf(tree) register NODE *tree; *************** *** 718,723 **** --- 791,798 ---- return tmp_number((AWKNUM) ret); } + extern NODE **fmt_list; /* declared in eval.c */ + void do_print(tree) register NODE *tree; *************** *** 746,756 **** if (OFMTidx == CONVFMTidx) (void) force_string(t1); else { char buf[100]; ! NUMTOSTR(buf, OFMT, t1->numbr); free_temp(t1); t1 = tmp_string(buf, strlen(buf)); } } efwrite(t1->stptr, sizeof(char), t1->stlen, fp, "print", rp, 0); --- 821,838 ---- if (OFMTidx == CONVFMTidx) (void) force_string(t1); else { + #ifndef GFMT_WORKAROUND char buf[100]; ! (void) sprintf(buf, OFMT, t1->numbr); free_temp(t1); t1 = tmp_string(buf, strlen(buf)); + #else /* GFMT_WORKAROUND */ + free_temp(t1); + t1 = format_tree(OFMT, + fmt_list[OFMTidx]->stlen, + tree); + #endif /* GFMT_WORKAROUND */ } } efwrite(t1->stptr, sizeof(char), t1->stlen, fp, "print", rp, 0); *************** *** 759,765 **** if (tree) { s = OFS; if (OFSlen) ! efwrite(s, sizeof(char), (size_t)OFSlen, fp, "print", rp, 0); } } s = ORS; --- 841,848 ---- if (tree) { s = OFS; if (OFSlen) ! efwrite(s, sizeof(char), (size_t)OFSlen, ! fp, "print", rp, 0); } } s = ORS; *************** *** 847,853 **** } static int firstrand = 1; ! static char state[256]; /* ARGSUSED */ NODE * --- 930,936 ---- } static int firstrand = 1; ! static char state[512]; /* ARGSUSED */ NODE * *************** *** 859,865 **** srandom(1); firstrand = 0; } ! return tmp_number((AWKNUM) random() / LONG_MAX); } NODE * --- 942,948 ---- srandom(1); firstrand = 0; } ! return tmp_number((AWKNUM) random() / GAWK_RANDOM_MAX); } NODE * *************** *** 876,885 **** (void) setstate(state); if (!tree) ! srandom((int) (save_seed = (long) time((time_t *) 0))); else { tmp = tree_eval(tree->lnode); ! srandom((int) (save_seed = (long) force_number(tmp))); free_temp(tmp); } firstrand = 0; --- 959,968 ---- (void) setstate(state); if (!tree) ! srandom((unsigned int) (save_seed = (long) time((time_t *) 0))); else { tmp = tree_eval(tree->lnode); ! srandom((unsigned int) (save_seed = (long) force_number(tmp))); free_temp(tmp); } firstrand = 0; *************** *** 952,963 **** tmp = tree->lnode; t = force_string(tree_eval(tmp)); - /* XXX - fix this in 2.16 */ /* do the search early to avoid work on non-match */ if (research(rp, t->stptr, 0, t->stlen, 1) == -1 || ! ((RESTART(rp, t->stptr) > t->stlen) && (matches = 1))) { free_temp(t); ! return tmp_number((AWKNUM) matches); } if (tmp->type == Node_val) --- 1035,1045 ---- tmp = tree->lnode; t = force_string(tree_eval(tmp)); /* do the search early to avoid work on non-match */ if (research(rp, t->stptr, 0, t->stlen, 1) == -1 || ! RESTART(rp, t->stptr) > t->stlen) { free_temp(t); ! return tmp_number((AWKNUM) 0.0); } if (tmp->type == Node_val) *************** *** 986,992 **** repl = s->stptr; replend = repl + s->stlen; repllen = replend - repl; ! emalloc(buf, char *, buflen, "do_sub"); ampersands = 0; for (scan = repl; scan < replend; scan++) { if (*scan == '&') { --- 1068,1076 ---- repl = s->stptr; replend = repl + s->stlen; repllen = replend - repl; ! emalloc(buf, char *, buflen + 2, "do_sub"); ! buf[buflen] = '\0'; ! buf[buflen + 1] = '\0'; ampersands = 0; for (scan = repl; scan < replend; scan++) { if (*scan == '&') { *************** *** 1027,1032 **** --- 1111,1118 ---- *bp++ = *scan; } else *bp++ = *scan; + + /* catch the case of gsub(//, "blah", whatever), i.e. empty regexp */ if (global && matchstart == matchend && matchend < text + textlen) { *bp++ = *matchend; matchend++; *************** *** 1045,1050 **** --- 1131,1137 ---- } for (scan = matchend; scan < text + textlen; scan++) *bp++ = *scan; + *bp = '\0'; textlen = bp - buf; free(t->stptr); t->stptr = buf; *************** *** 1083,1089 **** * caveat: don't use as argument to *printf()! * 'format' string HAS to be of "*.*g" kind, or we bomb! */ ! void sgfmt(buf, format, alt, fwidth, prec, g) char *buf; /* return buffer; assumed big enough to hold result */ const char *format; --- 1170,1176 ---- * caveat: don't use as argument to *printf()! * 'format' string HAS to be of "*.*g" kind, or we bomb! */ ! static void sgfmt(buf, format, alt, fwidth, prec, g) char *buf; /* return buffer; assumed big enough to hold result */ const char *format; diff -crN gawk-2.15.4/config/cray60 gawk-2.15.5/config/cray60 *** gawk-2.15.4/config/cray60 Mon May 27 11:53:23 1991 --- gawk-2.15.5/config/cray60 Mon May 9 22:44:10 1994 *************** *** 3,5 **** --- 3,8 ---- RANDOM_MISSING 1 STDC_HEADERS 1 CHAR_UNSIGNED 1 + GETPGRP_NOARG 1 + MAKE_ALLOCA_C + MAKE_CC diff -crN gawk-2.15.4/config/next20 gawk-2.15.5/config/next20 *** gawk-2.15.4/config/next20 Wed Jul 8 21:19:43 1992 --- gawk-2.15.5/config/next20 Mon May 9 22:38:11 1994 *************** *** 2,7 **** --- 2,8 ---- STRTOD_MISSING 1 /* NeXT strtod() is buggy */ STDC_HEADERS 1 ALLOCA_PROTO 1 + SRANDOM_PROTO 1 SZTC (size_t) INTC (int) MAKE_NeXT diff -crN gawk-2.15.4/config/next21 gawk-2.15.5/config/next21 *** gawk-2.15.4/config/next21 Tue Nov 2 06:30:50 1993 --- gawk-2.15.5/config/next21 Fri Apr 29 06:50:24 1994 *************** *** 1,6 **** --- 1,7 ---- NeXT running 2.1 or higher STDC_HEADERS 1 ALLOCA_PROTO 1 + SRANDOM_PROTO 1 SZTC (size_t) INTC (int) MAKE_NeXT diff -crN gawk-2.15.4/config/next30 gawk-2.15.5/config/next30 *** gawk-2.15.4/config/next30 Tue Nov 2 06:30:51 1993 --- gawk-2.15.5/config/next30 Fri Apr 29 06:50:31 1994 *************** *** 1,6 **** --- 1,7 ---- NeXT running 2.1 or higher STDC_HEADERS 1 ALLOCA_PROTO 1 + SRANDOM_PROTO 1 SZTC (size_t) INTC (int) MAKE_NeXT diff -crN gawk-2.15.4/config/osf1.dec gawk-2.15.5/config/osf1.dec *** gawk-2.15.4/config/osf1.dec Wed Dec 31 19:00:00 1969 --- gawk-2.15.5/config/osf1.dec Sun May 1 18:27:30 1994 *************** *** 0 **** --- 1,4 ---- + For DEC OSF/1 2.0 + STDC_HEADERS 1 + HAVE_UNDERSCORE_SETJMP 1 + SRANDOM_PROTO 1 diff -crN gawk-2.15.4/config/sco gawk-2.15.5/config/sco *** gawk-2.15.4/config/sco Wed Dec 31 19:00:00 1969 --- gawk-2.15.5/config/sco Thu Mar 17 23:02:43 1994 *************** *** 0 **** --- 1,6 ---- + SCO UNIX + RANDOM_MISSING 1 + STRCASE_MISSING 1 + STDC_HEADERS 1 + MAKE_ALLOCA_C + HAVE_STRING_H 1 diff -crN gawk-2.15.4/config/sgi405 gawk-2.15.5/config/sgi405 *** gawk-2.15.4/config/sgi405 Mon Oct 18 08:59:31 1993 --- gawk-2.15.5/config/sgi405 Fri Apr 29 06:49:21 1994 *************** *** 2,5 **** BLKSIZE_MISSING 1 STDC_HEADERS 1 GETPGRP_NOARG 1 - MAKE_ALLOCA_C --- 2,4 ---- diff -crN gawk-2.15.4/config/utek gawk-2.15.5/config/utek *** gawk-2.15.4/config/utek Wed Dec 31 19:00:00 1969 --- gawk-2.15.5/config/utek Sun May 1 18:20:10 1994 *************** *** 0 **** --- 1,18 ---- + For a Tektronix 4300 running UTek 4.0 (BSD based.) + SIGTYPE int + MEMCMP_MISSING 1 + MEMCPY_MISSING 1 + MEMSET_MISSING 1 + STRCASE_MISSING 1 + STRERROR_MISSING 1 + STRFTIME_MISSING 1 + STRTOD_MISSING 1 + STRTOL_MISSING 1 + NON_STD_SPRINTF 1 + VPRINTF_MISSING 1 + BSDSTDIO 1 + TZNAME_MISSING 1 + TZSET_MISSING 1 + LIMITS_H_MISSING 1 + TM_ZONE_MISSING 1 + MAKE_CC diff -crN gawk-2.15.4/config.in gawk-2.15.5/config.in *** gawk-2.15.4/config.in Thu Jan 13 21:15:31 1994 --- gawk-2.15.5/config.in Sun May 1 18:20:10 1994 *************** *** 92,97 **** --- 92,104 ---- */ /* #define HAVE_UNDERSCORE_SETJMP 1 */ + /* + * LIMITS_H_MISSING + * + * You don't have a include file. + */ + /* #define LIMITS_H_MISSING 1 */ + /***********************************************/ /* Missing library subroutines or system calls */ /***********************************************/ *************** *** 175,180 **** --- 182,196 ---- * If this is the case *and* strftime() is missing, define this. */ /* #define TZNAME_MISSING 1 */ + + /* + * TM_ZONE_MISSING + * + * Your "struct tm" is missing the tm_zone field. + * If this is the case *and* strftime() is missing *and* tzname is missing, + * define this. + */ + /* #define TM_ZONE_MISSING 1 */ /* * STDC_HEADERS diff -crN gawk-2.15.4/dfa.c gawk-2.15.5/dfa.c *** gawk-2.15.4/dfa.c Tue Jan 4 16:18:20 1994 --- gawk-2.15.5/dfa.c Sun Apr 17 17:14:23 1994 *************** *** 84,89 **** --- 84,92 ---- typedef void *ptr_t; #else typedef char *ptr_t; + #ifndef const + #define const + #endif #endif static void dfamust _RE_ARGS((struct dfa *dfa)); *************** *** 981,987 **** position t1, t2; for (i = 0; i < s->nelem && p.index < s->elems[i].index; ++i) ! ; if (i < s->nelem && p.index == s->elems[i].index) s->elems[i].constraint |= p.constraint; else --- 984,990 ---- position t1, t2; for (i = 0; i < s->nelem && p.index < s->elems[i].index; ++i) ! continue; if (i < s->nelem && p.index == s->elems[i].index) s->elems[i].constraint |= p.constraint; else *************** *** 1565,1571 **** /* If there are no characters left, there's no point in going on. */ for (j = 0; j < CHARCLASS_INTS && !matches[j]; ++j) ! ; if (j == CHARCLASS_INTS) continue; } --- 1568,1574 ---- /* If there are no characters left, there's no point in going on. */ for (j = 0; j < CHARCLASS_INTS && !matches[j]; ++j) ! continue; if (j == CHARCLASS_INTS) continue; } *************** *** 1583,1589 **** matches. */ intersectf = 0; for (k = 0; k < CHARCLASS_INTS; ++k) ! (intersect[k] = matches[k] & labels[j][k]) ? intersectf = 1 : 0; if (! intersectf) continue; --- 1586,1592 ---- matches. */ intersectf = 0; for (k = 0; k < CHARCLASS_INTS; ++k) ! (intersect[k] = matches[k] & labels[j][k]) ? (intersectf = 1) : 0; if (! intersectf) continue; *************** *** 1594,1601 **** /* Even an optimizing compiler can't know this for sure. */ int match = matches[k], label = labels[j][k]; ! (leftovers[k] = ~match & label) ? leftoversf = 1 : 0; ! (matches[k] = match & ~label) ? matchesf = 1 : 0; } /* If there were leftovers, create a new group labeled with them. */ --- 1597,1604 ---- /* Even an optimizing compiler can't know this for sure. */ int match = matches[k], label = labels[j][k]; ! (leftovers[k] = ~match & label) ? (leftoversf = 1) : 0; ! (matches[k] = match & ~label) ? (matchesf = 1) : 0; } /* If there were leftovers, create a new group labeled with them. */ *************** *** 2029,2037 **** free((ptr_t) d->trans[i]); else if (d->fails[i]) free((ptr_t) d->fails[i]); ! free((ptr_t) d->realtrans); ! free((ptr_t) d->fails); ! free((ptr_t) d->newlines); for (dm = d->musts; dm; dm = ndm) { ndm = dm->next; --- 2032,2040 ---- free((ptr_t) d->trans[i]); else if (d->fails[i]) free((ptr_t) d->fails[i]); ! if (d->realtrans) free((ptr_t) d->realtrans); ! if (d->fails) free((ptr_t) d->fails); ! if (d->newlines) free((ptr_t) d->newlines); for (dm = d->musts; dm; dm = ndm) { ndm = dm->next; *************** *** 2259,2265 **** while (rcp != NULL) { for (i = 1; lcp[i] != '\0' && lcp[i] == rcp[i]; ++i) ! ; if (i > len) len = i; rcp = index(rcp + 1, *lcp); --- 2262,2268 ---- while (rcp != NULL) { for (i = 1; lcp[i] != '\0' && lcp[i] == rcp[i]; ++i) ! continue; if (i > len) len = i; rcp = index(rcp + 1, *lcp); diff -crN gawk-2.15.4/eval.c gawk-2.15.5/eval.c *** gawk-2.15.4/eval.c Sat Jan 15 22:34:40 1994 --- gawk-2.15.5/eval.c Tue May 10 21:58:13 1994 *************** *** 137,142 **** --- 137,146 ---- NODE *volatile stable_tree; int volatile traverse = 1; /* True => loop thru tree (Node_rule_list) */ + /* avoid false source indications */ + source = NULL; + sourceline = 0; + if (tree == NULL) return 1; sourceline = tree->source_line; *************** *** 381,387 **** register int di; AWKNUM x, x1, x2; long lx; ! #ifdef CRAY long lx2; #endif --- 385,391 ---- register int di; AWKNUM x, x1, x2; long lx; ! #ifdef _CRAY long lx2; #endif *************** *** 396,409 **** if ((char)tree->var_value->stref <= 0) cant_happen(); return tree->var_value; } if (tree->type == Node_param_list) { ! if (stack_ptr[tree->param_cnt] == NULL) return Nnull_string; - else - return stack_ptr[tree->param_cnt]->var_value; } ! #endif switch (tree->type) { case Node_and: return tmp_number((AWKNUM) (eval_condition(tree->lnode) && eval_condition(tree->rnode))); --- 400,417 ---- if ((char)tree->var_value->stref <= 0) cant_happen(); return tree->var_value; } + #endif + if (tree->type == Node_param_list) { ! tree = stack_ptr[tree->param_cnt]; ! if (tree == NULL) return Nnull_string; } ! switch (tree->type) { + case Node_var: + return tree->var_value; + case Node_and: return tmp_number((AWKNUM) (eval_condition(tree->lnode) && eval_condition(tree->rnode))); *************** *** 446,452 **** return *lhs; case Node_var_array: ! fatal("attempt to use an array in a scalar context"); case Node_unary_minus: t1 = tree_eval(tree->subnode); --- 454,460 ---- return *lhs; case Node_var_array: ! fatal("attempt to use array `%s' in a scalar context", tree->vname); case Node_unary_minus: t1 = tree_eval(tree->subnode); *************** *** 530,535 **** --- 538,544 ---- } *strp = NULL; emalloc(str, char *, len+2, "tree_eval"); + str[len] = str[len+1] = '\0'; /* for good measure */ dest = str; strp = strlist; while (*strp) { *************** *** 651,657 **** return tmp_number(x1 - x2); case Node_var_array: ! fatal("attempt to use an array in a scalar context"); default: fatal("illegal type (%d) in tree_eval", tree->type); --- 660,666 ---- return tmp_number(x1 - x2); case Node_var_array: ! fatal("attempt to use array `%s' in a scalar context", tree->vname); default: fatal("illegal type (%d) in tree_eval", tree->type); *************** *** 966,977 **** if (arg->type == Node_param_list) arg = stack_ptr[arg->param_cnt]; n = *sp++; ! if (arg->type == Node_var && n->type == Node_var_array) { /* should we free arg->var_value ? */ arg->var_array = n->var_array; arg->type = Node_var_array; arg->array_size = n->array_size; arg->table_size = n->table_size; } /* n->lnode overlays the array size, don't unref it if array */ if (n->type != Node_var_array) --- 975,988 ---- if (arg->type == Node_param_list) arg = stack_ptr[arg->param_cnt]; n = *sp++; ! if ((arg->type == Node_var || arg->type == Node_var_array) ! && n->type == Node_var_array) { /* should we free arg->var_value ? */ arg->var_array = n->var_array; arg->type = Node_var_array; arg->array_size = n->array_size; arg->table_size = n->table_size; + arg->flags = n->flags; } /* n->lnode overlays the array size, don't unref it if array */ if (n->type != Node_var_array) *************** *** 1018,1024 **** switch (ptr->type) { case Node_var_array: ! fatal("attempt to use an array in a scalar context"); case Node_var: aptr = &(ptr->var_value); #ifdef DEBUG --- 1029,1035 ---- switch (ptr->type) { case Node_var_array: ! fatal("attempt to use array `%s' in a scalar context", ptr->vname); case Node_var: aptr = &(ptr->var_value); #ifdef DEBUG *************** *** 1194,1200 **** ORS[ORSlen] = '\0'; } ! static NODE **fmt_list = NULL; static int fmt_ok P((NODE *n)); static int fmt_index P((NODE *n)); --- 1205,1211 ---- ORS[ORSlen] = '\0'; } ! NODE **fmt_list = NULL; static int fmt_ok P((NODE *n)); static int fmt_index P((NODE *n)); diff -crN gawk-2.15.4/field.c gawk-2.15.5/field.c *** gawk-2.15.4/field.c Wed Dec 29 10:32:45 1993 --- gawk-2.15.5/field.c Wed May 18 07:26:41 1994 *************** *** 27,52 **** typedef void (* Setfunc) P((int, char*, int, NODE *)); ! static int (*parse_field) P((int, char **, int, NODE *, Regexp *, Setfunc, NODE *)); static void rebuild_record P((void)); ! static int re_parse_field P((int, char **, int, NODE *, Regexp *, Setfunc, NODE *)); ! static int def_parse_field P((int, char **, int, NODE *, Regexp *, Setfunc, NODE *)); ! static int sc_parse_field P((int, char **, int, NODE *, Regexp *, Setfunc, NODE *)); ! static int fw_parse_field P((int, char **, int, NODE *, Regexp *, Setfunc, NODE *)); static void set_element P((int, char *, int, NODE *)); ! static void grow_fields_arr P((int num)); static void set_field P((int num, char *str, int len, NODE *dummy)); static Regexp *FS_regexp = NULL; static char *parse_extent; /* marks where to restart parse of record */ ! static int parse_high_water=0; /* field number that we have parsed so far */ ! static int nf_high_water = 0; /* size of fields_arr */ static int resave_fs; static NODE *save_FS; /* save current value of FS when line is read, * to be used in deferred parsing --- 27,52 ---- typedef void (* Setfunc) P((int, char*, int, NODE *)); ! static long (*parse_field) P((int, char **, int, NODE *, Regexp *, Setfunc, NODE *)); static void rebuild_record P((void)); ! static long re_parse_field P((int, char **, int, NODE *, Regexp *, Setfunc, NODE *)); ! static long def_parse_field P((int, char **, int, NODE *, Regexp *, Setfunc, NODE *)); ! static long sc_parse_field P((int, char **, int, NODE *, Regexp *, Setfunc, NODE *)); ! static long fw_parse_field P((int, char **, int, NODE *, Regexp *, Setfunc, NODE *)); static void set_element P((int, char *, int, NODE *)); ! static void grow_fields_arr P((long num)); static void set_field P((int num, char *str, int len, NODE *dummy)); static Regexp *FS_regexp = NULL; static char *parse_extent; /* marks where to restart parse of record */ ! static long parse_high_water=0; /* field number that we have parsed so far */ ! static long nf_high_water = 0; /* size of fields_arr */ static int resave_fs; static NODE *save_FS; /* save current value of FS when line is read, * to be used in deferred parsing *************** *** 76,82 **** static void grow_fields_arr(num) ! int num; { register int t; register NODE *n; --- 76,82 ---- static void grow_fields_arr(num) ! long num; { register int t; register NODE *n; *************** *** 134,140 **** tlen += (NF - 1) * ofslen; if ((long)tlen < 0) tlen = 0; ! emalloc(ops, char *, tlen + 2, "fix_fields"); cops = ops; ops[0] = '\0'; for (ptr = &fields_arr[1]; ptr <= &fields_arr[NF]; ptr++) { --- 134,140 ---- tlen += (NF - 1) * ofslen; if ((long)tlen < 0) tlen = 0; ! emalloc(ops, char *, tlen + 2, "rebuild_record"); cops = ops; ops[0] = '\0'; for (ptr = &fields_arr[1]; ptr <= &fields_arr[NF]; ptr++) { *************** *** 206,212 **** { register int i; ! NF = (int) force_number(NF_node->var_value); if (NF > nf_high_water) grow_fields_arr(NF); for (i = parse_high_water + 1; i <= NF; i++) { --- 206,212 ---- { register int i; ! NF = (long) force_number(NF_node->var_value); if (NF > nf_high_water) grow_fields_arr(NF); for (i = parse_high_water + 1; i <= NF; i++) { *************** *** 221,227 **** * via (*parse_field)(). This variation is for when FS is a regular * expression -- either user-defined or because RS=="" and FS==" " */ ! static int re_parse_field(up_to, buf, len, fs, rp, set, n) int up_to; /* parse only up to this field number */ char **buf; /* on input: string to parse; on output: point to start next */ --- 221,227 ---- * via (*parse_field)(). This variation is for when FS is a regular * expression -- either user-defined or because RS=="" and FS==" " */ ! static long re_parse_field(up_to, buf, len, fs, rp, set, n) int up_to; /* parse only up to this field number */ char **buf; /* on input: string to parse; on output: point to start next */ *************** *** 242,248 **** return nf; if (*RS == 0 && default_FS) ! while (scan < end && isspace(*scan)) scan++; field = scan; while (scan < end --- 242,248 ---- return nf; if (*RS == 0 && default_FS) ! while (scan < end && (*scan == ' ' || *scan == '\t' || *scan == '\n')) scan++; field = scan; while (scan < end *************** *** 277,283 **** * via (*parse_field)(). This variation is for when FS is a single space * character. */ ! static int def_parse_field(up_to, buf, len, fs, rp, set, n) int up_to; /* parse only up to this field number */ char **buf; /* on input: string to parse; on output: point to start next */ --- 277,283 ---- * via (*parse_field)(). This variation is for when FS is a single space * character. */ ! static long def_parse_field(up_to, buf, len, fs, rp, set, n) int up_to; /* parse only up to this field number */ char **buf; /* on input: string to parse; on output: point to start next */ *************** *** 331,337 **** * via (*parse_field)(). This variation is for when FS is a single character * other than space. */ ! static int sc_parse_field(up_to, buf, len, fs, rp, set, n) int up_to; /* parse only up to this field number */ char **buf; /* on input: string to parse; on output: point to start next */ --- 331,337 ---- * via (*parse_field)(). This variation is for when FS is a single character * other than space. */ ! static long sc_parse_field(up_to, buf, len, fs, rp, set, n) int up_to; /* parse only up to this field number */ char **buf; /* on input: string to parse; on output: point to start next */ *************** *** 363,376 **** /* because it will be destroyed now: */ *end = fschar; /* sentinel character */ ! for (; nf < up_to; scan++) { field = scan; ! while (*scan++ != fschar) ! ; ! scan--; (*set)(++nf, field, (int)(scan - field), n); if (scan == end) break; } /* everything done, restore original char at *end */ --- 363,380 ---- /* because it will be destroyed now: */ *end = fschar; /* sentinel character */ ! for (; nf < up_to;) { field = scan; ! while (*scan != fschar) ! scan++; (*set)(++nf, field, (int)(scan - field), n); if (scan == end) break; + scan++; + if (scan == end) { /* FS at end of record */ + (*set)(++nf, field, 0, n); + break; + } } /* everything done, restore original char at *end */ *************** *** 384,390 **** * this is called both from get_field() and from do_split() * via (*parse_field)(). This variation is for fields are fixed widths. */ ! static int fw_parse_field(up_to, buf, len, fs, rp, set, n) int up_to; /* parse only up to this field number */ char **buf; /* on input: string to parse; on output: point to start next */ --- 388,394 ---- * this is called both from get_field() and from do_split() * via (*parse_field)(). This variation is for fields are fixed widths. */ ! static long fw_parse_field(up_to, buf, len, fs, rp, set, n) int up_to; /* parse only up to this field number */ char **buf; /* on input: string to parse; on output: point to start next */ *************** *** 395,401 **** NODE *n; { register char *scan = *buf; ! register int nf = parse_high_water; register char *end = scan + len; if (up_to == HUGE) --- 399,405 ---- NODE *n; { register char *scan = *buf; ! register long nf = parse_high_water; register char *end = scan + len; if (up_to == HUGE) *************** *** 515,525 **** NODE *t1, *t2, *t3, *tmp; NODE *fs; char *s; ! int (*parseit)P((int, char **, int, NODE *, Regexp *, Setfunc, NODE *)); Regexp *rp = NULL; ! t1 = tree_eval(tree->lnode); t2 = tree->rnode->lnode; t3 = tree->rnode->rnode->lnode; --- 519,539 ---- NODE *t1, *t2, *t3, *tmp; NODE *fs; char *s; ! long (*parseit)P((int, char **, int, NODE *, Regexp *, Setfunc, NODE *)); Regexp *rp = NULL; ! ! /* ! * do dupnode(), to avoid problems like ! * x = split(a[1], a, "blah") ! * since we assoc_clear the array. gack. ! * this also gives up complete call by value semantics. ! */ ! tmp = tree_eval(tree->lnode); ! t1 = dupnode(tmp); ! free_temp(tmp); ! t2 = tree->rnode->lnode; t3 = tree->rnode->rnode->lnode; *************** *** 552,558 **** s = t1->stptr; tmp = tmp_number((AWKNUM) (*parseit)(HUGE, &s, (int)t1->stlen, fs, rp, set_element, t2)); ! free_temp(t1); free_temp(t3); return tmp; } --- 566,572 ---- s = t1->stptr; tmp = tmp_number((AWKNUM) (*parseit)(HUGE, &s, (int)t1->stlen, fs, rp, set_element, t2)); ! unref(t1); free_temp(t3); return tmp; } *************** *** 563,568 **** --- 577,589 ---- char buf[10]; NODE *fs; + /* + * If changing the way fields are split, obey least-suprise + * semantics, and force $0 to be split totally. + */ + if (fields_arr != NULL) + (void) get_field(HUGE - 1, 0); + buf[0] = '\0'; default_FS = 0; if (FS_regexp) { *************** *** 588,593 **** --- 609,617 ---- else if (fs->stptr[0] != ' ' && fs->stlen == 1) { if (IGNORECASE == 0) parse_field = sc_parse_field; + else if (fs->stptr[0] == '\\') + /* yet another special case */ + strcpy(buf, "[\\\\]"); else sprintf(buf, "[%c]", fs->stptr[0]); } *************** *** 626,631 **** --- 650,662 ---- } if (do_unix) /* quick and dirty, does the trick */ return; + + /* + * If changing the way fields are split, obey least-suprise + * semantics, and force $0 to be split totally. + */ + if (fields_arr != NULL) + (void) get_field(HUGE - 1, 0); parse_field = fw_parse_field; scan = force_string(FIELDWIDTHS_node->var_value)->stptr; diff -crN gawk-2.15.4/gawk.1 gawk-2.15.5/gawk.1 *** gawk-2.15.4/gawk.1 Sun Dec 26 13:32:06 1993 --- gawk-2.15.5/gawk.1 Mon Apr 18 18:04:03 1994 *************** *** 1,7 **** .ds PX \s-1POSIX\s+1 .ds UX \s-1UNIX\s+1 .ds AN \s-1ANSI\s+1 ! .TH GAWK 1 "Dec 24 1993" "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 "Apr 18 1994" "Free Software Foundation" "Utility Commands" .SH NAME gawk \- pattern scanning and processing language .SH SYNOPSIS *************** *** 290,296 **** options are passed on to the AWK program in the .B ARGV array for processing. This is particularly useful for running AWK ! programs via the ``#!'' executable interpreter mechansim. .SH AWK PROGRAM EXECUTION .PP An AWK program consists of a sequence of pattern-action statements --- 290,296 ---- options are passed on to the AWK program in the .B ARGV array for processing. This is particularly useful for running AWK ! programs via the ``#!'' executable interpreter mechanism. .SH AWK PROGRAM EXECUTION .PP An AWK program consists of a sequence of pattern-action statements *************** *** 1671,1677 **** When .I awk was changed to match its documentation, this option was added to ! accomodate applications that depended upon the old behavior. (This feature was agreed upon by both the AT&T and GNU developers.) .PP The --- 1671,1677 ---- When .I awk was changed to match its documentation, this option was added to ! accommodate applications that depended upon the old behavior. (This feature was agreed upon by both the AT&T and GNU developers.) .PP The *************** *** 1883,1888 **** --- 1883,1901 ---- will support this usage if .B "\-W posix" has not been specified. + .SH ENVIRONMENT VARIABLES + If + .B POSIXLY_CORRECT + exists in the environment, then + .I gawk + behaves exactly as if + .B \-\-posix + had been specified on the command line. + If + .B \-\-lint + has been specified, + .I gawk + will issue a warning message to this effect. .SH BUGS The .B \-F diff -crN gawk-2.15.4/getopt.c gawk-2.15.5/getopt.c *** gawk-2.15.4/getopt.c Tue Nov 2 06:39:47 1993 --- gawk-2.15.5/getopt.c Sun May 15 11:23:53 1994 *************** *** 3,9 **** "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu before changing it! ! Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it --- 3,9 ---- "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu before changing it! ! Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 1994 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it *************** *** 59,69 **** /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ ! #if defined(__GNU_LIBRARY__) || defined(OS2) || defined(MSDOS) || defined(atarist) /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ #include ! #endif /* GNU C library. */ /* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a long-named option. Because this is not POSIX.2 compliant, it is --- 59,71 ---- /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ ! #if defined(__GNU_LIBRARY__) || defined(STDC_HEADERS) /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ #include ! #else ! extern char *getenv (); ! #endif /* __GNU_LIBRARY || STDC_HEADERS */ /* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a long-named option. Because this is not POSIX.2 compliant, it is *************** *** 163,169 **** REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; ! #if defined(__GNU_LIBRARY__) || defined(OS2) || defined(MSDOS) || defined(atarist) /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work --- 165,171 ---- REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; ! #if defined(__GNU_LIBRARY__) || defined(STDC_HEADERS) /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work *************** *** 175,182 **** /* Avoid depending on library functions or files whose names are inconsistent. */ - char *getenv (); - static char * my_index (str, chr) const char *str; --- 177,182 ---- *************** *** 204,210 **** extern size_t strlen (const char *); #endif ! #endif /* GNU C library. */ /* Handle permutation of arguments. */ --- 204,210 ---- extern size_t strlen (const char *); #endif ! #endif /* __GNU_LIBRARY__ || STDC_HEADERS */ /* Handle permutation of arguments. */ diff -crN gawk-2.15.4/io.c gawk-2.15.5/io.c *** gawk-2.15.4/io.c Thu Jan 13 21:15:32 1994 --- gawk-2.15.5/io.c Wed May 11 22:50:41 1994 *************** *** 36,41 **** --- 36,45 ---- #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) #endif + #ifndef ENFILE + #define ENFILE EMFILE + #endif + #ifndef atarist #define INVALID_HANDLE (-1) #else *************** *** 51,57 **** static int iop_close P((IOBUF *iop)); struct redirect *redirect P((NODE *tree, int *errflg)); static void close_one P((void)); ! static int close_redir P((struct redirect *rp)); #ifndef PIPES_SIMULATED static int wait_any P((int interesting)); #endif --- 55,61 ---- static int iop_close P((IOBUF *iop)); struct redirect *redirect P((NODE *tree, int *errflg)); static void close_one P((void)); ! static int close_redir P((struct redirect *rp, int exitwarn)); #ifndef PIPES_SIMULATED static int wait_any P((int interesting)); #endif *************** *** 159,171 **** void set_FNR() { ! FNR = (int) FNR_node->var_value->numbr; } void set_NR() { ! NR = (int) NR_node->var_value->numbr; } /* --- 163,175 ---- void set_FNR() { ! FNR = (long) FNR_node->var_value->numbr; } void set_NR() { ! NR = (long) NR_node->var_value->numbr; } /* *************** *** 256,267 **** IOBUF *iop; extern int exiting; ! if (setjmp(filebuf) != 0) { ! } while ((iop = nextfile(0)) != NULL) { if (inrec(iop) == 0) while (interpret(expression_value) && inrec(iop) == 0) ! ; /* recover any space from C based alloca */ (void) alloca(0); --- 260,271 ---- IOBUF *iop; extern int exiting; ! (void) setjmp(filebuf); ! while ((iop = nextfile(0)) != NULL) { if (inrec(iop) == 0) while (interpret(expression_value) && inrec(iop) == 0) ! continue; /* recover any space from C based alloca */ (void) alloca(0); *************** *** 409,415 **** } if (rp->fp == NULL && rp->iop == NULL) { /* too many files open -- close one and try again */ ! if (errno == EMFILE) close_one(); else { /* --- 413,419 ---- } if (rp->fp == NULL && rp->iop == NULL) { /* too many files open -- close one and try again */ ! if (errno == EMFILE || errno == ENFILE) close_one(); else { /* *************** *** 479,494 **** if (rp == NULL) /* no match */ return tmp_number((AWKNUM) 0.0); fflush(stdout); /* synchronize regular output */ ! tmp = tmp_number((AWKNUM)close_redir(rp)); rp = NULL; return tmp; } static int ! close_redir(rp) register struct redirect *rp; { int status = 0; if (rp == NULL) return 0; --- 483,500 ---- if (rp == NULL) /* no match */ return tmp_number((AWKNUM) 0.0); fflush(stdout); /* synchronize regular output */ ! tmp = tmp_number((AWKNUM)close_redir(rp, 0)); rp = NULL; return tmp; } static int ! close_redir(rp, exitwarn) register struct redirect *rp; + int exitwarn; { int status = 0; + char *what; if (rp == NULL) return 0; *************** *** 507,520 **** rp->iop = NULL; } } /* SVR4 awk checks and warns about status of close */ if (status) { char *s = strerror(errno); ! warning("failure status (%d) on %s close of \"%s\" (%s).", ! status, ! (rp->flag & RED_PIPE) ? "pipe" : ! "file", rp->value, s); if (! do_unix) { /* set ERRNO too so that program can get at it */ --- 513,531 ---- rp->iop = NULL; } } + + what = (rp->flag & RED_PIPE) ? "pipe" : "file"; + + if (exitwarn) + warning("no explicit close of %s \"%s\" provided", + what, rp->value); + /* SVR4 awk checks and warns about status of close */ 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 */ *************** *** 572,578 **** for (rp = red_head; rp != NULL; rp = next) { next = rp->next; /* close_redir() will print a message if needed */ ! if (close_redir(rp)) status++; rp = NULL; } --- 583,590 ---- for (rp = red_head; rp != NULL; rp = next) { next = rp->next; /* close_redir() will print a message if needed */ ! /* if do_lint, warn about lack of explicit close */ ! if (close_redir(rp, do_lint)) status++; rp = NULL; } *************** *** 794,800 **** char tbuf[BUFSIZ], *cp; int i; #if defined(NGROUPS_MAX) && NGROUPS_MAX > 0 ! #if defined(atarist) || defined(__svr4__) gid_t groupset[NGROUPS_MAX]; #else int groupset[NGROUPS_MAX]; --- 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]; diff -crN gawk-2.15.4/iop.c gawk-2.15.5/iop.c *** gawk-2.15.4/iop.c Tue Jan 4 16:18:21 1994 --- gawk-2.15.5/iop.c Sat May 14 23:59:58 1994 *************** *** 149,156 **** char rs; int saw_newline = 0, eat_whitespace = 0; /* used iff grRS==0 */ ! if (iop->cnt == EOF) /* previous read hit EOF */ return EOF; if (grRS == 0) { /* special case: grRS == "" */ rs = '\n'; --- 149,158 ---- char rs; int saw_newline = 0, eat_whitespace = 0; /* used iff grRS==0 */ ! if (iop->cnt == EOF) { /* previous read hit EOF */ ! *out = NULL; return EOF; + } if (grRS == 0) { /* special case: grRS == "" */ rs = '\n'; *************** *** 178,186 **** char *oldsplit = iop->buf + iop->secsiz; long len; /* record length so far */ - if ((iop->flag & IOP_IS_INTERNAL) != 0) - cant_happen(); - len = bp - start; if (len > iop->secsiz) { /* expand secondary buffer */ --- 180,185 ---- *************** *** 242,248 **** extern int default_FS; if (default_FS && (bp == start || eat_whitespace)) { ! while (bp < iop->end && isspace(*bp)) bp++; if (bp == iop->end) { eat_whitespace = 1; --- 241,248 ---- extern int default_FS; if (default_FS && (bp == start || eat_whitespace)) { ! while (bp < iop->end ! && (*bp == ' ' || *bp == '\t' || *bp == '\n')) bp++; if (bp == iop->end) { eat_whitespace = 1; *************** *** 272,279 **** iop->cnt = bp - start; } if (iop->cnt == EOF ! && (((iop->flag & IOP_IS_INTERNAL) != 0) || start == bp)) return EOF; iop->off = bp; bp--; --- 272,281 ---- iop->cnt = bp - start; } if (iop->cnt == EOF ! && (((iop->flag & IOP_IS_INTERNAL) != 0) || start == bp)) { ! *out = NULL; return EOF; + } iop->off = bp; bp--; *************** *** 281,286 **** --- 283,292 ---- bp++; *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) *bp = '\0'; else diff -crN gawk-2.15.4/main.c gawk-2.15.5/main.c *** gawk-2.15.4/main.c Tue Jan 4 17:10:36 1994 --- gawk-2.15.5/main.c Sun May 1 18:38:49 1994 *************** *** 55,63 **** NODE *ARGC_node, *ARGV_node, *ARGIND_node; NODE *FIELDWIDTHS_node; ! int NF; ! int NR; ! int FNR; int IGNORECASE; char *RS; char *OFS; --- 55,63 ---- NODE *ARGC_node, *ARGV_node, *ARGIND_node; NODE *FIELDWIDTHS_node; ! long NF; ! long NR; ! long FNR; int IGNORECASE; char *RS; char *OFS; *************** *** 134,144 **** { int c; char *scan; extern int optind; extern int opterr; extern char *optarg; - const char *optlist = "+F:f:v:W:m:"; - int stopped_early = 0; #ifdef __EMX__ _response(&argc, &argv); --- 134,146 ---- { int c; char *scan; + /* the + on the front tells GNU getopt not to rearrange argv */ + const char *optlist = "+F:f:v:W:m:"; + int stopped_early = 0; + int old_optind; extern int optind; extern int opterr; extern char *optarg; #ifdef __EMX__ _response(&argc, &argv); *************** *** 188,197 **** /* we do error messages ourselves on invalid options */ opterr = 0; ! /* the + on the front tells GNU getopt not to rearrange argv */ ! for (optopt = 0; (c = getopt_long(argc, argv, optlist, optab, NULL)) != EOF; ! optopt = 0) { if (do_posix) opterr = 1; switch (c) { --- 190,199 ---- /* we do error messages ourselves on invalid options */ opterr = 0; ! /* option processing. ready, set, go! */ ! for (optopt = 0, old_optind = 1; (c = getopt_long(argc, argv, optlist, optab, NULL)) != EOF; ! optopt = 0, old_optind = optind) { if (do_posix) opterr = 1; switch (c) { *************** *** 254,260 **** break; case 's': ! if (strlen(optarg) == 0) warning("empty argument to --source ignored"); else { srcfiles[++numfiles].stype = CMDLINE; --- 256,262 ---- break; case 's': ! if (optarg[0] == '\0') warning("empty argument to --source ignored"); else { srcfiles[++numfiles].stype = CMDLINE; *************** *** 291,297 **** */ if (! do_posix && (optopt == 0 || strchr(optlist, optopt) == NULL)) { ! optind--; stopped_early = 1; goto out; } else if (optopt) --- 293,304 ---- */ if (! do_posix && (optopt == 0 || strchr(optlist, optopt) == NULL)) { ! /* ! * can't just do optind--. In case of an ! * option with >=2 letters, getopt_long ! * won't have incremented optind. ! */ ! optind = old_optind; stopped_early = 1; goto out; } else if (optopt) *************** *** 309,314 **** --- 316,329 ---- if (do_nostalgia) nostalgia(); + /* check for POSIXLY_CORRECT environment variable */ + if (! do_posix && getenv("POSIXLY_CORRECT") != NULL) { + do_posix = 1; + if (do_lint) + warning( + "environment variable `POSIXLY_CORRECT' set: turning on --posix"); + } + /* POSIX compliance also implies no Unix extensions either */ if (do_posix) do_unix = 1; *************** *** 336,341 **** --- 351,360 ---- /* Set up the field variables */ init_fields(); + if (do_lint && begin_block == NULL && expression_value == NULL + && end_block == NULL) + warning("no program"); + if (begin_block) { in_begin_rule = 1; (void) interpret(begin_block); *************** *** 718,724 **** if (strncasecmp(cp, "source=", 7) != 0) goto unknown; cp += 7; ! if (strlen(cp) == 0) warning("empty argument to -Wsource ignored"); else { srcfiles[++numfiles].stype = CMDLINE; --- 737,743 ---- if (strncasecmp(cp, "source=", 7) != 0) goto unknown; cp += 7; ! if (cp[0] == '\0') warning("empty argument to -Wsource ignored"); else { srcfiles[++numfiles].stype = CMDLINE; diff -crN gawk-2.15.4/missing/strftime.3 gawk-2.15.5/missing/strftime.3 *** gawk-2.15.4/missing/strftime.3 Tue May 4 20:13:29 1993 --- gawk-2.15.5/missing/strftime.3 Sun May 1 18:09:49 1994 *************** *** 220,226 **** .RB ( 01 - 53 ). The method for determining the week number is as specified by ISO 8601 (to wit: if the week containing January 1 has four or more days in the ! new year, then it is week 1, otherwise it is week 53 of the previous year and the next week is week 1). .LP The text of the POSIX standard for the --- 220,227 ---- .RB ( 01 - 53 ). The method for determining the week number is as specified by ISO 8601 (to wit: if the week containing January 1 has four or more days in the ! new year, then it is week 1, otherwise it is the highest numbered ! week of the previous year (52 or 53) and the next week is week 1). .LP The text of the POSIX standard for the *************** *** 242,253 **** is replaced by the week number of the year (the first Monday as the first day of week 1) as a decimal number .RB ( 00 - 53 ). ! All days in a new year preceding the first Sunday are considered to be in week 0. - (Note: this last statement is quoted verbatim from the POSIX standard. - It probably means to say ``all days in a new year preceding the first - .I Monday - are considered to be in week 0.'') .LP In addition, the alternate representations .BR %Ec , --- 243,250 ---- is replaced by the week number of the year (the first Monday as the first day of week 1) as a decimal number .RB ( 00 - 53 ). ! All days in a new year preceding the first Monday are considered to be in week 0. .LP In addition, the alternate representations .BR %Ec , *************** *** 315,317 **** --- 312,316 ---- versions of this routine, and for advice about POSIX semantics. Additional thanks to Arthur David Olsen for some code improvements. + Thanks also to Tor Lillqvist + for code fixes to the ISO 8601 code. diff -crN gawk-2.15.4/missing/strftime.c gawk-2.15.5/missing/strftime.c *** gawk-2.15.4/missing/strftime.c Tue Jan 4 16:18:24 1994 --- gawk-2.15.5/missing/strftime.c Thu May 19 00:33:41 1994 *************** *** 1,8 **** /* * strftime.c * ! * Public-domain relatively quick-and-dirty implementation of ! * ANSI library routine for System V Unix systems. * * It's written in old-style C for maximal portability. * However, since I'm used to prototypes, I've included them too. --- 1,7 ---- /* * strftime.c * ! * Public-domain implementation of ANSI C library routine. * * It's written in old-style C for maximal portability. * However, since I'm used to prototypes, I've included them too. *************** *** 10,15 **** --- 9,15 ---- * If you want stuff in the System V ascftime routine, add the SYSV_EXT define. * For extensions from SunOS, add SUNOS_EXT. * For stuff needed to implement the P1003.2 date command, add POSIX2_DATE. + * For VMS dates, add VMS_EXT. * For complete POSIX semantics, add POSIX_SEMANTICS. * * The code for %c, %x, and %X is my best guess as to what's "appropriate". *************** *** 24,42 **** * January, February, March, 1991 * Updated March, April 1992 * Updated April, 1993 * * Fixes from ado@elsie.nci.nih.gov * February 1991, May 1992 ! * Fixes from Tor Lillqvist tor@tik.vtt.fi * May, 1993 */ #ifndef GAWK #include #include #include #include #include #endif /* defaults: season to taste */ --- 24,58 ---- * January, February, March, 1991 * Updated March, April 1992 * Updated April, 1993 + * Updated February, 1994 + * Updated May, 1994 * * Fixes from ado@elsie.nci.nih.gov * February 1991, May 1992 ! * Fixes from Tor Lillqvist tml@tik.vtt.fi * May, 1993 + * Further fixes from ado@elsie.nci.nih.gov + * February 1994 */ + /************ for gawk 2.15.5 ***************/ + #ifndef TZNAME_MISSING + #define HAVE_TZNAME + #endif + #ifndef TM_ZONE_MISSING + #define HAVE_TM_ZONE + #endif + /*********** end of for gawk 2.15.5 *********/ + #ifndef GAWK #include #include #include #include + #endif + #if defined(TM_IN_SYS_TIME) || ! defined(GAWK) #include + #include #endif /* defaults: season to taste */ *************** *** 92,98 **** #define range(low, item, hi) max(low, min(item, hi)) ! #if !defined(OS2) && !defined(MSDOS) && !defined(TZNAME_MISSING) extern char *tzname[2]; extern int daylight; #endif --- 108,114 ---- #define range(low, item, hi) max(low, min(item, hi)) ! #if !defined(OS2) && !defined(MSDOS) && defined(HAVE_TZNAME) extern char *tzname[2]; extern int daylight; #endif *************** *** 141,147 **** { char *endp = s + maxsize; char *start = s; ! char tbuf[100]; int i; static short first = 1; #ifdef POSIX_SEMANTICS --- 157,163 ---- { char *endp = s + maxsize; char *start = s; ! auto char tbuf[100]; int i; static short first = 1; #ifdef POSIX_SEMANTICS *************** *** 149,154 **** --- 165,175 ---- static int savetzlen = 0; char *tz; #endif /* POSIX_SEMANTICS */ + #ifndef HAVE_TM_ZONE + extern char *timezone(); + struct timeval tv; + struct timezone zone; + #endif /* HAVE_TM_ZONE */ /* various tables, useful in North America */ static const char *days_a[] = { *************** *** 173,178 **** --- 194,200 ---- if (s == NULL || format == NULL || timeptr == NULL || maxsize == 0) return 0; + /* quick check if we even need to bother */ if (strchr(format, '%') == NULL && strlen(format) + 1 >= maxsize) return 0; *************** *** 316,322 **** break; case 'U': /* week of year, Sunday is first day of week */ ! sprintf(tbuf, "%d", weeknumber(timeptr, 0)); break; case 'w': /* weekday, Sunday == 0, 0 - 6 */ --- 338,344 ---- break; case 'U': /* week of year, Sunday is first day of week */ ! sprintf(tbuf, "%02d", weeknumber(timeptr, 0)); break; case 'w': /* weekday, Sunday == 0, 0 - 6 */ *************** *** 325,331 **** break; case 'W': /* week of year, Monday is first day of week */ ! sprintf(tbuf, "%d", weeknumber(timeptr, 1)); break; case 'x': /* appropriate date representation */ --- 347,353 ---- break; case 'W': /* week of year, Monday is first day of week */ ! sprintf(tbuf, "%02d", weeknumber(timeptr, 1)); break; case 'x': /* appropriate date representation */ *************** *** 345,351 **** case 'y': /* year without a century, 00 - 99 */ i = timeptr->tm_year % 100; ! sprintf(tbuf, "%d", i); break; case 'Y': /* year with century */ --- 367,373 ---- case 'y': /* year without a century, 00 - 99 */ i = timeptr->tm_year % 100; ! sprintf(tbuf, "%02d", i); break; case 'Y': /* year with century */ *************** *** 353,369 **** break; case 'Z': /* time zone name or abbrevation */ ! i = 0; ! if ( ! #ifndef TZNAME_MISSING ! daylight && ! #endif ! timeptr->tm_isdst) ! i = 1; ! #ifdef TZNAME_MISSING strcpy(tbuf, timeptr->tm_zone); #else ! strcpy(tbuf, tzname[i]); #endif break; --- 375,391 ---- break; case 'Z': /* time zone name or abbrevation */ ! #ifdef HAVE_TZNAME ! i = (daylight && timeptr->tm_isdst); /* 0 or 1 */ ! strcpy(tbuf, tzname[i]); ! #else ! #ifdef HAVE_TM_ZONE strcpy(tbuf, timeptr->tm_zone); #else ! gettimeofday(& tv, & zone); ! strcpy(tbuf, timezone(zone.tz_minuteswest, ! timeptr->tm_isdst)); ! #endif #endif break; *************** *** 417,423 **** #ifdef VMS_EXT case 'v': /* date as dd-bbb-YYYY */ ! sprintf(tbuf, "%2d-%3.3s-%4d", range(1, timeptr->tm_mday, 31), months_a[range(0, timeptr->tm_mon, 11)], timeptr->tm_year + 1900); --- 439,445 ---- #ifdef VMS_EXT case 'v': /* date as dd-bbb-YYYY */ ! sprintf(tbuf, "%02d-%3.3s-%4d", range(1, timeptr->tm_mday, 31), months_a[range(0, timeptr->tm_mon, 11)], timeptr->tm_year + 1900); *************** *** 449,459 **** if (! warned && do_lint) { warned = 1; warning( ! "conversion %%V added in P1003.2/11.3; for VMS style date, use %%v"); } } #endif ! sprintf(tbuf, "%d", iso8601wknum(timeptr)); break; case 'u': --- 471,481 ---- if (! warned && do_lint) { warned = 1; warning( ! "conversion %%V added in P1003.2; for VMS style date, use %%v"); } } #endif ! sprintf(tbuf, "%02d", iso8601wknum(timeptr)); break; case 'u': *************** *** 469,480 **** break; } i = strlen(tbuf); ! if (i) if (s + i < endp - 1) { strcpy(s, tbuf); s += i; } else return 0; } out: if (s < endp && *format == '\0') { --- 491,503 ---- break; } i = strlen(tbuf); ! if (i) { if (s + i < endp - 1) { strcpy(s, tbuf); s += i; } else return 0; + } } out: if (s < endp && *format == '\0') { *************** *** 484,489 **** --- 507,527 ---- return 0; } + /* isleap --- is a year a leap year? */ + + #ifndef __STDC__ + static int + isleap(year) + int year; + #else + static int + isleap(int year) + #endif + { + return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0); + } + + #ifdef POSIX2_DATE /* iso8601wknum --- compute week number according to ISO 8601 */ *************** *** 497,516 **** #endif { /* ! * From 1003.2 D11.3: * If the week (Monday to Sunday) containing January 1 * has four or more days in the new year, then it is week 1; ! * otherwise it is week 53 of the previous year, and the ! * next week is week 1. * * ADR: This means if Jan 1 was Monday through Thursday, ! * it was week 1, otherwise week 53. */ ! int simple_wknum, jan1day, diff, ret; /* get week number, Monday as first day of the week */ ! simple_wknum = weeknumber(timeptr, 1) + 1; /* * With thanks and tip of the hatlo to tml@tik.vtt.fi --- 535,557 ---- #endif { /* ! * From 1003.2: * If the week (Monday to Sunday) containing January 1 * has four or more days in the new year, then it is week 1; ! * otherwise it is the highest numbered week of the previous ! * (52 or 53) year, and the next week is week 1. * * ADR: This means if Jan 1 was Monday through Thursday, ! * it was week 1, otherwise week 52 or 53. ! * ! * XPG4 erroneously included POSIX.2 rationale text in the ! * main body of the standard. Thus it requires week 53. */ ! int weeknum, jan1day, diff; /* get week number, Monday as first day of the week */ ! weeknum = weeknumber(timeptr, 1); /* * With thanks and tip of the hatlo to tml@tik.vtt.fi *************** *** 531,547 **** /* * If Jan 1 was a Monday through Thursday, it was in ! * week 1. Otherwise it was last year's week 53, which is * this year's week 0. */ ! if (jan1day >= 1 && jan1day <= 4) ! diff = 0; ! else ! diff = 1; ! ret = simple_wknum - diff; ! if (ret == 0) /* we're in the first week of the year */ ! ret = 53; ! return ret; } #endif --- 572,618 ---- /* * If Jan 1 was a Monday through Thursday, it was in ! * week 1. Otherwise it was last year's highest week, which is * this year's week 0. + * + * What does that mean? + * If Jan 1 was Monday, the week number is exactly right, it can + * never be 0. + * If it was Tuesday through Thursday, the weeknumber is one + * less than it should be, so we add one. + * Otherwise, Friday, Saturday or Sunday, the week number is + * OK, but if it is 0, it needs to be 52 or 53. */ ! switch (jan1day) { ! case 1: /* Monday */ ! break; ! case 2: /* Tuesday */ ! case 3: /* Wednedsday */ ! case 4: /* Thursday */ ! weeknum++; ! break; ! case 5: /* Friday */ ! case 6: /* Saturday */ ! case 0: /* Sunday */ ! if (weeknum == 0) { ! #ifdef USE_BROKEN_XPG4 ! /* XPG4 (as of March 1994) says 53 unconditionally */ ! weeknum = 53; ! #else ! /* get week number of last week of last year */ ! struct tm dec31ly; /* 12/31 last year */ ! dec31ly = *timeptr; ! dec31ly.tm_year--; ! dec31ly.tm_mon = 11; ! dec31ly.tm_mday = 31; ! dec31ly.tm_wday = (jan1day == 0) ? 6 : jan1day - 1; ! dec31ly.tm_yday = 364 + isleap(dec31ly.tm_year + 1900); ! weeknum = iso8601wknum(& dec31ly); ! #endif ! } ! break; ! } ! return weeknum; } #endif *************** *** 559,569 **** weeknumber(const struct tm *timeptr, int firstweekday) #endif { ! if (firstweekday == 0) ! return (timeptr->tm_yday + 7 - timeptr->tm_wday) / 7; ! else ! return (timeptr->tm_yday + 7 - ! (timeptr->tm_wday ? (timeptr->tm_wday - 1) : 6)) / 7; } #if 0 --- 630,648 ---- weeknumber(const struct tm *timeptr, int firstweekday) #endif { ! int wday = timeptr->tm_wday; ! int ret; ! ! if (firstweekday == 1) { ! if (wday == 0) /* sunday */ ! wday = 6; ! else ! wday--; ! } ! ret = ((timeptr->tm_yday + 7 - wday) / 7); ! if (ret < 0) ! ret = 0; ! return ret; } #if 0 *************** *** 666,679 **** "(%%p) locale's AM or PM based on 12-hour clock %p", "(%%r) time, 12-hour (same as %%I:%%M:%%S %%p) %r", "(%%u) ISO 8601: Weekday as decimal number [1 (Monday) - 7] %u", ! "(%%v) VAX date (dd-bbb-YYYY) %v", "(%%w) day of week (0..6, Sunday == 0) %w", "(%%x) appropriate locale date representation %x", "(%%y) last two digits of year (00..99) %y", (char *) NULL }; ! /* Main routine. */ int main(argc, argv) --- 745,758 ---- "(%%p) locale's AM or PM based on 12-hour clock %p", "(%%r) time, 12-hour (same as %%I:%%M:%%S %%p) %r", "(%%u) ISO 8601: Weekday as decimal number [1 (Monday) - 7] %u", ! "(%%v) VMS date (dd-bbb-YYYY) %v", "(%%w) day of week (0..6, Sunday == 0) %w", "(%%x) appropriate locale date representation %x", "(%%y) last two digits of year (00..99) %y", (char *) NULL }; ! /* main routine. */ int main(argc, argv) diff -crN gawk-2.15.4/msg.c gawk-2.15.5/msg.c *** gawk-2.15.4/msg.c Tue Jan 4 16:18:22 1994 --- gawk-2.15.5/msg.c Mon May 2 06:06:39 1994 *************** *** 52,58 **** (void) putc('(', stderr); if (file) (void) fprintf(stderr, "FILENAME=%s ", file); ! (void) fprintf(stderr, "FNR=%d) ", FNR); } (void) fprintf(stderr, s); vfprintf(stderr, emsg, argp); --- 52,58 ---- (void) putc('(', stderr); if (file) (void) fprintf(stderr, "FILENAME=%s ", file); ! (void) fprintf(stderr, "FNR=%ld) ", FNR); } (void) fprintf(stderr, s); vfprintf(stderr, emsg, argp); diff -crN gawk-2.15.4/node.c gawk-2.15.5/node.c *** gawk-2.15.4/node.c Tue Jan 4 16:18:23 1994 --- gawk-2.15.5/node.c Wed May 11 23:38:45 1994 *************** *** 122,128 **** { char buf[128]; register char *sp = buf; ! register long num = 0; #ifdef DEBUG if (s == NULL) cant_happen(); --- 122,128 ---- { char buf[128]; register char *sp = buf; ! double val; #ifdef DEBUG if (s == NULL) cant_happen(); *************** *** 132,141 **** if (s->stref != 0) ; /*cant_happen();*/ #endif ! /* avoids floating point exception in DOS*/ ! if ( s->numbr <= LONG_MAX && s->numbr >= -LONG_MAX) ! num = (long)s->numbr; ! if ((AWKNUM) num == s->numbr) { /* integral value */ if (num < NVAL && num >= 0) { sp = (char *) values[num]; s->stlen = 1; --- 132,174 ---- if (s->stref != 0) ; /*cant_happen();*/ #endif ! /* not an integral value, or out of range */ ! if ((val = double_to_int(s->numbr)) != s->numbr ! || val < LONG_MIN || val > LONG_MAX) { ! #ifdef GFMT_WORKAROUND ! NODE *dummy, *r; ! unsigned short oflags; ! extern NODE *format_tree P((const char *, int, NODE *)); ! extern NODE **fmt_list; /* declared in eval.c */ ! ! /* create dummy node for a sole use of format_tree */ ! getnode(dummy); ! dummy->lnode = s; ! dummy->rnode = NULL; ! oflags = s->flags; ! s->flags |= PERM; /* prevent from freeing by format_tree() */ ! r = format_tree(CONVFMT, fmt_list[CONVFMTidx]->stlen, dummy); ! s->flags = oflags; ! s->stfmt = (char)CONVFMTidx; ! s->stlen = r->stlen; ! s->stptr = r->stptr; ! freenode(r); /* Do not free_temp(r)! We want */ ! freenode(dummy); /* to keep s->stptr == r->stpr. */ ! ! goto no_malloc; ! #else ! /* ! * no need for a "replacement" formatting by gawk, ! * just use sprintf ! */ ! sprintf(sp, CONVFMT, s->numbr); ! s->stlen = strlen(sp); ! s->stfmt = (char)CONVFMTidx; ! #endif /* GFMT_WORKAROUND */ ! } else { ! /* integral value */ ! /* force conversion to long only once */ ! register long num = (long) val; if (num < NVAL && num >= 0) { sp = (char *) values[num]; s->stlen = 1; *************** *** 144,157 **** s->stlen = strlen(sp); } s->stfmt = -1; - } else { - NUMTOSTR(sp, CONVFMT, s->numbr); - s->stlen = strlen(sp); - s->stfmt = (char)CONVFMTidx; } - s->stref = 1; emalloc(s->stptr, char *, s->stlen + 2, "force_string"); memcpy(s->stptr, sp, s->stlen+1); s->flags |= STR; return s; } --- 177,187 ---- s->stlen = strlen(sp); } s->stfmt = -1; } emalloc(s->stptr, char *, s->stlen + 2, "force_string"); memcpy(s->stptr, sp, s->stlen+1); + no_malloc: + s->stref = 1; s->flags |= STR; return s; } *************** *** 183,189 **** if (n->type == Node_val && (n->flags & STR)) { r->stref = 1; emalloc(r->stptr, char *, r->stlen + 2, "dupnode"); ! memcpy(r->stptr, n->stptr, r->stlen+1); } return r; } --- 213,220 ---- if (n->type == Node_val && (n->flags & STR)) { r->stref = 1; emalloc(r->stptr, char *, r->stlen + 2, "dupnode"); ! memcpy(r->stptr, n->stptr, r->stlen); ! r->stptr[r->stlen] = '\0'; } return r; } *************** *** 286,293 **** /* get more nodes and initialize list */ emalloc(nextfree, NODE *, NODECHUNK * sizeof(NODE), "newnode"); ! for (np = nextfree; np < &nextfree[NODECHUNK - 1]; np++) np->nextp = np + 1; np->nextp = NULL; np = nextfree; nextfree = nextfree->nextp; --- 317,326 ---- /* get more nodes and initialize list */ emalloc(nextfree, NODE *, NODECHUNK * sizeof(NODE), "newnode"); ! for (np = nextfree; np < &nextfree[NODECHUNK - 1]; np++) { ! np->flags = 0; np->nextp = np + 1; + } np->nextp = NULL; np = nextfree; nextfree = nextfree->nextp; diff -crN gawk-2.15.4/patchlevel.h gawk-2.15.5/patchlevel.h *** gawk-2.15.4/patchlevel.h Wed Jan 12 06:56:26 1994 --- gawk-2.15.5/patchlevel.h Sun Feb 13 21:55:40 1994 *************** *** 1 **** ! #define PATCHLEVEL 4 --- 1 ---- ! #define PATCHLEVEL 5 diff -crN gawk-2.15.4/protos.h gawk-2.15.5/protos.h *** gawk-2.15.4/protos.h Wed Dec 29 10:35:41 1993 --- gawk-2.15.5/protos.h Sun May 1 18:20:21 1994 *************** *** 32,45 **** extern aptr_t realloc P((aptr_t, MALLOC_ARG_T)); extern aptr_t calloc P((MALLOC_ARG_T, MALLOC_ARG_T)); extern void free P((aptr_t)); ! extern char *getenv P((char *)); extern char *strcpy P((char *, const char *)); extern char *strcat P((char *, const char *)); - extern char *strncpy P((char *, const char *, int)); extern int strcmp P((const char *, const char *)); ! extern int strncmp P((const char *, const char *, int)); #ifndef VMS extern char *strerror P((int)); #else --- 32,47 ---- extern aptr_t realloc P((aptr_t, MALLOC_ARG_T)); extern aptr_t calloc P((MALLOC_ARG_T, MALLOC_ARG_T)); + #if !defined(sun) && !defined(__sun__) extern void free P((aptr_t)); ! #endif ! extern char *getenv P((const char *)); extern char *strcpy P((char *, const char *)); extern char *strcat P((char *, const char *)); extern int strcmp P((const char *, const char *)); ! extern char *strncpy P((char *, const char *, size_t)); ! extern int strncmp P((const char *, const char *, size_t)); #ifndef VMS extern char *strerror P((int)); #else *************** *** 48,59 **** extern char *strchr P((const char *, int)); extern char *strrchr P((const char *, int)); extern char *strstr P((const char *s1, const char *s2)); ! extern int strlen P((const char *)); extern long strtol P((const char *, char **, int)); #if !defined(_MSC_VER) && !defined(__GNU_LIBRARY__) extern size_t strftime P((char *, size_t, const char *, const struct tm *)); #endif extern time_t time P((time_t *)); extern aptr_t memset P((aptr_t, int, size_t)); extern aptr_t memcpy P((aptr_t, const aptr_t, size_t)); extern aptr_t memmove P((aptr_t, const aptr_t, size_t)); --- 50,65 ---- extern char *strchr P((const char *, int)); extern char *strrchr P((const char *, int)); extern char *strstr P((const char *s1, const char *s2)); ! extern size_t strlen P((const char *)); extern long strtol P((const char *, char **, int)); #if !defined(_MSC_VER) && !defined(__GNU_LIBRARY__) extern size_t strftime P((char *, size_t, const char *, const struct tm *)); #endif + #ifdef __STDC__ extern time_t time P((time_t *)); + #else + extern long time(); + #endif extern aptr_t memset P((aptr_t, int, size_t)); extern aptr_t memcpy P((aptr_t, const aptr_t, size_t)); extern aptr_t memmove P((aptr_t, const aptr_t, size_t)); *************** *** 62,68 **** extern int fprintf P((FILE *, const char *, ...)); #if !defined(MSDOS) && !defined(__GNU_LIBRARY__) ! extern size_t fwrite P((const void *, size_t, size_t, FILE *)); extern int fputs P((const char *, FILE *)); extern int unlink P((const char *)); #endif --- 68,78 ---- extern int fprintf P((FILE *, const char *, ...)); #if !defined(MSDOS) && !defined(__GNU_LIBRARY__) ! #ifdef __STDC__ ! extern size_t fwrite P((const aptr_t, size_t, size_t, FILE *)); ! #else ! extern int fwrite(); ! #endif extern int fputs P((const char *, FILE *)); extern int unlink P((const char *)); #endif *************** *** 83,89 **** #endif extern double pow P((double x, double y)); ! extern double atof P((char *)); extern double strtod P((const char *, char **)); extern int fstat P((int, struct stat *)); extern int stat P((const char *, struct stat *)); --- 93,99 ---- #endif extern double pow P((double x, double y)); ! extern double atof P((const char *)); extern double strtod P((const char *, char **)); extern int fstat P((int, struct stat *)); extern int stat P((const char *, struct stat *)); *************** *** 97,114 **** extern int dup2 P((int,int)); extern int fork P(()); extern int execl P((/* char *, char *, ... */)); extern int read P((int, char *, int)); extern int wait P((int *)); extern void _exit P((int)); - #ifndef __STDC__ - extern long time P((long *)); - #endif - #ifdef NON_STD_SPRINTF ! extern char *sprintf(); #else ! extern int sprintf(); #endif /* SPRINTF_INT */ #undef aptr_t --- 107,122 ---- extern int dup2 P((int,int)); extern int fork P(()); extern int execl P((/* char *, char *, ... */)); + #ifndef __STDC__ extern int read P((int, char *, int)); + #endif extern int wait P((int *)); extern void _exit P((int)); #ifdef NON_STD_SPRINTF ! extern char *sprintf P((char *, const char*, ...)); #else ! extern int sprintf P((char *, const char*, ...)); #endif /* SPRINTF_INT */ #undef aptr_t diff -crN gawk-2.15.4/test/Makefile gawk-2.15.5/test/Makefile *** gawk-2.15.4/test/Makefile Thu Jan 13 21:15:32 1994 --- gawk-2.15.5/test/Makefile Tue May 10 22:57:41 1994 *************** *** 7,13 **** fsbs negexp asgext anchgsub splitargv awkpath nfset reparse gawk.extensions: fieldwdth ignrcase posix manyfiles igncfs argtest \ ! badargtest extra: regtest inftest --- 7,13 ---- fsbs negexp asgext anchgsub splitargv awkpath nfset reparse gawk.extensions: fieldwdth ignrcase posix manyfiles igncfs argtest \ ! badargs extra: regtest inftest *************** *** 69,74 **** --- 69,75 ---- cmp posix.good tmp && rm -f tmp manyfiles:: + @rm -rf junk @mkdir junk @../gawk 'BEGIN { for (i = 1; i <= 300; i++) print i, i}' >tmp @../gawk -f manyfiles.awk tmp tmp *************** *** 137,145 **** @../gawk -f argtest.awk -x -y abc >tmp cmp argtest.good tmp && rm -f tmp ! badargtest:: @-../gawk -f 2>&1 | grep -v patchlevel > tmp cmp badargs.good tmp && rm -f tmp clean: ! rm -f tmp core --- 138,146 ---- @../gawk -f argtest.awk -x -y abc >tmp 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 diff -crN gawk-2.15.4/test/manyfiles.awk gawk-2.15.5/test/manyfiles.awk *** gawk-2.15.4/test/manyfiles.awk Tue Oct 19 20:07:58 1993 --- gawk-2.15.5/test/manyfiles.awk Wed Apr 27 07:00:40 1994 *************** *** 1 **** ! { print $2 > "junk/" $1 } --- 1 ---- ! { print $2 > ("junk/" $1) } diff -crN gawk-2.15.4/test/rs.good gawk-2.15.5/test/rs.good *** gawk-2.15.4/test/rs.good Tue Oct 19 20:07:59 1993 --- gawk-2.15.5/test/rs.good Wed Apr 27 06:54:22 1994 *************** *** 1,4 **** a b c d e - --- 1,3 ---- diff -crN gawk-2.15.4/vms/descrip.mms gawk-2.15.5/vms/descrip.mms *** gawk-2.15.4/vms/descrip.mms Thu Nov 4 06:25:52 1993 --- gawk-2.15.5/vms/descrip.mms Tue Mar 8 06:46:29 1994 *************** *** 109,115 **** # Release of gawk REL=2.15 ! PATCHLVL=3 # dummy target to allow building "gawk" in addition to explicit "gawk.exe" gawk : gawk.exe --- 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 *************** *** 132,150 **** write opt "identification=""V$(REL).$(PATCHLVL)""" close opt - $(AWKOBJS) : awk.h config.h - $(VMSCODE) : awk.h config.h $(VMSDIR)vms.h vms_misc.obj : $(VMSDIR)vms_misc.c vms_popen.obj : $(VMSDIR)vms_popen.c vms_fwrite.obj : $(VMSDIR)vms_fwrite.c vms_args.obj : $(VMSDIR)vms_args.c vms_gawk.obj : $(VMSDIR)vms_gawk.c vms_cli.obj : $(VMSDIR)vms_cli.c dfa.obj : awk.h config.h dfa.h regex.obj : awk.h config.h regex.h getopt.obj : getopt.h main.obj : patchlevel.h awktab.obj : awk.h awktab.c # bison or yacc required awktab.c : awk.y # foo.y :: yacc => y[_]tab.c, bison => foo_tab.c --- 132,151 ---- write opt "identification=""V$(REL).$(PATCHLVL)""" close opt vms_misc.obj : $(VMSDIR)vms_misc.c vms_popen.obj : $(VMSDIR)vms_popen.c vms_fwrite.obj : $(VMSDIR)vms_fwrite.c vms_args.obj : $(VMSDIR)vms_args.c vms_gawk.obj : $(VMSDIR)vms_gawk.c vms_cli.obj : $(VMSDIR)vms_cli.c + $(VMSCODE) : awk.h config.h $(VMSDIR)vms.h + dfa.obj : awk.h config.h dfa.h regex.obj : awk.h config.h regex.h getopt.obj : getopt.h main.obj : patchlevel.h awktab.obj : awk.h awktab.c + $(AWKOBJS) : awk.h config.h # bison or yacc required awktab.c : awk.y # foo.y :: yacc => y[_]tab.c, bison => foo_tab.c diff -crN gawk-2.15.4/vms/vmsbuild.com gawk-2.15.5/vms/vmsbuild.com *** gawk-2.15.4/vms/vmsbuild.com Wed Dec 29 10:42:58 1993 --- gawk-2.15.5/vms/vmsbuild.com Sat Feb 19 22:56:10 1994 *************** *** 5,11 **** $! gawk 2.15 revised, Oct'93 $! $ REL = "2.15" !release version number ! $ PATCHLVL = "4" $! $! [ 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 = "5" $! $! [ remove "/optimize=noinline" for VAX C V2.x or DEC C ] $! [ add "/standard=VAXC" for DEC C and "/g_float" for Alpha ] EOF