summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2010-07-16 12:45:40 +0300
committerArnold D. Robbins <arnold@skeeve.com>2010-07-16 12:45:40 +0300
commit558ba97bdeac5a68bb9248a5c4cdf2feeb24e771 (patch)
tree5c03c98edb9c5488103a6ffdef047e590e0b35b9
parent8c042f99cc7465c86351d21331a129111b75345d (diff)
downloadgawk-558ba97bdeac5a68bb9248a5c4cdf2feeb24e771.tar.gz
Move to gawk-3.0.1.gawk-3.0.1
-rw-r--r--ChangeLog482
-rw-r--r--FUTURES8
-rw-r--r--Makefile.in86
-rw-r--r--NEWS62
-rw-r--r--PORTS56
-rw-r--r--README16
-rw-r--r--README_d/README.VMS65
-rw-r--r--README_d/README.irix55
-rw-r--r--README_d/README.pc183
-rw-r--r--README_d/README.sgi7
-rw-r--r--README_d/README.sunos416
-rw-r--r--README_d/README.ultrix7
-rw-r--r--README_d/README.yacc3
-rw-r--r--acconfig.h2
-rw-r--r--aclocal.m449
-rw-r--r--alloca.c2
-rw-r--r--amiga/gawkmisc.ami2
-rw-r--r--array.c6
-rw-r--r--atari/ChangeLog9
-rw-r--r--atari/Makefile.awklib41
-rw-r--r--atari/Makefile.st183
-rw-r--r--atari/config.h37
-rw-r--r--atari/gawkmisc.atr2
-rw-r--r--awk.h56
-rw-r--r--awk.y55
-rw-r--r--awklib/ChangeLog13
-rw-r--r--awklib/Makefile.in22
-rw-r--r--awklib/eg/lib/mktime.awk2
-rw-r--r--awklib/eg/lib/round.awk32
-rw-r--r--awklib/eg/prog/cut.awk2
-rw-r--r--awklib/eg/prog/wc.awk2
-rw-r--r--awklib/group.awk80
-rwxr-xr-xawklib/igawk.save120
-rw-r--r--awklib/passwd.awk56
-rw-r--r--builtin.c309
-rw-r--r--configh.in24
-rwxr-xr-xconfigure347
-rw-r--r--configure.in20
-rw-r--r--custom.h8
-rw-r--r--dfa.c4
-rw-r--r--doc/ChangeLog48
-rw-r--r--doc/Makefile.in55
-rw-r--r--doc/README.card19
-rw-r--r--doc/ad.block48
-rw-r--r--doc/awkcard.in1353
-rw-r--r--doc/awkforai.txt150
-rw-r--r--doc/cardfonts37
-rw-r--r--doc/colors42
-rw-r--r--doc/gawk.1109
-rw-r--r--doc/gawk.texi675
-rw-r--r--doc/macros211
-rw-r--r--doc/no.colors31
-rw-r--r--doc/setter.outline77
-rw-r--r--doc/texinfo.tex1378
-rw-r--r--eval.c132
-rw-r--r--field.c248
-rw-r--r--gawkmisc.c4
-rw-r--r--getopt.c129
-rw-r--r--io.c252
-rw-r--r--main.c222
-rw-r--r--missing.c4
-rw-r--r--missing/strftime.32
-rw-r--r--missing/strftime.c8
-rw-r--r--msg.c2
-rw-r--r--node.c67
-rw-r--r--patchlevel.h2
-rw-r--r--pc/ChangeLog4
-rw-r--r--pc/Makefile98
-rw-r--r--pc/Makefile.tst205
-rw-r--r--pc/config.h2
-rw-r--r--pc/gawkmisc.pc2
-rw-r--r--posix/gawkmisc.c2
-rw-r--r--protos.h2
-rw-r--r--random.c (renamed from missing/random.c)3
-rw-r--r--random.h29
-rw-r--r--re.c9
-rw-r--r--regex.c98
-rw-r--r--regex.h26
-rw-r--r--stamp-h.in2
-rw-r--r--test/ChangeLog137
-rw-r--r--test/Makefile279
-rw-r--r--test/Makefile.in121
-rw-r--r--test/README5
-rw-r--r--test/back89.in2
-rw-r--r--test/back89.ok1
-rw-r--r--test/backgsub.awk4
-rw-r--r--test/backgsub.in1
-rw-r--r--test/backgsub.ok1
-rw-r--r--test/badargs.ok5
-rw-r--r--test/clsflnam.awk12
-rw-r--r--test/clsflnam.in3
-rw-r--r--test/clsflnam.ok0
-rw-r--r--test/dynlj.awk1
-rw-r--r--test/dynlj.ok1
-rw-r--r--test/eofsplit.awk68
-rw-r--r--test/eofsplit.ok0
-rw-r--r--test/fldchgnf.awk1
-rw-r--r--test/fldchgnf.in1
-rw-r--r--test/fldchgnf.ok2
-rw-r--r--test/fnarray.awk7
-rw-r--r--test/fnarray.ok1
-rw-r--r--test/gensub.awk1
-rw-r--r--test/gensub.ok1
-rw-r--r--test/getlnhd.awk10
-rw-r--r--test/getlnhd.ok2
-rw-r--r--test/gsubasgn.awk13
-rw-r--r--test/gsubasgn.ok4
-rw-r--r--test/gsubtest.awk8
-rw-r--r--test/gsubtest.ok6
-rw-r--r--test/mmap8k.in143
-rw-r--r--test/nlfldsep.ok13
-rwxr-xr-xtest/nlfldsep.sh10
-rw-r--r--test/prt1eval.awk6
-rw-r--r--test/prt1eval.ok1
-rw-r--r--test/prtoeval.awk4
-rw-r--r--test/prtoeval.ok2
-rw-r--r--test/rand.awk2
-rw-r--r--test/rand.ok1
-rw-r--r--test/reindops.awk6
-rw-r--r--test/reindops.in1
-rw-r--r--test/reindops.ok1
-rw-r--r--test/splitvar.awk5
-rw-r--r--test/splitvar.in1
-rw-r--r--test/splitvar.ok1
-rw-r--r--test/splitwht.awk7
-rw-r--r--test/splitwht.ok2
-rw-r--r--test/sprintfc.awk1
-rw-r--r--test/sprintfc.in3
-rw-r--r--test/sprintfc.ok3
-rw-r--r--test/strftime.ok1
-rw-r--r--test/substr.awk5
-rw-r--r--test/substr.ok1
-rw-r--r--test/tradanch.awk2
-rw-r--r--test/tradanch.in2
-rw-r--r--test/tradanch.ok0
-rw-r--r--test/tweakfld.awk296
-rw-r--r--test/tweakfld.in3
-rw-r--r--test/tweakfld.ok3
-rw-r--r--version.c4
-rw-r--r--vms/ChangeLog61
-rw-r--r--vms/descrip.mms108
-rw-r--r--vms/gawkmisc.vms4
-rw-r--r--vms/redirect.h12
-rw-r--r--vms/vms-conf.h18
-rw-r--r--vms/vms.h43
-rw-r--r--vms/vms_args.c17
-rw-r--r--vms/vms_cli.c34
-rw-r--r--vms/vms_fwrite.c20
-rw-r--r--vms/vms_gawk.c6
-rw-r--r--vms/vms_misc.c13
-rw-r--r--vms/vms_popen.c32
-rw-r--r--vms/vmsbuild.com72
-rw-r--r--vms/vmstest.com587
153 files changed, 8199 insertions, 2374 deletions
diff --git a/ChangeLog b/ChangeLog
index 40821925..c084177f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,481 @@
+Tue Dec 10 23:09:26 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Release 3.0.1: Release tar file made.
+
+Tue Dec 10 22:39:41 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (dist): add dependency on `info'. Remove line that
+ does makeinfo.
+ (install): use $(LN) not $(LN_S) to link gawk gawk-version.
+
+Sun Dec 8 07:53:44 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (gawk): took COMPFLAGS out of link line for help
+ on VMS posix. Shouldn't (I hope) affect anything else.
+
+Thu Nov 28 11:52:24 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * configure.in (AC_PROG_INSTALL): Set INSTALL to install-sh.
+
+Tue Nov 26 22:42:00 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * PORTS: Updated list of systems.
+ * Makefile.in (install): Fix some typos and add some improvements
+ for Ultrix.
+
+Sun Nov 24 22:16:26 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (do_printf): if no args, fatal error. Return silently
+ if --traditional.
+
+Thu Nov 7 20:54:43 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * io.c (inrec): make sure EOF hasn't already happened before
+ trying to read; prevents accessing freed buffer. Thanks to
+ Michal Jaegermann.
+ * Makefile.in [AWKSRC]: add random.h.
+ random.h: new file, redefines names of the `random' functions.
+ random.c, builtin.c: add include of random.h.
+
+Thu Nov 7 09:06:21 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * awk.y (snode): undo 4 Oct change, put do_split code.
+ field.c (do_split): restore old code; add test for CONST, so
+ that re_parse_field is used if third arg to split is a regexp
+ constant.
+
+Mon Nov 4 12:57:11 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * main.c (main): Research -m[fr] options don't need literal '='
+ characters. Brian's documentation was confusing. Fixed, not
+ that anyone actually uses these options with gawk.
+
+Sun Nov 3 11:23:21 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * field.c (def_parse_field): add \n to list of acceptable white space.
+ (posix_def_parse_field): new routine, just like def_parse_field(),
+ but only allows space and tab as separators.
+ (do_split, set_FS): make appropriate choice between the two
+ *def_parse_field() routines.
+
+Fri Oct 25 10:13:06 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * configure.in: remove test for random.
+ * Makefile.in: add random.c to list of files always compiled.
+ * missing.c: remove HAVE_RANDOM test.
+ * builtin.c: remove ifdef's for HAVE_RANDOM.
+ [GAWK_RAND_MAX]: use constant we know works with our random().
+ * random.c: new file - moved from missing/ directory.
+
+Wed Oct 23 19:46:01 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * builtin.c (do_tolower, do_toupper): Add `unsigned char *' casts.
+
+Tue Oct 22 21:27:52 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c [GAWK_RANDOM_MAX]: Try to make definition a bit
+ smarter; don't use RAND_MAX if it's equal to SHRT_MAX, blows
+ things up.
+
+Tue Oct 22 08:49:20 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * main.c (copyleft): update copyright date to 1996.
+ too many files to list: update copyright date to 1996.
+
+Sun Oct 20 12:21:09 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * awk.y, dfa.c, eval.c, io.c, re.c: added various FIXME comments.
+
+Sat Oct 19 22:06:42 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * eval.c (nodetype2str): make static, add prototype.
+ * field.c (sc_parse_field): cast array subscripts to int to
+ shut up gcc warnings.
+ * gawkmisc.c: add prototype for xmalloc.
+ * awk.h: add prototype for getredirect.
+ * builtin.c (do_fflush): remove extern decl of getredirect.
+ * io.c (get_a_record, mmap_get_record): change decl of rs to int,
+ to shut up gcc warnings.
+ * awk.y (isassignable): add a default to switch to quiet gcc.
+ * getopt.c (_getopt_internal): give default value to `indfound'.
+
+Fri Oct 18 09:00:49 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * regex.h [RE_SYNTAX_AWK]: add RE_CONTEXT_INDEP_ANCHORS.
+
+Thu Oct 17 22:32:55 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * aclocal.m4 [AM_SANITY_CHECK_CC]: added.
+ * configure.in: use it.
+
+Thu Oct 17 21:43:25 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * configure.in: add checks for locale.h and setlocale().
+ awk.h: include locale.h and define out setlocale() if not available.
+ main.c (main): call setlocale().
+ builtin.c (do_tolower, do_toupper): use unsigned char pointers,
+ to get other charsets right in different locales.
+
+Wed Oct 16 21:32:53 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (format_tree): Change initial buffer size to 512
+ and use a constant. Allows large values of %f per bug report
+ from sheyn@cs.bu.edu.
+
+Wed Oct 16 21:22:08 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in [MISC]: removed TAGS and tags
+ (local-distclean): added TAGS and tags
+ (maintainer-clean): removed TAGS and tags
+
+Wed Oct 16 12:28:43 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * main.c (version): Add call to copyleft(), per new standards.
+ version.c: Fix text of version string to match new standards.
+
+Sun Oct 6 22:19:45 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * regex.c: updated to Emacs 19.34b base.
+
+Sun Oct 6 21:57:34 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * re.c (make_regexp): fixed to handle \8 and \9 in the middle
+ of a regexp.
+
+Fri Oct 4 10:26:16 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * awk.y (snode): remove case for do_split; always making the
+ third arg a Node_regex is wrong.
+ field.c (do_split): rationalized to distinguish `/ /' from `" "'.
+ Generally fixed up.
+ * node.c (parse_escape): Allow single digit \x escapes.
+
+1996-10-02 Paul Eggert <eggert@twinsun.com>
+
+ * builtin.c (format_tree):
+ Fix bug in %d and %i format: NaNs, and values
+ in the range LONG_MAX+1 .. ULONG_MAX, were mishandled.
+ Don't assume that double values <= -1 are converted to unsigned
+ long in the expected way; the C Standard doesn't guarantee this.
+
+1996-10-02 Paul Eggert <eggert@twinsun.com>
+
+ * awk.h (INT_MAX): Remove unused symbol.
+
+Mon Sep 30 22:19:11 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * getopt.c (_getopt_internal): If 'W' is in the optstring followed
+ by a ';' then search through the long opts table. This makes
+ `-W foo=bar' same as `--foo=bar'.
+ * main.c (main): 'W' now prints an error message.
+ (gawk_option): deleted the routine.
+
+Sun Sep 29 23:04:54 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (sub_common): fix several bugs with gsub when
+ matching null strings. See test/gsubtest.awk.
+
+Fri Sep 20 17:35:54 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * alloca.c (NULL): don't define if <config.h> has already done so.
+
+Fri Sep 20 11:54:31 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (do_print): evaluate all the expressions first and
+ then print them. Avoids suprising behavior. See test/prtoeval.awk
+ for an example.
+
+Tue Sep 10 06:21:40 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * awk.h [FUNC]: new flag, marks a Node_parameter_list as really
+ being the function name; allows more checking in awk.y.
+ * awk.y (isassignable): now takes a NODE * instead of a type, to
+ check if a function parameter is marked FUNC, then it's the function
+ name, which is not assignable. Fix call from snode().
+ (function_prologue): mark function name as FUNC.
+ (yyerror): don't call exit() anymore; gawk will now report
+ all syntax errors.
+
+Sun Sep 1 19:36:30 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * field.c (rebuild_record): after building new field 0, go through
+ all old fields, and if they used to point into the old one,
+ have them point into the new one. Then turn off PERM flag before
+ unref-ing field 0.
+
+Wed Aug 28 19:13:34 1996 Arnold D. Robbins <arnold@math.utah.edu>
+
+ * eval.c (set_IGNORECASE): Correctly parenthesize bit operations
+ in test and fix logic for string value.
+
+Wed Aug 28 22:06:33 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * main.c (usage): add email addresses for bug reporting, per
+ change in GNU Coding Standards from RMS.
+
+Sun Aug 11 23:13:22 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (install): correct use of $(INSTALL_PROGRAM).
+
+Thu Aug 8 23:29:43 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * parse.y (isassignable): new function, checks in type can
+ be assigned to.
+ (snode): changed checking for 3rd arg of gsub to be more
+ general, supersedes earlier change.
+
+Thu Aug 8 13:58:26 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * parse.y (snode): If third arg to sub or gsub is builtin
+ function, complain, since can't substitute into result.
+ * eval.c (r_get_lhs): diagnose Node_builtin as an error, instead
+ of falling through into default case and using cant_happen().
+
+Thu Aug 1 07:13:14 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * regex.h [RE_DEBUG]: new macro.
+ [RE_SYNTAX_GNU_AWK]: add RE_DEBUG.
+ [RE_SYNTAX_POSIX_AWK]: add RE_INTERVALS.
+ * regex.c (re_set_syntax): add #ifdef DEBUG code to turn on `debug'
+ flag if RE_DEBUG set, and turn off debug if not set and debug
+ was on.
+ * main.c (main): remove `do_intervals = TRUE' from `if (do_posix)',
+ it's now handled in the definition of RE_SYNTAX_POSIX_AWK.
+
+Mon Jul 29 17:49:07 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * io.c (O_ACCMODE): define it if <fcntl.h> doesn't.
+
+Mon Jul 29 12:02:48 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * eval.c (set_IGNORECASE): made somewhat smarter. gawk -v IGNORECASE=0
+ was acting the same as -v IGNORECASE=1. Thanks to Darrell Hankerson
+ for the bug report.
+
+Fri Jul 26 12:04:43 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * awk.h (format_val): add declaration of new routine.
+ * node.c (format_val): new routine, abstracts old guts of
+ r_forcestring; accepts format string and index as additional params.
+ (r_force_string): changed to call format_val.
+ * builtin.c (do_print): don't tree_eval the tree twice in case
+ OFMTidx != CONVFMTidx; doing so could cause side effects
+ (from bug report by Tobias Rettstadt, xassp@ipds.uni-kiel.de).
+ Instead, call format_val.
+
+Mon Jul 22 21:59:15 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * io.c (iop_close): change check for "is $0 in the input buffer"
+ to use `< (iop->buf + iop->secsiz + iop->size)' instead of
+ `< iop->end'. The latter is bogus if EOF has been hit on the
+ file. Fix from Darrel Hankerson based on bug report by
+ Charles Howes (howes@grid.direct.ca). See test/eofsplit.awk.
+
+Thu Jul 18 19:43:20 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (sub_common): backed out change of Feb 14 in favor of:
+ (do_gensub): Changed to use make_string and then to |= TEMP
+ flag, based on bug report and patch from Katsuyuki Okabe,
+ hgc02147@niftyserve.or.jp.
+
+Thu Jul 18 19:23:53 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * custom.h: added ifdef for QNX, based on bug report from
+ Michael Hunter, mphunter@qnx.com.
+
+Mon Jul 15 09:31:01 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * io.c (redirect): When finding the rp pointer, if it's not
+ NULL, set str = rp->value. This gets the '\0' terminated
+ version. Motivated by bug report from John Hawkinson
+ (jhawk@bbnplanet.com).
+
+Sun Jul 14 18:40:26 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * configure.in: added call to AC_CHECK_LIB(m, fmod), since
+ apparently some systems have fmod in the math library.
+ Portability: the Holy Grail. Sigh.
+
+Sun Jul 14 18:08:01 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * awk.h: add Jim Meyerings ISASCII etc hacks for ctype macros.
+ * builtin.c (do_toupper, do_tolower, sub_common): changed to use
+ upper-case versions of ctype macros.
+ * main.c (main): ditto.
+ * node.c (r_force_number, parse_escape): ditto.
+
+Sun Jul 14 06:34:18 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * field.c (set_record): made it always do the PERM flag.
+ Fixes cases where $0 is assigned to, e.g. by gsub, keeps
+ the fields valid.
+ (get_field): removed the call to reset_record in
+ case where ! field0_valid. We want to leave the fields alone
+ if they've been changed.
+
+Thu Jul 11 23:04:20 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * io.c (devopen): change tests of (flag & O_fooONLY) to
+ (flag & O_ACCMODE) == O_fooONLY. Per (long standing) bug
+ report from Chapman Flack.
+ (close_redir): change final conditional to just (status != 0)
+ so that ERRNO always set; the warning had its own `if (do_lint)'
+ anyway.
+ * eval.c (do_split): force type of array to be Node_var_array
+ instead of Node_var. Per (long standing) bug report from
+ Chapman Flack.
+
+Thu Jul 11 22:17:14 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (install): added symlink of gawk to awk if
+ no awk in $(bindir).
+ (LN_S): new variable for symlinking.
+ (uninstall): remove awk if it's the same gawk.
+ * Configure.in: Added call to AC_PROG_LN_S for Makefile.in.
+
+Sun Jul 7 15:47:13 1996 Arnold D. Robbins <arnold@infographix.com>
+
+ * main.c (main): made `--posix' turn on interval expressions.
+ Gawk now matches its documentation. (What a concept!)
+
+Wed Jul 3 15:02:48 1996 Arnold D. Robbins <arnold@infographix.com>
+
+ * regex.h, regex.c: upgraded to changes from Emacs 19.31.
+
+Fri May 17 08:46:07 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * io.c (get_a_record): added `continued' flag. Fix from
+ Darrell Hankerson for when RS = "\n|something".
+
+Wed May 15 02:34:55 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (awklib/all): now depends on gawk, fixes problem
+ with parrallel make.
+
+Tue May 14 15:02:52 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (format_tree): fix handling of '*' to deal with
+ negative value for fieldwidth -- make positive and turn on
+ left justify. Per bug report from Michael Brennan.
+
+Sun May 12 20:42:06 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * eval.c (r_get_lhs): case Node_subscript. Check if array name
+ is actually a function, fatal error if so.
+
+Sun May 5 10:11:52 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * io.c (redirect): call flush_io() before creating a new output pipe,
+ per bug report from Brian Kernighan (bwk@research.bell-labs.com).
+
+Fri Mar 15 06:38:33 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (install): use $(INSTALL_PROGRAM), not $(INSTALL).
+ (local-distclean): add `*~' to list of files to be removed.
+ (CFLAGS): now contains just @CFLAGS@.
+ (COMPFLAGS): replaces use of CFLAGS, has CFLAGS plus all the
+ other stuff.
+
+Wed Mar 13 14:19:38 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * io.c (mmap_get_record): fixed to not place sentinel at end
+ of mmap'ed object. Won't work if file is exact multiple of
+ disk block size. See comments in code for more info.
+ Thanks to Rick Adams (rick@uunet.uu.net) for help in testing.
+
+Sun Mar 10 22:50:23 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * io.c (do_close): notice if we were called as `close(FILENAME)'
+ and arrange to close the current input file. This turns out
+ to be easy to do, just call `nextfile(TRUE)'. Based on bug report
+ from Pascal A. Dupuis, <dupuis@lei.ucl.ac.be>.
+
+Thu Mar 7 08:08:51 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * field.c (init_fields, grow_fields, set_field, rebuild_record):
+ Nuke the `nodes' array everywhere. Anytime a field is unref'ed,
+ allocate a new node that is a copy of Nnull_string. This avoids
+ subtle memory management problems when doing a lot of assignment
+ to fields, and tweaking of NF. Make sure that fields_arr[0] always
+ has a type of Node_val!
+ * field.c (set_NF): If NF is decremented, clear fields between
+ NF and parse_high_water, otherwise if NF incremented, clear
+ fields between parse_high_water and NF.
+ * eval.c (nodetype2str): new function, used for diganostics.
+ eval.c (interpret): use nodetype2str when finding invalid node.
+
+Mon Mar 4 09:02:28 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (do_toupper, do_tolower): use isascii along with
+ isupper/islower before changing case, in case characters have
+ the high bit set. This is a hack.
+
+Mon Feb 26 22:24:44 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (sub_common): if no match, and called from gensub,
+ don't free the temporary string, since the tmp_number then
+ writes over it.
+
+Sun Feb 25 23:13:01 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (format_tree): fixed %c to treat user input as
+ numeric also by adding test for MAYBE_NUM.
+
+Tue Feb 20 12:25:50 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * configure.in: Added AC_FUNC_MMAP call and add madvise to
+ list of functions to look for.
+ * awk.h [IOP_ISMAPPED]: new flag value for mmap support and new
+ `getrec' structure member in struct iobuf.
+ * io.c (iop_alloc, iop_close): changed to map/unmap input file
+ into memory if possible.
+ (mmap_get_record): new function to actually retrieve the
+ record from mmaped file.
+
+Thu Feb 1 08:56:46 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (do_substr): fixed lint message to use indx+1 when
+ start position is past end of string.
+
+Sun Jan 28 07:00:56 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (do_substr): rationalized handling of missing length
+ argument, as well as various accompagnying lint warnings. Previous
+ code was slightly bogus. Talk about your Day 1 bugs.
+
+Thu Jan 25 14:09:11 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * builtin.c (do_substr): if length exceeds length of actual
+ string, do computation of needed substring length *after*
+ the lint warning.
+
+Wed Jan 24 10:06:16 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (gawk): Add $(CFLAGS) to link line.
+ (Makefile): target depends on the Makefile.in files.
+ (OTHERS): Added TAGS and tags to the distribution.
+ (local-distclean): New rule.
+ (distclean): Use it.
+ (maintainer-clean): Don't `make distclean' before running submakes,
+ since that removes makefiles needed for the submakes.
+ * builtin.c (do_strftime): Remove hard coded limit on length of result.
+ Based on code from Paul Eggert (eggert@twinsun.com).
+
+Mon Jan 22 13:16:37 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * main.c (usage): takes new fp parameter which is either
+ stdout for `--help' (per the GNU Coding Standards) or stderr
+ if an error occurs. Fix all calls.
+ (version): prints to stdout per the coding stds.
+ (copyleft): prints to stdout now, not stderr, and exits.
+
+Fri Jan 19 08:10:29 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * regex.h [RE_GNU_AWK]: added RE_CONTEXT_INDEP_OPS to set of
+ bits we turn off for regular operation. Breaks things like
+ /^+[0-9]+/ to match a literal `+' at the beginning of, say,
+ a phone number.
+
Wed Jan 10 23:19:36 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
* 3.0.0 polished up and release tar file made.
@@ -10,8 +488,8 @@ Wed Dec 27 11:46:16 1995 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
Mon Aug 28 23:04:30 1995 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
* awk.h updated for NeXT - bracket TRUE/FALSE
- * removed shadowing of 'start' in io.c:get_a_record
- * Makefile.in and Doc/Makefile.in: fixed to use gawk.1 and gawk.texi,
+ * io.c (get_a_record): removed shadowing of 'start' in
+ * Makefile.in and doc/Makefile.in: fixed to use gawk.1 and gawk.texi,
instead of gawk.1.in and gawk.texi.in.
Mon Aug 25 11:04:30 1995 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
diff --git a/FUTURES b/FUTURES
index 431ecd1b..13a312c1 100644
--- a/FUTURES
+++ b/FUTURES
@@ -57,7 +57,11 @@ In 3.1
======
A PROCINFO array to replace /dev/pid, /dev/user, et al.
- Use mmap to read input files on systems that support it.
+ DONE: Use mmap to read input files on systems that support it.
+
+ Add `abort' statement a la Thompson awk.
+
+ Consider removing use of and/or need for the protos.h file.
Use a new or improved dfa.
@@ -71,7 +75,7 @@ In 3.1
Use rx instead of regex.
- Do a reference card.
+ DONE: Do a reference card.
? Have strftime() pay attention to the value of ENVIRON["TZ"]
diff --git a/Makefile.in b/Makefile.in
index 3897e39d..7082fc30 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,6 +1,6 @@
# Makefile for GNU Awk.
#
-# Copyright (C) 1986, 1988-1995 the Free Software Foundation, Inc.
+# Copyright (C) 1986, 1988-1996 the Free Software Foundation, Inc.
#
# This file is part of GAWK, the GNU implementation of the
# AWK Programming Language.
@@ -37,6 +37,9 @@ LIBS = @LIBS@
ALLOCA = @ALLOCA@
+LN = ln
+LN_S = @LN_S@
+
exec_prefix = @exec_prefix@
prefix = @prefix@
binprefix =
@@ -54,7 +57,8 @@ libexecdir = @libexecdir@/awk
DEFPATH = ".:$(datadir)"
SHELL = /bin/sh
-CFLAGS = @CFLAGS@ -DGAWK -I. -I$(srcdir) @DEFS@
+CFLAGS = @CFLAGS@
+COMPFLAGS = $(CFLAGS) -DGAWK -I. -I$(srcdir) @DEFS@
# object files
AWKOBJS = array.o builtin.o eval.o field.o gawkmisc.o io.o main.o \
@@ -62,9 +66,9 @@ AWKOBJS = array.o builtin.o eval.o field.o gawkmisc.o io.o main.o \
ALLOBJS = $(AWKOBJS) awktab.o
-# GNUOBJS
-# GNU stuff that gawk uses as library routines.
-GNUOBJS= getopt.o getopt1.o regex.o dfa.o $(ALLOCA)
+# LIBOBJS
+# GNU and other stuff that gawk uses as library routines.
+LIBOBJS= getopt.o getopt1.o regex.o dfa.o random.o $(ALLOCA)
# source and documentation files
SRC = array.c builtin.c eval.c field.c gawkmisc.c io.c main.c \
@@ -72,13 +76,13 @@ SRC = array.c builtin.c eval.c field.c gawkmisc.c io.c main.c \
ALLSRC= $(SRC) awktab.c
-AWKSRC= awk.h awk.y custom.h $(ALLSRC) patchlevel.h protos.h
+AWKSRC= awk.h awk.y custom.h $(ALLSRC) patchlevel.h protos.h random.h
-GNUSRC = alloca.c dfa.c dfa.h regex.c regex.h getopt.h getopt.c getopt1.c
+LIBSRC = alloca.c dfa.c dfa.h regex.c regex.h getopt.h getopt.c getopt1.c random.c
COPIES = missing/system.c missing/tzset.c \
missing/memcmp.c missing/memcpy.c missing/memset.c \
- missing/random.c missing/strncasecmp.c missing/strchr.c \
+ missing/strncasecmp.c missing/strchr.c \
missing/strerror.c missing/strtod.c \
missing/strftime.c missing/strftime.3
@@ -97,6 +101,8 @@ OTHERS= amiga doc pc atari vms README_d posix awklib
ALLDOC= doc/gawk.dvi $(TEXFILES) doc/gawk.info*
+MAKEFILEIN = Makefile.in awklib/Makefile.in doc/Makefile.in test/Makefile.in
+
# Release of gawk. There can be no leading or trailing white space here!
REL=3.0
@@ -105,10 +111,10 @@ REL=3.0
.SUFFIXES: .c .o
.c.o:
- $(CC) -c $(CFLAGS) $<
+ $(CC) -c $(COMPFLAGS) $<
# rules to build gawk
-all: gawk doc/all awklib/all
+all: gawk awklib/all doc/all
# stuff to make sure that configure has been run.
$(srcdir)/configure: configure.in aclocal.m4
@@ -124,30 +130,32 @@ config.h: stamp-h
stamp-h: configh.in config.status
$(SHELL) ./config.status
-Makefile: Makefile.in config.status
+Makefile: $(MAKEFILEIN) config.status
$(SHELL) ./config.status
config.status: configure
$(SHELL) ./config.status --recheck
-gawk: $(ALLOBJS) $(GNUOBJS) $(REOBJS)
- $(CC) -o gawk $(LDFLAGS) $(ALLOBJS) $(GNUOBJS) $(REOBJS) -lm $(LIBS)
+gawk: $(ALLOBJS) $(LIBOBJS) $(REOBJS)
+ $(CC) -o gawk $(LDFLAGS) $(ALLOBJS) $(LIBOBJS) $(REOBJS) $(LIBS)
$(ALLOBJS): awk.h dfa.h regex.h config.h custom.h
-$(GNUOBJS): config.h custom.h
+$(LIBOBJS): config.h custom.h
# SunOS make's (at least) VPATH doesn't do subdirectories...
# Solaris make doesn't allow $< in the actual rule
gawkmisc.o: $(srcdir)/amiga/gawkmisc.ami $(srcdir)/atari/gawkmisc.atr \
$(srcdir)/pc/gawkmisc.pc $(srcdir)/posix/gawkmisc.c \
$(srcdir)/vms/gawkmisc.vms
- $(CC) -c $(CFLAGS) -DDEFPATH='$(DEFPATH)' $(srcdir)/gawkmisc.c
+ $(CC) -c $(COMPFLAGS) -DDEFPATH='$(DEFPATH)' $(srcdir)/gawkmisc.c
getopt.o: getopt.h
getopt1.o: getopt.h
+builtin.o: random.h
+
main.o: patchlevel.h
awktab.c: awk.y
@@ -158,12 +166,19 @@ awktab.c: awk.y
# VMS POSIX make won't apply the default .c.o rule to awktab.o for some reason
awktab.o: awktab.c awk.h
- $(CC) -c $(CFLAGS) $(srcdir)/awktab.c
+ $(CC) -c $(COMPFLAGS) $(srcdir)/awktab.c
alloca.o: alloca.c
install: gawk info installdirs
- $(INSTALL) gawk $(bindir) && chmod 755 $(bindir)/gawk
+ -rm -f $(bindir)/gawk
+ fullname=gawk-$(REL).`./gawk '{print $$3}' patchlevel.h` ; \
+ $(INSTALL_PROGRAM) gawk $(bindir)/$$fullname && chmod 775 $(bindir)/$$fullname ; \
+ (cd $(bindir); $(LN) $$fullname gawk)
+ (cd $(bindir); \
+ if [ ! -f awk ]; \
+ then $(LN_S) gawk awk; \
+ fi; exit 0)
cd doc && $(MAKE) install
cd awklib && $(MAKE) install
@@ -172,17 +187,26 @@ installdirs: mkinstalldirs
$(libdir) $(infodir) $(mandir) $(libexecdir)
uninstall:
- rm -f $(bindir)/gawk
+ (cd $(bindir); \
+ if [ -f awk ] && cmp awk gawk > /dev/null; then rm -f awk; fi)
+ (fullname=gawk-$(REL).`gawk '{print $$3}' patchlevel.h` ; \
+ cd $(bindir); \
+ if cmp gawk $$fullname; then rm -f gawk; fi ; \
+ rm -f $(bindir)/$$fullname)
cd doc && $(MAKE) uninstall
cd awklib && $(MAKE) uninstall
-rmdir $(datadir) $(libexecdir)
# auxiliary rules for release maintenance
lint: $(ALLSRC)
- lint -hcbax $(CFLAGS) $(ALLSRC)
+ lint -hcbax $(COMPFLAGS) $(ALLSRC)
xref:
- cxref -c $(CFLAGS) $(ALLSRC) | grep -v ' /' >xref
+ cxref -c $(COMPFLAGS) $(ALLSRC) | grep -v ' /' >xref
+
+mostlyclean:
+ : mostly clean does nothing for gawk
+ : use "make clean" to really clean things out
clean:
rm -rf gawk *.o core y.output
@@ -190,16 +214,17 @@ clean:
cd test && $(MAKE) clean
cd awklib && $(MAKE) clean
-distclean: clean
- rm -f Makefile TAGS tags *.orig *.rej */*.orig */*.rej awk.output \
+local-distclean:
+ rm -f Makefile *.orig *.rej */*.orig */*.rej awk.output \
gmon.out make.out config.h config.status config.cache \
- config.log stamp-h
+ config.log stamp-h tags TAGS *~
+
+distclean: clean local-distclean
cd doc && $(MAKE) distclean
cd awklib && $(MAKE) distclean
+ cd test && $(MAKE) distclean
-mostlyclean: clean
-
-maintainer-clean: distclean
+maintainer-clean: clean local-distclean
@echo "This command is intended for maintainers to use; it"
@echo "deletes files that may require special tools to rebuild."
rm -f awktab.c
@@ -211,6 +236,8 @@ clobber: maintainer-clean
TAGS:
etags $(AWKSRC)
+
+tags:
ctags $(AWKSRC)
dvi: $(srcdir)/doc/gawk.texi
@@ -222,14 +249,14 @@ info: $(srcdir)/doc/gawk.texi
doc/all:
cd doc && $(MAKE) all
-awklib/all:
+awklib/all: gawk
cd awklib && $(MAKE) all
-dist: $(AWKSRC) $(GNUSRC) $(DOCS) $(MISC) $(COPIES) awklib/stamp-eg distclean
+dist: $(AWKSRC) $(LIBSRC) $(DOCS) $(MISC) $(COPIES) awklib/stamp-eg info distclean
-rm -rf gawk-$(REL)*
dir=gawk-$(REL).`gawk '{print $$3}' patchlevel.h` && \
mkdir $$dir && \
- cp -pr $(AWKSRC) $(GNUSRC) $(MISC) $$dir && \
+ cp -pr $(AWKSRC) $(LIBSRC) $(MISC) $$dir && \
mkdir $$dir/missing && \
cp -p $(COPIES) $$dir/missing && \
for i in $(OTHERS); \
@@ -237,7 +264,6 @@ dist: $(AWKSRC) $(GNUSRC) $(DOCS) $(MISC) $(COPIES) awklib/stamp-eg distclean
cp -pr $$i $$dir ; \
done && \
cp -pr test $$dir && \
- (cd $$dir/doc; $(MAKEINFO) gawk.texi) && \
find $$dir -type d -exec chmod 777 {} ';' && \
find $$dir -print | doschk && \
tar -cf - $$dir | gzip > $$dir.tar.gz && \
diff --git a/NEWS b/NEWS
index 3ac650cf..98a01a3c 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,58 @@
-Changes from 2.15.6 to 3.0
---------------------------
+Changes from 3.0.0 to 3.0.1
+---------------------------
+
+Troff source for a handy-dandy five color reference card is now provided.
+Thanks to SSC for their macros.
+
+Gawk now behaves like Unix awk and mawk, in that newline acts as white
+space for separating fields and for split(), by default. In posix mode,
+only space and tab separate fields. The documentation has been updated to
+reflect this.
+
+Tons and tons of small bugs fixed and new tests added, see the ChangeLogs.
+
+Lots fewer compile time warnings from gcc -Wall. Remaining ones aren't
+worth fixing.
+
+Gawk now pays some attention to the locale settings.
+
+Fixes to gsub to catch several corner cases.
+
+The `print' statement now evaluates all expressions first, and then
+prints them. This leads to less suprising behaviour if any expression has
+output side effects.
+
+Miscellanious improvements in regex.h and regex.c.
+
+Gawk will now install itself as gawk-M.N.P in $(bindir), and link
+`gawk' to it. This makes it easy to have multiple versions of gawk
+simultaneously. It will also now install itself as `awk' in $(bindir)
+if there is no `awk' there. This is in addition to installing itself as
+`gawk'. This change benefits the Hurd, and possibly other systems. One
+day, gawk will drop the `g', but not yet.
+
+`--posix' turns on interval expressions. Gawk now matches its documentation.
+
+`close(FILENAME)' now does something meaningful.
+
+Field management code in field.c majorly overhauled, several times.
+
+The gensub code has been fixed, several bugs are now gone.
+
+Gawk will use mmap for data file input if it is available.
+
+The printf/sprintf code has been improved.
+
+Minor issues in Makefile setup worked on and improved.
+
+builtin.c:do_substr rationalized.
+
+Regex matching fixed so that /+[0-9]/ now matches the leading +.
+
+For building on vms, the default compiler is now DEC C rather than VAX C.
+
+Changes from 2.15.6 to 3.0.0
+----------------------------
Fixed spelling of `Programming' in the copyright notice in all the files.
@@ -73,7 +126,7 @@ accepted but generates a lint warning. `next file' will go away eventually.
Gawk with --lint will now notice empty source files and empty data files.
-Amiga support using the Unix emulation added. Thanks to fnf@amigalib.com.
+Amiga support using the Unix emulation added. Thanks to fnf@ninemoons.com.
test/Makefile is now "parallel-make safe".
@@ -82,8 +135,7 @@ pure posix regexps, and --compat goes to traditional Unix regexps. However,
interval expressions, even though specified by POSIX, are turned off by
default, to avoid breaking old code.
-IGNORECASE now applies to *everything*, string comparison as well
-as regexp operations.
+IGNORECASE now applies to string comparison as well as regexp operations.
The AT&T Bell Labs Research awk fflush builtin function is now supported.
fflush is extended to flush stdout if no arg and everything if given
diff --git a/PORTS b/PORTS
index 5087a430..596f1fda 100644
--- a/PORTS
+++ b/PORTS
@@ -1,35 +1,31 @@
A recent version of gawk has been successfully compiled and run "make test"
on the following:
-Sun 4/490 running 4.1
-NeXT running 2.0
-DECstation 3100 running Ultrix 4.0 or Ultrix 3.1 (different config)
-AtariST (16-bit ints, gcc compiler, byacc, running under TOS)
-ESIX V.3.2 Rev D (== System V Release 3.2), the 386. compiler was gcc + bison
-IBM RS/6000 (see README.rs6000)
-486 running SVR4, using cc and bison
-SGI running IRIX 3.3 using gcc (fails with cc)
-Sequent Balance running Dynix V3.1
-Cray Y-MP8 running Unicos 6.0.11
-Cray 2 running Unicos 6.1 (modulo trailing zeroes in chem)
-VAX/VMS V5.x (should also work on 4.6 and 4.7)
-VMS POSIX V1.0, V1.1
-OpenVMS AXP V1.0
-MSDOS - Microsoft C 5.1, compiles and runs very simple testing
-BSD 4.4alpha
+Using cc:
+ Dec Alpha OSF 4.0
+ HP9000/755 HP-UX 9.01
+ IBM PowerPC AIX 4.1.4.0
+ SGI IRIX 4.0.5
+ SGI IRIX 5.3
+ SunOS 4.1.3
+ SunOS 5.5
-From: ghazi@noc.rutgers.edu (Kaveh R. Ghazi):
+Other systems:
+ DEC Alpha OSF/1 3.2
+ DEC Alpha Linux/AXP
+ DECstation 5000 ULTRIX 4.3
+ HP 9000/735 HP-UX 10.01
+ IBM RS/6000 AIX 3.2
+ IBM SP2 AIX 4.1
+ NeXT Turbostation Mach 3.3
+ SGI Indigo/2 IRIX 5.3
+ SGI PowerChallenge IRIX 6.1
+ Sun SPARC Solaris 2.5
+ Sun SPARC Solaris 2.5.1
+ Sun SPARC SunOS 4.1.3
+ Sun SPARC Linux 2.0.22
+ Intel x86 Linux 2.1.10
+ Intel x86 DOS (compiler: djgpp v2, emx+gcc,
+ and MSC 6.00A, 7, and 8)
+ Intel x86 OS+2 (compiler: emx+gcc)
-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 --git a/README b/README
index 982f37c2..ddbd7110 100644
--- a/README
+++ b/README
@@ -1,10 +1,10 @@
README:
-This is GNU Awk 3.0. It should be upwardly compatible with the Bell
+This is GNU Awk 3.0.1. It should be upwardly compatible with the Bell
Labs research version of awk. It is almost completely compliant with
the 1993 POSIX 1003.2 standard for awk.
-This release adds new features -- see NEWS for details.
+Patch 1 just fixes bugs -- see NEWS for details.
See the file INSTALL for installation instructions.
@@ -25,20 +25,22 @@ The man page is up to date.
INSTALLATION:
-Check whether there is a system-specific README file for your system under
-the `README_d' directory.
+Check whether there is a system-specific README file for your system
+under the `README_d' directory. If there's something there that you
+should have read and didn't, and you bug me about it, I'm going to yell
+at you.
See the file INSTALL.
If you have neither bison nor yacc, use the awktab.c file here. It was
-generated with bison, and has no AT&T code in it. (Note that modifying
+generated with bison, and has no proprietary code in it. (Note that modifying
awk.y without bison or yacc will be difficult, at best. You might want
to get a copy of bison from the FSF too.)
If you have an MS-DOS or OS/2 system, use the stuff in the `pc' directory.
Similarly, there are separate directories for Ataris, Amigas, and VMS.
-Appendix B of The GAWK Manual discusses configuration in detail. The
+Appendix B of The GNU Awk User's Guide discusses configuration in detail. The
configuration process is now based on Autoconf, so the whole business
should be considerably simpler than it was in gawk 2.X.Y.
@@ -89,4 +91,4 @@ OS/2:
Amiga:
Fred Fish
- fnf@amigalib.com
+ fnf@ninemoons.com
diff --git a/README_d/README.VMS b/README_d/README.VMS
index 057a359f..40442b14 100644
--- a/README_d/README.VMS
+++ b/README_d/README.VMS
@@ -8,21 +8,20 @@ utility. From the source directory, use either
or
|$ MMS/DECRIPTION=[.VMS]DECSRIP.MMS GAWK
-VAX C V3.x -- use either vmsbuild.com or descrip.mms as is. These use
- CC/OPTIMIZE=NOLINE, which is essential for version 3.0.
-VAX C V2.x -- (version 2.3 or 2.4; older ones won't work); edit either
- vmsbuild.com or descrip.mms according to the comments in them.
- For vmsbuild.com, this just entails removing two '!' delimiters.
- Also edit config.h (which is a copy of file [.config]vms-conf.h)
- and comment out or delete the two lines ``#define __STDC__ 0''
- and ``#define VAXC_BUILTINS'' near the end.
-GNU C -- edit vmsbuild.com or descrip.mms; the changes are different
- from those for VAX C V2.x, but equally straightforward. No
- changes to config.h should be needed.
-DEC C -- edit vmsbuild.com or descrip.mms according to their comments.
-
- Tested under VAX/VMS V5.5-2 using VAX C V3.2, GNU C 1.42 and 2.5.0.
-Should work without modifications for VMS V4.6 and up.
+DEC C -- use either vmsbuild.com or descrip.mms as is.
+VAX C -- use `@vmsbuild VAXC' or `MMS/MACRO=("VAXC")'. On a system
+ with both VAX C and DEC C installed where DEC C is the default,
+ use `MMS/MACRO=("VAXC","CC=CC/VAXC")' for the MMS variant; for
+ the vmsbuild.com variant, any need for `/VAXC' will be detected
+ automatically.
+GNU C -- use `@vmsbuild GNUC' or `MMS/MACRO=("GNUC")'. On a system
+ where the GCC command is not already defined, use either
+ `@vmsbuild GNUC DO_GNUC_SETUP' or
+ `MMS/MACRO=("GNUC","DO_GNUC_SETUP")'.
+
+ Tested under Alpha/VMS V6.2 using DEC C V5.2 and under VAX/VMS V6.2
+using DEC C V5.2, VAX C 3.2, and GNU C 2.7.1. GAWK should work without
+modifications for VMS V4.6 and up.
Installing GAWK on VMS:
@@ -85,24 +84,20 @@ multi-translation RMS searchlist.
Building and using GAWK under VMS POSIX:
Ignore the instructions above, although vms/gawk.hlp should still
-be made available in a help library. Make sure that the two scripts,
-'configure' and 'mungeconf', are executable; use `chmod +x' on them if
-necessary. Then execute the following two commands:
- |psx> configure vms-posix
- |psx> make PARSER=yacc awktab.c gawk
-The first command will construct files "config.h" and "Makefile" out of
-templates. The second command will compile and link 'gawk'. Due to
-a 'make' bug in VMS POSIX 1.0 and V1.1, the file "awktab.c" must be
-given as an explicit target or it will not be built and the final link
-step will fail. Ignore the warning "Could not find lib m in lib list";
-it is harmless, caused by the Makefile's explicit use of -lm as a linker
-option which is not needed under VMS POSIX. Under V1.1 (but not V1.0)
-a problem with the yacc skeleton /etc/yyparse.c will cause a compiler
-warning for awktab.c, followed by a linker warning about compilation
-warnings in the resulting object module. These warnings can be ignored.
-
- Another 'make' bug interferes with exercising various components
-of the test suite, but all the actual tests should execute correctly.
-(The main exception being book/wordfreq, which gives different results
-due to VMS POSIX 'sort' rather than to 'gawk'.)
+be made available in a help library. The source tree should be unpacked
+into a container file subsystem rather than into the ordinary VMS file
+system. Make sure that the two scripts, 'configure' and 'vms/posix-cc.sh',
+are executable; use `chmod +x' on them if necessary. Then execute the
+following two commands:
+ |psx> CC=vms/posix-cc.sh configure
+ |psx> make CC=c89 gawk
+The first command will construct files "config.h" and "Makefile" out
+of templates, using a script to make the C compiler fit 'configure's
+expectations. The second command will compile and link 'gawk' using
+the C compiler directly; ignore any warnings from `make' about being
+unable to redefine "CC". The configure script will take a very long
+time to execute, but at least it provides incremental feedback as it
+runs.
+
+ Tested with VAX/VMS V6.2 + VMS POSIX V2.0 + DEC C V5.2.
diff --git a/README_d/README.irix b/README_d/README.irix
new file mode 100644
index 00000000..f69bf347
--- /dev/null
+++ b/README_d/README.irix
@@ -0,0 +1,55 @@
+From: "Kaveh R." <ghazi@caip.rutgers.edu!>
+Date: Fri, 6 Dec 1996 11:51:27 -0500 (EST)
+To: arnold@skeeve.atl.ga.us
+Subject: Re: new (and I sure hope final) test release of 3.0.1
+
+ Gawk built everywhere except on irix-4.0.5:
+
+cc -c -DGAWK -I. -I.. -DHAVE_CONFIG_H ../array.c
+accom: Error: ../protos.h, line 73: One declaration for is non-prototype style,)
+ extern int fprintf () ;
+ ----------------------^
+accom: Error: ../protos.h, line 73: One declaration for fprintf is non-prototyp)
+ extern int fprintf () ;
+ ----------------------^
+accom: Error: ../protos.h, line 78: redeclaration of fwrite
+ extern int fwrite();
+ -------------------^
+accom: Error: ../protos.h, line 91: One declaration for is non-prototype style,)
+ extern int sscanf () ;
+ ---------------------^
+accom: Error: ../protos.h, line 91: One declaration for sscanf is non-prototype)
+ extern int sscanf () ;
+ ---------------------^
+accom: Error: ../protos.h, line 126: One declaration for is non-prototype style)
+ extern int sprintf () ;
+ -----------------------------^
+accom: Error: ../protos.h, line 126: One declaration for sprintf is non-prototy)
+ extern int sprintf () ;
+ -----------------------------^
+accom: Error: /usr/include/unistd.h, line 96: One declaration for is non-protot)
+ extern int execl( char *, char *, ...);
+ -----------------------------------------------^
+accom: Error: /usr/include/unistd.h, line 96: One declaration for execl is non-)
+ extern int execl( char *, char *, ...);
+ -----------------------------------------------^
+make: *** [array.o] Error 1
+
+
+ The compiler on irix-4.0.5 understands and uses prototypes in
+its headers, but does not define __STDC__. Since gawk's source code
+prototypes various systems calls and libc functions, without function
+arguments since __STDC__ is not defined, you get these problems.
+
+ I was able to get around it by setting CFLAGS to "-D__STDC__=1".
+Then gawk's source code prototyped functions with arguments, and the above
+errors did not occur. I wonder why gawk is prototyping system functions.
+
+ Anyway, after using the CFLAGS hack (only necessary on irix-4.0.5)
+all systems built and passed "make check".
+
+ --Kaveh
+--
+Kaveh R. Ghazi Systems Engineer / Project Leader
+ghazi@caip.rutgers.edu ICon CMT Corp.
+
diff --git a/README_d/README.pc b/README_d/README.pc
index 875cd53c..07ea334f 100644
--- a/README_d/README.pc
+++ b/README_d/README.pc
@@ -2,17 +2,18 @@ This is the README for GNU awk 3.0 under OS/2 and DOS.
Gawk has been compiled and tested under OS/2 and DOS using the GNU
development tools from DJ Delorie (DJGPP, DOS-only) and Eberhard Mattes
-(EMX, DOS and OS/2). Microsoft C can be used to build 16-bit versions
+(EMX, DOS and OS/2). Microsoft C can be used to build 16-bit versions
for DOS and OS/2.
Building gawk
-------------
-Copy the files in the `pc' directory to the directory with the rest of
-the gawk sources. The makefile contains a configuration section with
-comments, and may need to be edited in order to work with your make
-utility.
+Copy the files in the `pc' directory (EXCEPT for `ChangeLog') to the
+directory with the rest of the gawk sources. (The subdirectories of
+`pc' need not be copied.) The makefile contains a configuration
+section with comments, and may need to be edited in order to work
+with your make utility.
The "prefix" line in the Makefile is used during the install of gawk
(and in building igawk.bat and igawk.cmd). Since the libraries for
@@ -20,8 +21,8 @@ gawk will be installed under $(prefix)/lib/awk (e.g., /gnu/lib/awk),
it is convenient to have this directory in DEFPATH of config.h.
The makefile contains a number of targets for building various DOS and
-OS/2 versions. A list of targets will be printed if the make command is
-given without a target. As an example, to build gawk using the djgpp
+OS/2 versions. A list of targets will be printed if the make command is
+given without a target. As an example, to build gawk using the djgpp
tools, enter "make djgpp".
@@ -29,9 +30,8 @@ Testing and installing gawk
---------------------------
The command "make test" (and possibly "make install") requires several
-Unix-like tools, including an sh-like shell, sed, cp, and cmp. Only dmake
-and OS/2 GNU make are known to work on "make test"; in particular, the
-make delivered as part of the DJGPP tools and Ndmake will not work.
+Unix-like tools, including an sh-like shell, sed, cp, and cmp. Only
+dmake and GNU make are known to work on "make test".
There are two methods for the install: Method 1 uses a typical Unix-like
approach and requires cat, cp, mkdir, sed, and sh; method 2 uses gawk
@@ -39,9 +39,9 @@ and batch files. See the configuration section of the makefile.
The file test/Makefile will need some editing (especially for DOS). A
sample makefile with comments appears in pc/Makefile.tst, and can be
-used to modify test/Makefile for your platform. In addition, the files
-in the test directory ending with ".ok" may need to have their
-end-of-line markers converted, as described in Makefile.tst.
+used to modify test/Makefile for your platform. In addition, some
+files in the test directory may need to have their end-of-line markers
+converted, as described in Makefile.tst.
It is routine to install by hand, but note that the install target also
builds igawk.bat and igawk.cmd, which are used to add an include
@@ -51,12 +51,44 @@ facility to gawk (and which require sh).
Notes
-----
-1. An sh-like shell may be useful for awk programming (and is essential
-for running "make test"). Stewartson's sh (OS/2 and DOS) is a good choice:
+1. Collections containing gawk and various utilities for OS/2 or DOS
+include the GNUish Project, Rommel's OS/2 collection at LEO, and the
+djgpp collection.
- oak.oakland.edu:SimTel/msdos/sysutil/ms_sh23[bs].zip
- ftp-os2.cdrom.com:pub/os2/unix/ms_sh23[bs].zip
- ftp.leo.org:pub/comp/os/os2/shells/ms_sh23b.zip
+The GNUish Project was designed to bring GNU-like programs to small
+systems running OS/2 and DOS. Binary distributions of gawk are
+maintained in GNUish, and include 16bit OS/2 and DOS versions and a
+djgpp-compiled version. Information on GNUish is available via
+
+ http://www.simtel.net/simtel.net/
+ http://www.leo.org/pub/comp/platforms/pc/gnuish
+ http://wuarchive.wustl.edu/systems/msdos/gnuish/
+or
+ ftp://ftp.simtel.net/simtelnet/gnu/gnuish
+ ftp://oak.oakland.edu/pub/simtelnet/gnu/gnuish
+ ftp://wuarchive.wustl.edu/systems/msdos/gnuish/
+
+Documentation appears in gnuish.htm (html) or gnuish.inf (info).
+
+Kai Uwe Rommel <rommel@leo.org> maintains a (mostly OS/2) collection at
+
+ http://www.leo.org/archiv/os2 or ftp://ftp.leo.org
+
+It contains emx-compiled (32bit) versions of gawk for OS/2 and DOS,
+along with many OS/2 utilities.
+
+The djgpp collection at
+
+ http://www.simtel.net/simtelnet/gnu/djgpp
+ ftp://ftp.simtel.net/simtelnet/pub/gnu/djgpp
+
+contains a djgpp-compiled (32bit) version of gawk, along with many
+djgpp-compiled utilities.
+
+
+2. An sh-like shell may be useful for awk programming (and is essential
+for running "make test"). Stewartson's sh (OS/2 and DOS) is a good
+choice, and may be found in GNUish.
Stewartson's shell uses a configuration file (see "Command Line Building"
in the sh manual page), and it may be necessary to edit the entry for
@@ -70,64 +102,67 @@ gawk. The following entries are suggested:
# --but without the use of @-include files.
However, users of djgpp versions of gawk may prefer "dos" over "unix"
-in the above, due to the broken way djgpp handles @-include files.
-Entries for other other utilities (such as sed and wc) may need to be
-edited in order to match your specific collection of programs.
+in the above, due to the way djgpp handles @-include files. Entries
+for other other utilities (such as sed and wc) may need to be edited
+in order to match your specific collection of programs.
-The Korn shell (ksh) may be another possibility:
-
- ftp-os2.cdrom.com:pub/os2/unix/ksh522rt.zip
- ftp.leo.org:pub/comp/os/os2/shells/ksh513rt.zip
+As of Fall 1996, Daisuke Aoyama <jack@st.rim.or.jp> has a test version
+of bash (compiled with djgpp). This version worked flawlessly in
+tests with djgpp gawk and make. It was added to the djgpp collection
+in Nov-96, and may also be obtained via
-Bash (OS/2) should be a good choice; however, there has been some
-trouble getting a solid version for OS/2. As of Feb-95, there are
-two bash ports, available in:
+ http://www.st.rim.or.jp/~jack/alpha/
+ http://www.neongenesis.com/~jack/djgpp-work/alpha/
- ftp.leo.org:pub/comp/os/os2/shells/gnu/gnubash.zip
- ftp.leo.org:pub/comp/os/os2/shells/gnu/bash-112.zip
- ftp-os2.cdrom.com:pub/os2/unix/bash_112.zip
+Under OS/2, bash should be a good choice; however, there has been some
+trouble getting a solid version. As of Feb-95, there are two bash ports,
+available at LEO under shells/gnu/.
-Hamilton's C Shell is another possibility, available for a number of
-platforms. A demo is available at ftp.leo.org.
+LEO also contains a Korn shell (ksh), tcsh, zsh, and a demo of
+Hamilton's C shell, but these have not been tested with gawk by the
+maintainers. Reports are welcomed.
Users of the emx versions of gawk may wish to set EMXSHELL, which
-overrides COMSPEC when running shells from emx programs.
+overrides COMSPEC when running shells from emx programs. Similarly,
+the djgpp version of gawk respects SHELL.
-The site ftp.leo.org (ftp.informatik.tu-muenchen.de) is maintained
-by Kai Uwe Rommel (rommel@ars.de), and is also accessible at
-http://www.leo.org/archiv/os2/ via WWW.
+Compatibility among shells and various utilities (including gawk)
+continues to be a problem. Stewartson's shell may be the best choice
+for emx-compiled programs (although djgpp-bash almost works with
+emx on DOS). GNU make is recommended if using djgpp-bash.
-2. Stewartson's shell contains sources for a setargv-replacement
-for MSC, which can add enhanced command-line processing capabilities
-to gawk. Strongly recommended. See the makefile.
-
-
-3. dmake is by Dennis Vadura (dvadura@watdragon.uwaterloo.ca), CS Dept.,
-University of Waterloo. OS/2 and DOS versions can be found at
+3. GNU make is available at LEO for OS/2 and in the djgpp collection
+for DOS.
- ftp.leo.org:pub/comp/os/os2/devtools/utils/dmake38.zip
- ftp.leo.org:pub/comp/os/os2/devtools/utils/dmake40os2.zip
- ftp-os2.cdrom.com:pub/os2/dev16/dmake38x.zip
+dmake is by Dennis Vadura (dvadura@watdragon.uwaterloo.ca), CS
+Dept., University of Waterloo. OS/2 and DOS versions can be found as
+part of the GNUish project. Note that DOS users will need the DOS-only
+version (due to the swap requirement).
-DOS users will need the DOS-only version (due to the swap requirement):
-
- oak.oakland.edu:SimTel/msdos/c/dmake38[es].zip
-
-Ndmake is by D.G. Kneller. This ShareWare program was later released
-as Opus Make (which is available for OS/2 and DOS). Ndmake 4.5 is
+Ndmake is by D.G. Kneller. This ShareWare program was later released
+as Opus Make (which is available for OS/2 and DOS). Ndmake 4.5 is
available at
- oak.oakland.edu:SimTel/msdos/c/ndmake45.zip
-
-GNU make is from the FSF. An OS/2 version can be found at
+ ftp://ftp.simtel.net/simtelnet/msdos/c/ndmake45.zip
- ftp.leo.org:pub/comp/os/os2/devtools/gnu/gnumake.zip
-For DOS, dmake-3.8 is recommended. The make delivered with djgpp can
-be used on the djgpp target, but will fail on targets with more
-complicated quoting. Makefile compatibility among all the versions
-of OS/2 and DOS gawk has been an ugly problem.
+4. Stewartson's shell contains sources for a setargv-replacement
+for MSC, which can add enhanced command-line processing capabilities
+to gawk. See the makefile. Note that there is a fatal bug in
+stdargv.c, triggered in the case of no closing quote. The following
+patch treats this case as if a quote was inserted as the last
+character on the command-line.
+
+478,479c478,482
+< else
+< spos = &spos[strlen (cpos)];
+---
+> else {
+> /* No matching quote. Fake it. */
+> spos = cpos + strlen (cpos) + 1;
+> break;
+> }
Known bugs
@@ -163,9 +198,35 @@ according to Mattes' recommendation:
tm, just set its tm_isdst to a positive value or to zero, respectively.
Then, strftime() will replace %Z with the name of the time zone.
+However, this probably won't yield a generic solution given that the rules
+for when DST starts and stops vary depending upon your location and the
+rules have changed over time. Most versions of UNIX maintain this
+information in a database (of sorts). In Solaris, for instance, it can be
+found in /usr/share/zoneinfo/*. The setting of the TZ environment variable
+(eg. TZ=US/Pacific) is then used to lookup the specifics for that locale.
+
5. The 16-bit DOS version can exhaust memory on scripts such as Henry
Spencer's "awf". Use GNU C versions if possible.
+6. builtin.c of gawk-3.0.1 triggers a bug in MSC 6.00A. The makefile
+works around the bug by compiling builtin.c without optimizations (-Od).
+In limited testing, it appears that inserting some dummy code in
+builtin.c can provide a better solution than disabling optimizations.
+
+7. The support in djgpp for sh-like shells (as is needed in
+test/getlnhd.awk) was in development as of Oct-96. Pre-release
+versions of the library worked in our tests. Similarly, the makefiles
+depend on features of djgpp-make which were available only in
+pre-release versions.
+
+The DOS maintainers wish to express their thanks to Eli Zaretskii
+<eliz@is.elta.co.il> for his work and for the many conversations
+concerning gawk-3.0.1, make, and djgpp.
+
+8. There are problems with system() when using the rsx package with emx
+programs (rsx is used in DPMI environments such as MS-Win). The djgpp
+versions are preferred in this case.
+
----
diff --git a/README_d/README.sgi b/README_d/README.sgi
index 0d89ad3e..49a5679c 100644
--- a/README_d/README.sgi
+++ b/README_d/README.sgi
@@ -1,10 +1,11 @@
-Sun Dec 31 15:07:11 EST 1995
+Tue Sep 10 08:53:46 EDT 1996
-Gawk 3.0 is known to be broken on 64-bit SGI machines running IRIX 6.x.
+Gawk 3.0.x is known to be broken on 64-bit SGI machines running IRIX 6.2.
1) It needs to be compiled with the native cc, not gcc.
-2) Even if compiled with the native cc, the gensub and gnu regex tests fail.
+2) Even if compiled with the native cc, the -32 option must be used.
+ If not, the gensub and gnu regex tests fail.
I don't have access to an IRIX 6.x machine, so I am not able to track
down the problem. If any kind soul is able to run gawk from a debugger
diff --git a/README_d/README.sunos4 b/README_d/README.sunos4
index e1ae900d..ea9a1952 100644
--- a/README_d/README.sunos4
+++ b/README_d/README.sunos4
@@ -6,3 +6,19 @@ generate under SunOS 4.1.x for io.c.
If you send me email about this without having read this file, I will
fuss at you!
+
+Arnold Robbins
+arnold@gnu.ai.mit.edu
+
+Tue Jan 30 07:01:39 EST 1996
+
+The manyfiles test fails under SunOS 4.1.4. There appears to be some
+bug in libc (shared and static) for SunOS 4.1.4. I got a working gawk
+binary by linking in /usr/5lib/libc.a statically.
+
+
+,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,
+ Jim Farrell | phone 610-940-6020 | Platinum technology
+Systems Administrator | vmail 800-526-9096 x7512 | 620 W. Germantown Pike
+ jwf@platinum.com | fax 610-940-6021 | Plymouth Meeting,Pa,19462
+'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'
diff --git a/README_d/README.ultrix b/README_d/README.ultrix
index 9c56c250..4943409c 100644
--- a/README_d/README.ultrix
+++ b/README_d/README.ultrix
@@ -18,3 +18,10 @@ these paragraphs to it:
does the job. Without the switch gawk will compile and run correctly,
but you will get complaints about lost optimisations in builtin.c,
awk.tab.c and regex.c.
+
+From: Arnold Robbins <arnold@math.utah.edu>
+Date: Sun Sep 8 07:05:07 EDT 1996
+
+On Decstations using Ultrix 4.3, the tweakfld test case will fail. It
+appears that routines in the math library return very small but non-zero
+numbers in cases where most other systems return zero.
diff --git a/README_d/README.yacc b/README_d/README.yacc
index 9c5de13a..aa8ee8ef 100644
--- a/README_d/README.yacc
+++ b/README_d/README.yacc
@@ -5,3 +5,6 @@ of the parse stack. This only shows up when gawk is dealing with deeply
nested control structures, such as those in `awf'.
The problem goes away if you use either bison or Berkeley yacc.
+
+Arnold Robbins
+arnold@gnu.ai.mit.edu
diff --git a/acconfig.h b/acconfig.h
index 325fa9f2..40b484ce 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1995 the Free Software Foundation, Inc.
+ * Copyright (C) 1995, 96 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
diff --git a/aclocal.m4 b/aclocal.m4
index 9086bd81..3070af39 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,7 +1,7 @@
dnl
dnl aclocal.m4 --- autoconf input file for gawk
dnl
-dnl Copyright (C) 1995 the Free Software Foundation, Inc.
+dnl Copyright (C) 1995, 96 the Free Software Foundation, Inc.
dnl
dnl This file is part of GAWK, the GNU implementation of the
dnl AWK Progamming Language.
@@ -132,3 +132,50 @@ eate executables.]) ;;
esac
AC_MSG_RESULT(yes)
])dnl
+
+
+dnl To: Keith Bostic <bostic@bsdi.com>
+dnl Cc: bug-gnu-utils@prep.ai.mit.edu
+dnl Subject: Re: autoconf-2.7
+dnl From: Jim Meyering <meyering@asic.sc.ti.com>
+dnl Date: 15 Oct 1996 11:57:12 -0500
+dnl
+dnl | The assumption that, if a simple program can't be compiled and
+dnl | run, that the user is doing cross-compilation, is causing me
+dnl | serious grief. The problem is that Solaris ships a cc command
+dnl | that just fails, if you haven't bought their compiler.
+dnl |
+dnl | What the user is eventually told is that it's not possible to
+dnl | run test programs when cross-compiling, which doesn't point them
+dnl | at the right problem.
+dnl |
+dnl | Maybe it's just me, but I don't know too many normal users that
+dnl | do cross-compilation. I'd like to see a more stringent test to
+dnl | decide if we're doing cross-compilation. (Maybe with a message
+dnl | to use gcc!?!? ;-})
+dnl
+dnl Now I put this line in configure.in files:
+dnl
+dnl AM_SANITY_CHECK_CC
+dnl
+dnl Here's the macro that goes in aclocal.m4 -- it should be in the
+dnl next official release of automake.
+
+AC_DEFUN(AM_SANITY_CHECK_CC,
+[dnl Derived from macros from Bruno Haible and from Cygnus.
+AC_MSG_CHECKING([whether the compiler ($CC $CFLAGS $LDFLAGS) actually works])
+AC_LANG_SAVE
+ AC_LANG_C
+ AC_TRY_RUN([main() { exit(0); }],
+ am_cv_prog_cc_works=yes, am_cv_prog_cc_works=no,
+ dnl When crosscompiling, just try linking.
+ AC_TRY_LINK([], [], am_cv_prog_cc_works=yes,
+ am_cv_prog_cc_works=no))
+AC_LANG_RESTORE
+case "$am_cv_prog_cc_works" in
+ *no) AC_MSG_ERROR([Installation or configuration problem: C compiler cannot cr
+eate executables.]) ;;
+ *yes) ;;
+esac
+AC_MSG_RESULT(yes)
+])dnl
diff --git a/alloca.c b/alloca.c
index 76b4ae00..a14eb079 100644
--- a/alloca.c
+++ b/alloca.c
@@ -66,7 +66,9 @@ typedef void *pointer;
typedef char *pointer;
#endif
+#ifndef NULL
#define NULL 0
+#endif
/* Different portions of Emacs need to call different versions of
malloc. The Emacs executable needs alloca to call xmalloc, because
diff --git a/amiga/gawkmisc.ami b/amiga/gawkmisc.ami
index 863a5c8f..1107d8d6 100644
--- a/amiga/gawkmisc.ami
+++ b/amiga/gawkmisc.ami
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991 - 95 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991 - 96 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Progamming Language.
diff --git a/array.c b/array.c
index 348b3433..cbc1a236 100644
--- a/array.c
+++ b/array.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991 - 95 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991 - 96 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -213,14 +213,12 @@ NODE *symbol;
register NODE *subs;
int hash1;
{
- register NODE *bucket, *prev = 0;
+ register NODE *bucket;
for (bucket = symbol->var_array[hash1]; bucket != NULL;
bucket = bucket->ahnext) {
if (cmp_nodes(bucket->ahname, subs) == 0)
return bucket;
- else
- prev = bucket; /* save previous list entry */
}
return NULL;
}
diff --git a/atari/ChangeLog b/atari/ChangeLog
index 570c031b..562b6dea 100644
--- a/atari/ChangeLog
+++ b/atari/ChangeLog
@@ -1,3 +1,12 @@
+Thu Nov 21 13:11:20 1996 Michal Jaegermann <michal@phys.ualberta.ca>
+
+ * Makefile.st: Once again Makefile.st and config.h chase
+ moving targets from the main directory.
+
+Thu Nov 7 21:02:01 1996 Michal Jaegermann <michal@phys.ualberta.ca>
+
+ * Makefile.st, Makefile.awklib: sync'ed with ones in main tree.
+
Wed Jan 10 22:58:55 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
* ChangeLog created.
diff --git a/atari/Makefile.awklib b/atari/Makefile.awklib
index 30be5226..abdc1649 100644
--- a/atari/Makefile.awklib
+++ b/atari/Makefile.awklib
@@ -5,7 +5,7 @@
# This Makefile actually will work for awklib even when NOT
# compiling with Atari Makefile!!!
#
-# Copyright (C) 1995 the Free Software Foundation, Inc.
+# Copyright (C) 1995, 96 the Free Software Foundation, Inc.
#
# This file is part of GAWK, the GNU implementation of the
# AWK Programming Language.
@@ -48,45 +48,53 @@ infodir = ${prefix}/info
datadir = ${prefix}/share/awk
libexecdir = ${exec_prefix}/libexec/awk
+# default names of library utilities; on some systems they may require
+# names with extenstions
PWCAT = pwcat
GRCAT = grcat
-AUXPROGS = $(PWCAT) $(GRCAT)
+# the following command used, when necessary, for edits when
+# creating igawk from igawk.sh
GCOM = '{print}'
-GAWK = ../gawk
+GAWK = gawk
+# $(AWK) is a by default freshly compiled gawk or installed awk when
+# cross-compiling; it is used for edits, since we may compile not on
+# Unix machine and an utility like 'sed' may NOT exist there
+AWK = $(srcdir)/../$(GAWK)
+AUXPROGS = $(PWCAT) $(GRCAT)
AUXAWK = passwd.awk group.awk
all: stamp-eg $(AUXPROGS) igawk $(AUXAWK)
stamp-eg: $(srcdir)/../doc/gawk.texi
rm -fr eg stamp-eg
- $(GAWK) -f $(srcdir)/extract.awk $(srcdir)/../doc/gawk.texi
+ $(AWK) -f $(srcdir)/extract.awk $(srcdir)/../doc/gawk.texi
@echo 'some makes are stupid and will not check a directory' > stamp-eg
@echo 'against a file, so this file is a place holder. gack.' >> stamp-eg
$(PWCAT): $(srcdir)/eg/lib/pwcat.c
- $(CC) $(CFLAGS) $(srcdir)/eg/lib/pwcat.c -o $@
+ $(CC) $(CFLAGS) $(srcdir)/eg/lib/pwcat.c $(LDFLAGS) -o $@
$(GRCAT): $(srcdir)/eg/lib/grcat.c
- $(CC) $(CFLAGS) $(srcdir)/eg/lib/grcat.c -o $@
+ $(CC) $(CFLAGS) $(srcdir)/eg/lib/grcat.c $(LDFLAGS) -o $@
igawk: $(srcdir)/eg/prog/igawk.sh
- $(GAWK) $(GCOM) $(srcdir)/eg/prog/igawk.sh > $@ ; chmod 755 $@
+ $(AWK) $(GCOM) $(srcdir)/eg/prog/igawk.sh > $@ ; chmod 755 $@
passwd.awk: $(srcdir)/eg/lib/passwdawk.in
- (cd $(srcdir)/eg/lib ; \
- sed 's;/usr/local/libexec/awk;$(libexecdir);' < passwdawk.in) > passwd.awk
+ $(AWK) '{gsub(/\/usr\/local\/libexec\/awk/, "$(libexecdir)"); print}' \
+ $? > $@
group.awk: $(srcdir)/eg/lib/groupawk.in
- (cd $(srcdir)/eg/lib ; \
- sed 's;/usr/local/libexec/awk;$(libexecdir);' < groupawk.in) > group.awk
+ $(AWK) '{gsub(/\/usr\/local\/libexec\/awk/, "$(libexecdir)"); print}' \
+ $? > $@
install: igawk $(AUXPROGS) $(AUXAWK)
- $(INSTALL_PROGRAM) igawk $(bindir)
+ $(INSTALL_PROGRAM) igawk $(bindir)/igawk && chmod 755 $(bindir)/igawk
for i in $(AUXPROGS) ; do \
- $(INSTALL_PROGRAM) $$i $(libexecdir) ; \
+ $(INSTALL_PROGRAM) $$i $(libexecdir)/$$i ; \
done
for i in $(AUXAWK) $(srcdir)/eg/lib/*.awk ; do \
- $(INSTALL_DATA) $$i $(datadir) ; \
+ $(INSTALL_DATA) $$i $(datadir)/$$i ; \
done
# libexecdir and bindir are removed in the top level Makefile's uninstall
@@ -95,10 +103,7 @@ uninstall:
rm -f $(bindir)/igawk
clean:
- rm -f $(AUXPROGS) igawk
-
-maintainer-clean: clean
- rm -fr eg stamp-eg
+ rm -f $(AUXPROGS) $(AUXAWK) igawk *~
distclean: clean
rm -f Makefile
diff --git a/atari/Makefile.st b/atari/Makefile.st
index ca00b466..20664a48 100644
--- a/atari/Makefile.st
+++ b/atari/Makefile.st
@@ -9,7 +9,7 @@
# (like bash). If this is not the case you will have to edit various
# targets or perform some actions by hand.
#
-# Copyright (C) 1986, 1988-1995 the Free Software Foundation, Inc.
+# Copyright (C) 1986, 1988-1996 the Free Software Foundation, Inc.
#
# This file is part of GAWK, the GNU implementation of the
# AWK Programming Language.
@@ -29,23 +29,29 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+MAKEINFO = makeinfo --no-split
srcdir = .
# native compiler with freshly compiled gawk.ttp to fix awklib
+GAWK = gawk.ttp
CC = gcc
-GAWK=../gawk.ttp
+
# cross-compiler and gawk already installed on the system (any awk will do)
-# CC = cgcc
# GAWK = gawk
+# CC = cgcc
+
# WIDTH and EXT have to be both defined or both undefined
# WIDTH = -mshort -DINT_IS_16BIT
# EXT = 16
+
OFLAGS = -O2 -Wall -fomit-frame-pointer $(WIDTH)
LDFLAGS = $(WIDTH)
YACC = bison -y
-INSTALL = cp -p
+# xstrip -k in target gawk.ttp removes all symbols but _stksize
+# allowing for stack size manipulations without recompiling (with fixstk)
+INSTALL = xstrip -k ; cp -p
INSTALL_PROGRAM = ${INSTALL}
#INSTALL_DATA = ${INSTALL} -m 644
INSTALL_DATA = ${INSTALL}
@@ -60,14 +66,15 @@ prefix = /usr/local
binprefix =
manprefix =
-bindir = $(exec_prefix)/bin
-libdir = $(exec_prefix)/lib
+bindir = ${exec_prefix}/bin
+libdir = ${exec_prefix}/lib
manexta = l
-mandir = $(prefix)/man$(manexta)
+mandir = ${prefix}/man/man$(manexta)
manext = .$(manexta)
-infodir = $(prefix)/info
-datadir = $(prefix)/lib/awk
-libexecdir = $(prefix)/libexec/awk
+infodir = ${prefix}/info
+#datadir = ${prefix}/share/awk
+datadir = ${prefix}/lib/awk
+libexecdir = ${exec_prefix}/lib/awk
#DEFPATH = ".:$(datadir)"
# datadir is passed to the next Makefile level and through sed
@@ -76,27 +83,42 @@ libexecdir = $(prefix)/libexec/awk
DEFPATH = ".,c:\\lib\\awk,c:\\gnu\\lib\\awk"
SHELL = /bin/sh
-CFLAGS = $(OFLAGS) -DGAWK -I. -I$(srcdir) -DHAVE_CONFIG_H
-MFLAGS = "CC=$(CC)" "CFLAGS=$(CFLAGS) $(LDFLAGS)" GAWK=$(GAWK) \
- PWCAT=pwcat.ttp GRCAT=grcat.ttp GCOM='{sub(/\":\"/, "\",\""); print}' \
- "INSTALL_PROGRAM=$(INSTALL)" "INSTALL_DATA=$(INSTALL)" \
+SHELL = /bin/sh
+#CFLAGS = -g -O
+CFLAGS = $(OFLAGS)
+COMPFLAGS = $(CFLAGS) -DGAWK -I. -I$(srcdir) -DHAVE_CONFIG_H
+
+MFLAGS = "CC=$(CC)" \
+ "CFLAGS=$(CFLAGS)" \
+ GAWK=../$(GAWK) \
+ AWK=awk \
+ PWCAT=pwcat.ttp GRCAT=grcat.ttp \
+ "GCOM='{sub(/\":\"/, \"\\\",\\\"\"); print}'" \
+ "COMPFLAGS=$(COMPFLAGS)" \
+ "LDFLAGS=$(LDFLAGS)" \
+ "INSTALL=$(INSTALL)" \
+ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+ "INSTALL_DATA=$(INSTALL_DATA)" \
"bindir=$(bindir)" \
"libdir=$(libdir)" \
"mandir=$(mandir)" \
+ "manext=$(manext)" \
"infodir=$(infodir)" \
"datadir=$(datadir)" \
"libexecdir=$(libexecdir)"
+MMAKE = $(MAKE) $(MFLAGS)
+
# object files
AWKOBJS = array.o builtin.o eval.o field.o gawkmisc.o io.o main.o \
missing.o msg.o node.o re.o version.o
ALLOBJS = $(AWKOBJS) awktab.o
-# GNUOBJS
-# GNU stuff that gawk uses as library routines.
-GNUOBJS= getopt.o getopt1.o regex.o dfa.o $(ALLOCA)
+# LIBOBJS
+# GNU and other stuff that gawk uses as library routines.
+LIBOBJS= getopt.o getopt1.o regex.o dfa.o random.o $(ALLOCA)
# source and documentation files
SRC = array.c builtin.c eval.c field.c gawkmisc.c io.c main.c \
@@ -104,50 +126,62 @@ SRC = array.c builtin.c eval.c field.c gawkmisc.c io.c main.c \
ALLSRC= $(SRC) awktab.c
-AWKSRC= awk.h awk.y $(ALLSRC) patchlevel.h protos.h
+AWKSRC= awk.h awk.y custom.h $(ALLSRC) patchlevel.h protos.h random.h
+
+LIBSRC = alloca.c dfa.c dfa.h regex.c regex.h getopt.h getopt.c getopt1.c random.c
-GNUSRC = alloca.c dfa.c dfa.h regex.c regex.h getopt.h getopt.c getopt1.c
+COPIES = missing/system.c missing/tzset.c \
+ missing/memcmp.c missing/memcpy.c missing/memset.c \
+ missing/strncasecmp.c missing/strchr.c \
+ missing/strerror.c missing/strtod.c \
+ missing/strftime.c missing/strftime.3
-DOCS= doc/gawk.1.in doc/gawk.texi.in doc/texinfo.tex
+DOCS= doc/gawk.1 doc/gawk.texi doc/texinfo.tex
TEXFILES= doc/gawk.aux doc/gawk.cp doc/gawk.cps doc/gawk.fn doc/gawk.fns \
doc/gawk.ky doc/gawk.kys doc/gawk.pg doc/gawk.pgs doc/gawk.toc \
doc/gawk.tp doc/gawk.tps doc/gawk.vr doc/gawk.vrs
+MISC = NEWS COPYING FUTURES Makefile.in PROBLEMS README PORTS POSIX.STD \
+ configure configure.in acconfig.h configh.in ACKNOWLEDGMENT \
+ ChangeLog INSTALL LIMITATIONS install-sh mkinstalldirs aclocal.m4 \
+ stamp-h.in
+
+OTHERS= amiga doc pc atari vms README_d posix awklib
+
ALLDOC= doc/gawk.dvi $(TEXFILES) doc/gawk.info*
+MAKEFILEIN = Makefile.in awklib/Makefile.in doc/Makefile.in test/Makefile.in
+
# Release of gawk. There can be no leading or trailing white space here!
REL=3.0
-PROG=gawk.ttp
# clear out suffixes list
.SUFFIXES:
.SUFFIXES: .c .o
.c.o:
- $(CC) -c $(CFLAGS) $<
-
-# rules to build $(PROG)
-all: $(PROG) awklib/all
+ $(CC) -c $(COMPFLAGS) $<
-alldoc: all doc/all
+# rules to build gawk
+all: $(GAWK) awklib/all
-$(PROG): $(ALLOBJS) $(GNUOBJS) $(REOBJS)
- $(CC) -o $@ $(LDFLAGS) $(ALLOBJS) $(GNUOBJS) $(REOBJS) $(LIBS)
-# toglclr -fload $@
-# xstrip -k $@
+alldoc: all doc/all
+$(GAWK): $(ALLOBJS) $(LIBOBJS) $(REOBJS)
+ $(CC) -o $(GAWK) $(COMPFLAGS) $(LDFLAGS) $(ALLOBJS) $(LIBOBJS) \
+ $(REOBJS) $(LIBS)
$(ALLOBJS): awk.h dfa.h regex.h config.h custom.h
-
-$(GNUOBJS): config.h custom.h
+
+$(LIBOBJS): config.h custom.h
gawkmisc.o: $(srcdir)/atari/gawkmisc.atr
- $(CC) -c -DDEFPATH='$(DEFPATH)' $(CFLAGS) $(srcdir)/$<
+ $(CC) -c $(COMPFLAGS) -DDEFPATH='$(DEFPATH)' $(srcdir)/gawkmisc.c
# this rule needed or not - depending on your library
missing.o io.o:
- $(CC) -c $(CFLAGS) -DPIPES_SIMULATED $(srcdir)/$<
+ $(CC) -c $(COMPFLAGS) -DPIPES_SIMULATED $(srcdir)/$<
# cheat with defines to force an inclusion of a proper code
getopt.o: getopt.h
@@ -157,6 +191,8 @@ getopt.o: getopt.h
getopt1.o: getopt.h
+random.o: random.h
+
main.o: patchlevel.h
awktab.c: awk.y
@@ -167,77 +203,80 @@ awktab.c: awk.y
# VMS POSIX make won't apply the default .c.o rule to awktab.o for some reason
awktab.o: awktab.c awk.h
- $(CC) -c $(CFLAGS) $(srcdir)/awktab.c
+ $(CC) -c $(COMPFLAGS) $(srcdir)/awktab.c
alloca.o: alloca.c
-install: $(PROG)
- $(INSTALL) $(PROG) $(bindir) && chmod 755 $(bindir)/$(PROG)
- cd awklib && $(MAKE) $(MFLAGS) install
-# cd doc && $(MAKE) $(MFLAGS) install
+install: $(GAWK) info installdirs
+ $(INSTALL_PROGRAM) $(GAWK) $(bindir) && chmod 755 $(bindir)/$(GAWK)
+ cd awklib && $(MMAKE) install
+
+installdirs: mkinstalldirs
+ $(srcdir)/mkinstalldirs $(bindir) $(datadir) \
+ $(libdir) $(infodir) $(mandir) $(libexecdir)
installdoc: info
- cd doc && $(MAKE) $(MFLAGS) install
+ cd doc && $(MMAKE) install
#
#installtotal: installdirs install installdoc
-
-installdirs: mkinstalldirs
- $(srcdir)/mkinstalldirs $(bindir) $(datadir) \
- $(libdir) $(infodir) $(mandir)
-
uninstall:
- rm -f $(bindir)/$(PROG)
- cd awklib && $(MAKE) $(MFLAGS) uninstall
-# cd doc && $(MAKE) $(MFLAGS) uninstall
+ rm -f $(bindir)/$(GAWK)
+ cd awklib && $(MMAKE) uninstall
+ -rmdir $(datadir) $(libexecdir)
+# cd doc && $(MMAKE) uninstall
clean:
- rm -rf $(PROG) *.o core y.output
- cd awklib && $(MAKE) $(MFLAGS) clean
+ rm -rf $(GAWK) *.o core y.output
+ cd awklib && $(MMAKE) clean
# the following does not always make sense (when crosscompiling)
# cd test && $(MAKE) $(MFLAGS) clean
# cd doc && $(MAKE) $(MFLAGS) clean
+local-distclean:
+ rm -f Makefile *.orig *.rej */*.orig */*.rej awk.output \
+ gmon.out make.out config.h config.status config.cache \
+ config.log stamp-h *~
-distclean: clean
- rm -f Makefile *.orig *.rej */*.orig */*.rej awk.output gmon.out \
- make.out config.h config.status config.cache config.log stamp-h stamp-h.in
- cd doc && $(MAKE) $(MFLAGS) distclean
+distclean: clean local-distclean
+ cd doc && $(MMAKE) distclean
+ cd awklib && $(MMAKE) distclean
+ cd test && $(MMAKE) distclean
-mostlyclean: clean
-
-maintainer-clean: distclean
- @echo "This command is intended for maintainers to use;"
- @echo "it deletes files that may require special tools to rebuild."
- rm -f awktab.c
- cd doc && $(MAKE) $(MFLAGS) maintainer-clean
- cd test && $(MAKE) $(MFLAGS) maintainer-clean
-# cd awklib && $(MAKE) $(MFLAGS) maintainer-clean
+maintainer-clean: clean local-distclean
+ @echo "This command is intended for maintainers to use; it"
+ @echo "deletes files that may require special tools to rebuild."
+ rm -f awktab.c TAGS tags
+ cd doc && $(MMAKE) maintainer-clean
+# cd test && $(MMAKE) maintainer-clean
+# cd awklib && $(MMAKE) maintainer-clean
clobber: maintainer-clean
TAGS:
etags $(AWKSRC)
+
+tags:
ctags $(AWKSRC)
-dvi: $(srcdir)/doc/gawk.texi.in
- cd doc && $(MAKE) $(MFLAGS) dvi
+dvi: $(srcdir)/doc/gawk.texi
+ cd doc && $(MMAKE) dvi
-info: $(srcdir)/doc/gawk.texi.in
- cd doc && $(MAKE) $(MFLAGS) info
+info: $(srcdir)/doc/gawk.texi
+ cd doc && $(MMAKE) info
doc/all:
- cd doc && $(MAKE) $(MFLAGS) all
+ cd doc && $(MMAKE) all
awklib/all:
- cd awklib && $(MAKE) $(MFLAGS) all
+ cd awklib && $(MMAKE) all
# to run this target you have to adjust test/Makefile quite a bit
-# in order to make it paltable to your shell
+# in order to make it palatable to your shell
#
-check: $(PROG)
- cd test; $(MAKE) -k
+check: $(GAWK)
+ cd test; $(MMAKE) -k
test: check
diff --git a/atari/config.h b/atari/config.h
index 8793d698..1e40b132 100644
--- a/atari/config.h
+++ b/atari/config.h
@@ -3,11 +3,11 @@
* revise for your configuration if configure script does not work
*/
/*
- * acconfig.h -- configuration definitions for gawk.
+ * config.h -- configuration definitions for gawk.
*/
/*
- * Copyright (C) 1995 the Free Software Foundation, Inc.
+ * Copyright (C) 1995, 96 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -57,9 +57,15 @@
/* Define if you don't have vprintf but do have _doprnt. */
/* #undef HAVE_DOPRNT */
+/* Define if you have a working `mmap' system call. */
+/* #undef HAVE_MMAP */
+
/* Define if your struct stat has st_blksize. */
#define HAVE_ST_BLKSIZE 1
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
+#define HAVE_SYS_WAIT_H 1
+
/* Define if your struct tm has tm_zone. */
/* #undef HAVE_TM_ZONE */
@@ -110,17 +116,19 @@
/* Define to `int' if <sys/types.h> doesn't define. */
/* #undef uid_t */
-/* #undef GETPGRP_IS_STANDARD */ /* getpgrp does/does not take an argument */
-/* #define HAVE_BCOPY 1 *//* we have the bcopy function */
-#define HAVE_MEMCPY 1 /* we have the memcpy function */
#define HAVE_STRINGIZE 1 /* can use ANSI # operator in cpp */
-#define HAVE_STRING_H 1 /* the <string.h> header file */
/* #undef REGEX_MALLOC */ /* use malloc instead of alloca in regex.c */
#define SPRINTF_RET int /* return type of sprintf */
/* Define if you have the fmod function. */
#define HAVE_FMOD 1
+/* Define if you have the getpagesize function. */
+#define HAVE_GETPAGESIZE 1
+
+/* Define if you have the madvise function. */
+/* #undef HAVE_MADVISE */
+
/* Define if you have the memcmp function. */
#define HAVE_MEMCMP 1
@@ -130,9 +138,6 @@
/* Define if you have the memset function. */
#define HAVE_MEMSET 1
-/* Define if you have the random function. */
-#define HAVE_RANDOM 1
-
/* Define if you have the strchr function. */
#define HAVE_STRCHR 1
@@ -155,12 +160,24 @@
/* Define if you have the tzset function. */
#define HAVE_TZSET 1
+/* Define if you have the valloc function. */
+/* #undef HAVE_VALLOC */
+
+/* Define if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
/* Define if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define if you have the <signum.h> header file. */
/* #undef HAVE_SIGNUM_H */
+/* Define if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H 1
+
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
/* Define if you have the <strings.h> header file. */
/* #undef HAVE_STRINGS_H */
@@ -169,3 +186,5 @@
/* Define if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
+
+#include <custom.h> /* overrides for stuff autoconf can't deal with */
diff --git a/atari/gawkmisc.atr b/atari/gawkmisc.atr
index ef09b813..2a9fcb27 100644
--- a/atari/gawkmisc.atr
+++ b/atari/gawkmisc.atr
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-1993 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-1996 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Progamming Language.
diff --git a/awk.h b/awk.h
index 7e16a132..7ab23285 100644
--- a/awk.h
+++ b/awk.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-1995 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-1996 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -29,12 +29,17 @@
#include <config.h>
#endif
+#define _GNU_SOURCE 1 /* enable GNU extensions */
+
#include <stdio.h>
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif /* HAVE_LIMITS_H */
#include <ctype.h>
#include <setjmp.h>
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif /* HAVE_LOCALE_H */
#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
#include <stdarg.h>
#else
@@ -54,6 +59,36 @@ extern int errno;
/* This section is the messiest one in the file, not a lot that can be done */
+/* First, get the ctype stuff right; from Jim Meyering */
+#if defined(STDC_HEADERS) || (!defined(isascii) && !defined(HAVE_ISASCII))
+#define ISASCII(c) 1
+#else
+#define ISASCII(c) isascii(c)
+#endif
+
+#ifdef isblank
+#define ISBLANK(c) (ISASCII(c) && isblank(c))
+#else
+#define ISBLANK(c) ((c) == ' ' || (c) == '\t')
+#endif
+#ifdef isgraph
+#define ISGRAPH(c) (ISASCII(c) && isgraph(c))
+#else
+#define ISGRAPH(c) (ISASCII(c) && isprint(c) && !isspace(c))
+#endif
+
+#define ISPRINT(c) (ISASCII (c) && isprint (c))
+#define ISDIGIT(c) (ISASCII (c) && isdigit (c))
+#define ISALNUM(c) (ISASCII (c) && isalnum (c))
+#define ISALPHA(c) (ISASCII (c) && isalpha (c))
+#define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
+#define ISLOWER(c) (ISASCII (c) && islower (c))
+#define ISPUNCT(c) (ISASCII (c) && ispunct (c))
+#define ISSPACE(c) (ISASCII (c) && isspace (c))
+#define ISUPPER(c) (ISASCII (c) && isupper (c))
+#define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
+
+
#ifdef __STDC__
#define P(s) s
#define MALLOC_ARG_T size_t
@@ -121,6 +156,10 @@ lose
#endif /* not HAVE_DOPRNT */
#endif /* HAVE_VPRINTF */
+#ifndef HAVE_SETLOCALE
+#define setlocale(locale, val) /* nothing */
+#endif /* HAVE_SETLOCALE */
+
#ifdef VMS
#include "vms/redirect.h"
#endif /*VMS*/
@@ -292,7 +331,8 @@ typedef enum nodevals {
Node_OFS,
Node_ORS,
Node_OFMT,
- Node_CONVFMT
+ Node_CONVFMT,
+ Node_final /* sentry value, not legal */
} NODETYPE;
/*
@@ -364,9 +404,12 @@ typedef struct exp_node {
# define NUM 32 /* numeric value is current */
# define NUMBER 64 /* assigned as number */
# define MAYBE_NUM 128 /* user input: if NUMERIC then
- * a NUMBER */
+ * a NUMBER */
# define ARRAYMAXED 256 /* array is at max size */
# define SCALAR 512 /* used as scalar, can't be array */
+# define FUNC 1024 /* this parameter is really a
+ * function name; see awk.y */
+
char *vname; /* variable's name */
} NODE;
@@ -434,6 +477,8 @@ typedef struct iobuf {
# define IOP_IS_TTY 1
# define IOP_IS_INTERNAL 2
# define IOP_NO_FREE 4
+# define IOP_MMAPPED 8
+ int (*getrec)();
} IOBUF;
typedef void (*Func_ptr)();
@@ -473,9 +518,6 @@ struct src {
/* Return means return from a function call; leave value in ret_node */
#define TAG_RETURN 3
-#ifndef INT_MAX
-#define INT_MAX ((int)(~(1 << (sizeof (int) * 8 - 1))))
-#endif
#ifndef LONG_MAX
#define LONG_MAX ((long)(~(1L << (sizeof (long) * 8 - 1))))
#endif
@@ -741,6 +783,7 @@ extern int pathopen P((const char *file));
extern NODE *do_getline P((NODE *tree));
extern void do_nextfile P((void));
extern IOBUF *iop_alloc P((int fd, const char *name));
+extern struct redirect *getredirect P((char *str, int len));
/* main.c */
extern int main P((int argc, char **argv));
extern void load_environ P((void));
@@ -768,6 +811,7 @@ extern void fatal ();
#endif
/* node.c */
extern AWKNUM r_force_number P((NODE *n));
+extern NODE *format_val P((char *format, int index, NODE *s));
extern NODE *r_force_string P((NODE *s));
extern NODE *dupnode P((NODE *n));
extern NODE *mk_number P((AWKNUM x, unsigned int flags));
diff --git a/awk.y b/awk.y
index d4b443fa..f855f254 100644
--- a/awk.y
+++ b/awk.y
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-1995 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-1996 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -52,7 +52,8 @@ static NODE *make_param P((char *name));
static NODE *mk_rexp P((NODE *exp));
static int dup_parms P((NODE *func));
static void param_sanity P((NODE *arglist));
-static int isnoeffect P((NODETYPE));
+static int isnoeffect P((NODETYPE t));
+static int isassignable P((NODE *n));
enum defref { FUNC_DEFINE, FUNC_USE };
static void func_use P((char *name, enum defref how));
@@ -279,7 +280,11 @@ function_prologue
}
func_name '(' opt_param_list r_paren opt_nls
{
- $$ = append_right(make_param($3), $5);
+ NODE *t;
+
+ t = make_param($3);
+ t->flags |= FUNC;
+ $$ = append_right(t, $5);
can_return = TRUE;
/* check for duplicate parameter names */
if (dup_parms($$))
@@ -1002,7 +1007,6 @@ va_dcl
strcpy(bp, mesg);
err("", buf, args);
va_end(args);
- exit(2);
}
/* get_src_buf --- read the next buffer of source program */
@@ -1844,6 +1848,11 @@ NODE *subn;
r->proc = tokentab[idx].ptr;
/* special case processing for a few builtins */
+ /*
+ * FIXME: go through these to make sure that everything done
+ * here is really right. Move anything that's not into
+ * the corresponding routine.
+ */
if (nexp == 0 && r->proc == do_length) {
subn = node(node(make_number(0.0), Node_field_spec, (NODE *) NULL),
Node_expression_list,
@@ -1860,8 +1869,12 @@ NODE *subn;
(NODE *) NULL),
Node_expression_list,
(NODE *) NULL));
- else if (do_lint && subn->rnode->rnode->lnode->type == Node_val)
- warning("string literal as last arg of substitute");
+ else if (subn->rnode->rnode->lnode->type == Node_val) {
+ if (do_lint)
+ warning("string literal as last arg of substitute");
+ } else if (! isassignable(subn->rnode->rnode->lnode))
+ yyerror("%s third parameter is not a changeable object",
+ r->proc == do_sub ? "sub" : "gsub");
} else if (r->proc == do_gensub) {
if (subn->lnode->type != Node_regex)
subn->lnode = mk_rexp(subn->lnode);
@@ -2318,3 +2331,33 @@ NODETYPE type;
return FALSE;
}
+
+/* isassignable --- can this node be assigned to? */
+
+static int
+isassignable(n)
+register NODE *n;
+{
+ switch (n->type) {
+ case Node_var:
+ case Node_FIELDWIDTHS:
+ case Node_RS:
+ case Node_FS:
+ case Node_FNR:
+ case Node_NR:
+ case Node_NF:
+ case Node_IGNORECASE:
+ case Node_OFMT:
+ case Node_CONVFMT:
+ case Node_ORS:
+ case Node_OFS:
+ case Node_field_spec:
+ case Node_subscript:
+ return TRUE;
+ case Node_param_list:
+ return ((n->flags & FUNC) == 0); /* ok if not func name */
+ default:
+ break; /* keeps gcc -Wall happy */
+ }
+ return FALSE;
+}
diff --git a/awklib/ChangeLog b/awklib/ChangeLog
new file mode 100644
index 00000000..2fab5799
--- /dev/null
+++ b/awklib/ChangeLog
@@ -0,0 +1,13 @@
+Sun Oct 20 12:30:41 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (install): minor tweaks for portability.
+
+Fri Mar 15 06:33:38 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (pwcat, grcat): Add $(LDFLAGS).
+ (clean): add `*~' to list of files to be removed.
+
+Wed Jan 24 10:06:16 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (clean): Remove $(AUXAWK).
+ (maintainer-clean): Depend on distclean, not the other way around.
diff --git a/awklib/Makefile.in b/awklib/Makefile.in
index f5d1b95c..87209881 100644
--- a/awklib/Makefile.in
+++ b/awklib/Makefile.in
@@ -1,6 +1,6 @@
# Makefile for GNU Awk support library.
#
-# Copyright (C) 1995 the Free Software Foundation, Inc.
+# Copyright (C) 1995-1996 the Free Software Foundation, Inc.
#
# This file is part of GAWK, the GNU implementation of the
# AWK Programming Language.
@@ -56,10 +56,10 @@ stamp-eg: $(srcdir)/../doc/gawk.texi
@echo 'against a file, so this file is a place holder. gack.' >> stamp-eg
pwcat: $(srcdir)/eg/lib/pwcat.c
- $(CC) $(CFLAGS) $(srcdir)/eg/lib/pwcat.c -o $@
+ $(CC) $(CFLAGS) $(srcdir)/eg/lib/pwcat.c $(LDFLAGS) -o $@
grcat: $(srcdir)/eg/lib/grcat.c
- $(CC) $(CFLAGS) $(srcdir)/eg/lib/grcat.c -o $@
+ $(CC) $(CFLAGS) $(srcdir)/eg/lib/grcat.c $(LDFLAGS) -o $@
igawk: $(srcdir)/eg/prog/igawk.sh
cp $(srcdir)/eg/prog/igawk.sh $@ ; chmod 755 $@
@@ -73,12 +73,12 @@ group.awk: $(srcdir)/eg/lib/groupawk.in
sed 's;/usr/local/libexec/awk;$(libexecdir);' < groupawk.in) > group.awk
install: igawk $(AUXPROGS) $(AUXAWK)
- $(INSTALL_PROGRAM) igawk $(bindir)
+ $(INSTALL_PROGRAM) igawk $(bindir)/igawk && chmod 755 $(bindir)/igawk
for i in $(AUXPROGS) ; do \
- $(INSTALL_PROGRAM) $$i $(libexecdir) ; \
+ $(INSTALL_PROGRAM) $$i $(libexecdir)/$$i ; \
done
for i in $(AUXAWK) $(srcdir)/eg/lib/*.awk ; do \
- $(INSTALL_DATA) $$i $(datadir) ; \
+ $(INSTALL_DATA) $$i $(datadir)/$$i ; \
done
# libexecdir and bindir are removed in the top level Makefile's uninstall
@@ -87,10 +87,12 @@ uninstall:
rm -f $(bindir)/igawk
clean:
- rm -f $(AUXPROGS) igawk
-
-maintainer-clean: clean
- rm -fr eg stamp-eg
+ rm -f $(AUXPROGS) $(AUXAWK) igawk *~
distclean: clean
rm -f Makefile
+
+maintainer-clean: distclean
+ @echo "This command is intended for maintainers to use; it"
+ @echo "deletes files that may require special tools to rebuild."
+ rm -fr eg stamp-eg
diff --git a/awklib/eg/lib/mktime.awk b/awklib/eg/lib/mktime.awk
index 60c5b60d..f43d6d19 100644
--- a/awklib/eg/lib/mktime.awk
+++ b/awklib/eg/lib/mktime.awk
@@ -73,7 +73,7 @@ function mktime(str, res1, res2, a, b, i, j, t, diff)
a[3] < 1 || a[3] > 31 ||
a[4] < 0 || a[4] > 23 ||
a[5] < 0 || a[5] > 59 ||
- a[6] < 0 || a[6] > 61 )
+ a[6] < 0 || a[6] > 60 )
return -1
res1 = _tm_addup(a)
diff --git a/awklib/eg/lib/round.awk b/awklib/eg/lib/round.awk
new file mode 100644
index 00000000..d484e148
--- /dev/null
+++ b/awklib/eg/lib/round.awk
@@ -0,0 +1,32 @@
+# round --- do normal rounding
+#
+# Arnold Robbins, arnold@gnu.ai.mit.edu, August, 1996
+# Public Domain
+
+function round(x, ival, aval, fraction)
+{
+ ival = int(x) # integer part, int() truncates
+
+ # see if fractional part
+ if (ival == x) # no fraction
+ return x
+
+ if (x < 0) {
+ aval = -x # absolute value
+ ival = int(aval)
+ fraction = aval - ival
+ if (fraction >= .5)
+ return int(x) - 1 # -2.5 --> -3
+ else
+ return int(x) # -2.3 --> -2
+ } else {
+ fraction = x - ival
+ if (fraction >= .5)
+ return ival + 1
+ else
+ return ival
+ }
+}
+
+# test harness
+{ print $0, round($0) }
diff --git a/awklib/eg/prog/cut.awk b/awklib/eg/prog/cut.awk
index c69e6492..7c0da75e 100644
--- a/awklib/eg/prog/cut.awk
+++ b/awklib/eg/prog/cut.awk
@@ -92,7 +92,7 @@ function set_charlist( field, i, j, f, g, t,
if (index(f[i], "-") != 0) { # range
m = split(f[i], g, "-")
if (m != 2 || g[1] >= g[2]) {
- printf(bad character list: %s\n",
+ printf("bad character list: %s\n",
f[i]) > "/dev/stderr"
exit 1
}
diff --git a/awklib/eg/prog/wc.awk b/awklib/eg/prog/wc.awk
index e9898159..e5553116 100644
--- a/awklib/eg/prog/wc.awk
+++ b/awklib/eg/prog/wc.awk
@@ -27,7 +27,7 @@ BEGIN {
if (! do_lines && ! do_words && ! do_chars)
do_lines = do_words = do_chars = 1
- print_total = (ARC - i > 2)
+ print_total = (ARGC - i > 2)
}
function beginfile(file)
{
diff --git a/awklib/group.awk b/awklib/group.awk
deleted file mode 100644
index a8103a04..00000000
--- a/awklib/group.awk
+++ /dev/null
@@ -1,80 +0,0 @@
-# group.awk --- functions for dealing with the group file
-# Arnold Robbins, arnold@gnu.ai.mit.edu, Public Domain
-# May 1993
-
-BEGIN \
-{
- # Change to suit your system
- _gr_awklib = "/usr/local/libexec/awk/"
-}
-function _gr_init( oldfs, oldrs, olddol0, grcat, n, a, i)
-{
- if (_gr_inited)
- return
-
- oldfs = FS
- oldrs = RS
- olddol0 = $0
- FS = ":"
- RS = "\n"
-
- grcat = _gr_awklib "grcat"
- while ((grcat | getline) > 0) {
- if ($1 in _gr_byname)
- _gr_byname[$1] = _gr_byname[$1] "," $4
- else
- _gr_byname[$1] = $0
- if ($3 in _gr_bygid)
- _gr_bygid[$3] = _gr_bygid[$3] "," $4
- else
- _gr_bygid[$3] = $0
-
- n = split($4, a, "[ \t]*,[ \t]*")
- for (i = 1; i <= n; i++)
- if (a[i] in _gr_groupsbyuser)
- _gr_groupsbyuser[a[i]] = \
- _gr_groupsbyuser[a[i]] " " $1
- else
- _gr_groupsbyuser[a[i]] = $1
-
- _gr_bycount[++_gr_count] = $0
- }
- close(grcat)
- _gr_count = 0
- _gr_inited++
- FS = oldfs
- RS = oldrs
- $0 = olddol0
-}
-function getgrnam(group)
-{
- _gr_init()
- if (group in _gr_byname)
- return _gr_byname[group]
- return ""
-}
-function getgrgid(gid)
-{
- _gr_init()
- if (gid in _gr_bygid)
- return _gr_bygid[gid]
- return ""
-}
-function getgruser(user)
-{
- _gr_init()
- if (user in _gr_groupsbyuser)
- return _gr_groupsbyuser[user]
- return ""
-}
-function getgrent()
-{
- _gr_init()
- if (++gr_count in _gr_bycount)
- return _gr_bycount[_gr_count]
- return ""
-}
-function endgrent()
-{
- _gr_count = 0
-}
diff --git a/awklib/igawk.save b/awklib/igawk.save
deleted file mode 100755
index 87412aa8..00000000
--- a/awklib/igawk.save
+++ /dev/null
@@ -1,120 +0,0 @@
-#! /bin/sh
-
-# igawk --- like gawk but do @include processing
-# Arnold Robbins, arnold@gnu.ai.mit.edu, Public Domain
-# July 1993
-
-if [ "$1" = debug ]
-then
- set -x
- shift
-else
- # cleanup on exit, hangup, interrupt, quit, termination
- trap 'rm -f /tmp/ig.[se].$$' 0 1 2 3 15
-fi
-
-while [ $# -ne 0 ] # loop over arguments
-do
- case $1 in
- --) shift; break;;
-
- -W) shift
- set -- -W"$@"
- continue;;
-
- -[vF]) opts="$opts $1 '$2'"
- shift;;
-
- -[vF]*) opts="$opts '$1'" ;;
-
- -f) echo @include "$2" >> /tmp/ig.s.$$
- shift;;
-
- -f*) f=`echo "$1" | sed 's/-f//'`
- echo @include "$f" >> /tmp/ig.s.$$ ;;
-
- -?file=*) # -Wfile or --file
- f=`echo "$1" | sed 's/-.file=//'`
- echo @include "$f" >> /tmp/ig.s.$$ ;;
-
- -?file) # get arg, $2
- echo @include "$2" >> /tmp/ig.s.$$
- shift;;
-
- -?source=*) # -Wsource or --source
- t=`echo "$1" | sed 's/-.source=//'`
- echo "$t" >> /tmp/ig.s.$$ ;;
-
- -?source) # get arg, $2
- echo "$2" >> /tmp/ig.s.$$
- shift;;
-
- --*) opts="$opts '$1'" ;;
-
- *) break;;
- esac
-
- shift
-done
-
-if [ ! -s /tmp/ig.s.$$ ]
-then
- echo "$1" > /tmp/ig.s.$$
- shift
-fi
-
-# at this point, /tmp/ig.s.$$ has the program
-gawk -- '
-# process @include directives
-
-function pathto(file, i, t, junk)
-{
- if (index(file, "/") != 0)
- return file
-
- for (i = 1; i <= ndirs; i++) {
- t = (pathlist[i] "/" file)
- if ((getline junk < t) > 0) {
- # found it
- close(t)
- return t
- }
- }
- return ""
-}
-BEGIN {
- path = ENVIRON["AWKPATH"]
- ndirs = split(path, pathlist, ":")
- for (i = 1; i <= ndirs; i++) {
- if (pathlist[i] == "")
- pathlist[i] = "."
- }
- stackptr = 0
- input[stackptr] = ARGV[1] # ARGV[1] is first file
-
- for (; stackptr >= 0; stackptr--) {
- while ((getline < input[stackptr]) > 0) {
- if (tolower($1) != "@include") {
- print
- continue
- }
- fpath = pathto($2)
- if (fpath == "") {
- printf("igawk:%s:%d: cannot find %s\n", \
- input[stackptr], FNR, $2) > "/dev/stderr"
- continue
- }
- if (! (fpath in processed)) {
- processed[fpath] = input[stackptr]
- input[++stackptr] = fpath
- } else
- print $2, "included in", input[stackptr], \
- "already included in", \
- processed[fpath] > "/dev/stderr"
- }
- close(input[stackptr])
- }
-}' /tmp/ig.s.$$ > /tmp/ig.e.$$
-eval gawk -f /tmp/ig.e.$$ $opts -- "$@"
-
-exit $?
diff --git a/awklib/passwd.awk b/awklib/passwd.awk
deleted file mode 100644
index 7b64f60d..00000000
--- a/awklib/passwd.awk
+++ /dev/null
@@ -1,56 +0,0 @@
-# passwd.awk --- access password file information
-# Arnold Robbins, arnold@gnu.ai.mit.edu, Public Domain
-# May 1993
-
-BEGIN {
- # tailor this to suit your system
- _pw_awklib = "/usr/local/libexec/awk/"
-}
-
-function _pw_init( oldfs, oldrs, olddol0, pwcat)
-{
- if (_pw_inited)
- return
- oldfs = FS
- oldrs = RS
- olddol0 = $0
- FS = ":"
- RS = "\n"
- pwcat = _pw_awklib "pwcat"
- while ((pwcat | getline) > 0) {
- _pw_byname[$1] = $0
- _pw_byuid[$3] = $0
- _pw_bycount[++_pw_total] = $0
- }
- close(pwcat)
- _pw_count = 0
- _pw_inited = 1
- FS = oldfs
- RS = oldrs
- $0 = olddol0
-}
-function getpwnam(name)
-{
- _pw_init()
- if (name in _pw_byname)
- return _pw_byname[name]
- return ""
-}
-function getpwuid(uid)
-{
- _pw_init()
- if (uid in _pw_byuid)
- return _pw_byuid[uid]
- return ""
-}
-function getpwent()
-{
- _pw_init()
- if (_pw_count < _pw_total)
- return _pw_bycount[++_pw_count]
- return ""
-}
-function endpwent()
-{
- _pw_count = 0
-}
diff --git a/builtin.c b/builtin.c
index d6efd78d..b8fc58ff 100644
--- a/builtin.c
+++ b/builtin.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-1995 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-1996 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -29,16 +29,13 @@
#undef CHARBITS
#undef INTBITS
#include <math.h>
+#include "random.h"
-#ifndef HAVE_RANDOM
+/* can declare these, since we always use the random shipped with gawk */
extern char *initstate P((unsigned seed, char *state, int n));
extern char *setstate P((char *state));
extern long random P((void));
-#define SRANDOM_PROTO
-#endif
-#ifdef SRANDOM_PROTO
extern void srandom P((unsigned int seed));
-#endif
extern NODE **fields_arr;
extern int output_is_tty;
@@ -73,18 +70,10 @@ static void sgfmt P((char *buf, const char *format, int alt,
#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.
- * On SGI with 64 bit support (IRIX 6.*), check the size of _MIPS_SZLONG
- * and chop.... Per limits.h.
+ * Since we supply the version of random(), we know what
+ * value to use here.
*/
-#if (defined(__alpha) && defined(__osf__)) || defined(_CRAY) || (_MIPS_SZLONG == 64)
-#define GAWK_RANDOM_MAX (LONG_MAX & 0x7fffffff)
-#else
-#define GAWK_RANDOM_MAX LONG_MAX
-#endif
+#define GAWK_RANDOM_MAX 0x7fffffffL
static void efwrite P((const void *ptr, size_t size, size_t count, FILE *fp,
const char *from, struct redirect *rp, int flush));
@@ -166,7 +155,6 @@ NODE *
do_fflush(tree)
NODE *tree;
{
- extern struct redirect *getredirect();
struct redirect *rp;
NODE *tmp;
FILE *fp;
@@ -406,7 +394,6 @@ register NODE *carg;
long fw, prec;
int lj, alt, big, bigbig, small, have_prec, need_format;
long *cur = NULL;
- long val;
#ifdef sun386 /* Can't cast unsigned (int/long) from ptr->value */
long tmp_uval; /* on 386i 4.0.1 C compiler -- it just hangs */
#endif
@@ -425,9 +412,10 @@ register NODE *carg;
static char lchbuf[] = "0123456789abcdef";
static char Uchbuf[] = "0123456789ABCDEF";
- emalloc(obuf, char *, 120, "format_tree");
+#define INITIAL_OUT_SIZE 512
+ emalloc(obuf, char *, INITIAL_OUT_SIZE, "format_tree");
obufout = obuf;
- osiz = 120;
+ osiz = INITIAL_OUT_SIZE;
ofre = osiz - 1;
need_format = FALSE;
@@ -509,8 +497,17 @@ check_pos:
parse_next_arg();
*cur = force_number(arg);
free_temp(arg);
- if (cur == &prec)
+ if (*cur < 0 && cur == &fw) {
+ *cur = -*cur;
+ lj++;
+ }
+ if (cur == &prec) {
+ if (*cur >= 0)
+ have_prec = TRUE;
+ else
+ have_prec = FALSE;
cur = NULL;
+ }
goto retry;
case ' ': /* print ' ' or '-' */
/* 'space' flag is ignored */
@@ -588,6 +585,9 @@ check_pos:
case 'c':
need_format = FALSE;
parse_next_arg();
+ /* user input that looks numeric is numeric */
+ if ((arg->flags & (MAYBE_NUM|NUMBER)) == MAYBE_NUM)
+ (void) force_number(arg);
if (arg->flags & NUMBER) {
#ifdef sun386
tmp_uval = arg->numbr;
@@ -619,25 +619,18 @@ check_pos:
need_format = FALSE;
parse_next_arg();
tmpval = force_number(arg);
- /* this ugly cast fixes a (sunos) pcc problem. sigh. */
- if (tmpval > (double) ((unsigned long) ULONG_MAX)
- || tmpval < LONG_MIN) {
- /* out of range - emergency use of %g format */
- cs1 = 'g';
- goto format_float;
- }
- val = (long) tmpval;
-
- if (val < 0) {
+ if (tmpval < 0) {
+ if (tmpval < LONG_MIN)
+ goto out_of_range;
sgn = TRUE;
- if (val > LONG_MIN)
- uval = (unsigned long) -val;
- else
- uval = (unsigned long) (-(LONG_MIN + 1))
- + (unsigned long) 1;
+ uval = - (unsigned long) (long) tmpval;
} else {
+ /* Use !, so that NaNs are out of range.
+ The cast avoids a SunOS 4.1.x cc bug. */
+ if (! (tmpval <= (unsigned long) ULONG_MAX))
+ goto out_of_range;
sgn = FALSE;
- uval = (unsigned long) val;
+ uval = (unsigned long) tmpval;
}
do {
*--cp = (char) ('0' + uval % 10);
@@ -677,14 +670,17 @@ check_pos:
need_format = FALSE;
parse_next_arg();
tmpval = force_number(arg);
- /* this ugly cast fixes a (sunos) pcc problem. sigh. */
- if (tmpval > (double) ((unsigned long) ULONG_MAX)
- || tmpval < LONG_MIN) {
- /* out of range - emergency use of %g format */
- cs1 = 'g';
- goto format_float;
+ if (tmpval < 0) {
+ if (tmpval < LONG_MIN)
+ goto out_of_range;
+ uval = (unsigned long) (long) tmpval;
+ } else {
+ /* Use !, so that NaNs are out of range.
+ The cast avoids a SunOS 4.1.x cc bug. */
+ if (! (tmpval <= (unsigned long) ULONG_MAX))
+ goto out_of_range;
+ uval = (unsigned long) tmpval;
}
- uval = (unsigned long) tmpval;
/*
* precision overrides '0' flags. however, for
* integer formats, precsion is minimum number of
@@ -728,6 +724,12 @@ check_pos:
s0 = s1;
free_temp(arg);
break;
+
+ out_of_range:
+ /* out of range - emergency use of %g format */
+ cs1 = 'g';
+ goto format_float;
+
case 'g':
case 'G':
case 'e':
@@ -818,7 +820,16 @@ register NODE *tree;
struct redirect *rp = NULL;
register FILE *fp;
- if (tree->rnode) {
+ if (tree->lnode == NULL) {
+ if (do_traditional) {
+ if (do_lint)
+ warning("printf: no arguments");
+ return; /* bwk accepts it silently */
+ }
+ fatal("printf: no arguments");
+ }
+
+ if (tree->rnode != NULL) {
int errflg; /* not used, sigh */
rp = redirect(tree->rnode, &errflg);
@@ -862,36 +873,40 @@ NODE *tree;
NODE *r;
register int indx;
size_t length;
- int is_long;
t1 = force_string(tree_eval(tree->lnode));
t2 = tree_eval(tree->rnode->lnode);
- if (tree->rnode->rnode == NULL) /* third arg. missing */
- length = t1->stlen;
- else {
+ indx = (int) force_number(t2) - 1;
+ free_temp(t2);
+ if (indx < 0) {
+ if (do_lint)
+ warning("substr: start index %d invalid, using 1",
+ indx+1);
+ indx = 0; /* awk indices start at 1, C at 0 */
+ }
+ if (tree->rnode->rnode == NULL) { /* third arg. missing */
+ length = t1->stlen - indx; /* use remainder of string */
+ } else {
t3 = tree_eval(tree->rnode->rnode->lnode);
length = (size_t) force_number(t3);
free_temp(t3);
}
- indx = (int) force_number(t2) - 1;
- free_temp(t2);
- if (indx < 0)
- indx = 0;
+ if ((indx + length) > t1->stlen) {
+ if (do_lint)
+ warning(
+ "substr: length %d at position %d exceeds length of first argument (%d)",
+ length, indx+1, t1->stlen);
+ length = t1->stlen - indx;
+ }
if (indx >= t1->stlen || (long) length <= 0) {
if (do_lint && indx >= t1->stlen)
warning("substr: position %d is past end of string",
- indx);
+ indx+1);
if (do_lint && (long) length <= 0)
- warning("substr: length %d <= 0", (long) length);
+ warning("substr: length %d is <= 0", (long) length);
free_temp(t1);
return Nnull_string;
}
- if ((is_long = (indx + length > t1->stlen)) || LONG_MAX - indx < length) {
- length = t1->stlen - indx;
- if (do_lint && is_long)
- warning("substr: length %d at position %d exceeds length of first argument",
- length, indx+1);
- }
r = tmp_string(t1->stptr + indx, length);
free_temp(t1);
return r;
@@ -906,7 +921,9 @@ NODE *tree;
NODE *t1, *t2, *ret;
struct tm *tm;
time_t fclock;
- char buf[BUFSIZ]; /* XXX - fixed length */
+ char *bufp;
+ size_t buflen, bufsize;
+ char buf[BUFSIZ];
static char def_format[] = "%a %b %d %H:%M:%S %Z %Y";
char *format;
@@ -932,7 +949,21 @@ NODE *tree;
tm = localtime(&fclock);
- ret = tmp_string(buf, strftime(buf, 100, format, tm));
+ bufp = buf;
+ bufsize = sizeof(buf);
+ for (;;) {
+ buflen = strftime(bufp, bufsize, format, tm);
+ if (buflen > 0)
+ break;
+ bufsize *= 2;
+ if (bufp == buf)
+ emalloc(bufp, char *, bufsize, "do_strftime");
+ else
+ erealloc(bufp, char *, bufsize, "do_strftime");
+ }
+ ret = tmp_string(bufp, buflen);
+ if (bufp != buf)
+ free(bufp);
if (t1)
free_temp(t1);
return ret;
@@ -1002,10 +1033,11 @@ void
do_print(tree)
register NODE *tree;
{
- register NODE *t1;
+ register NODE **t;
struct redirect *rp = NULL;
register FILE *fp;
- register char *s;
+ int numnodes, i;
+ NODE *save;
if (tree->rnode) {
int errflg; /* not used, sigh */
@@ -1019,32 +1051,40 @@ register NODE *tree;
return;
} else
fp = stdout;
- tree = tree->lnode;
- while (tree != NULL) {
- t1 = tree_eval(tree->lnode);
- if (t1->flags & NUMBER) {
+
+ /*
+ * General idea is to evaluate all the expressions first and
+ * then print them, otherwise you get suprising behavior.
+ * See test/prtoeval.awk for an example program.
+ */
+ save = tree = tree->lnode;
+ for (numnodes = 0; tree != NULL; tree = tree->rnode)
+ numnodes++;
+ emalloc(t, NODE **, numnodes * sizeof(NODE *), "do_print");
+
+ tree = save;
+ for (i = 0; tree != NULL; i++, tree = tree->rnode) {
+ t[i] = tree_eval(tree->lnode);
+ if (t[i]->flags & NUMBER) {
if (OFMTidx == CONVFMTidx)
- (void) force_string(t1);
- else {
- free_temp(t1);
- t1 = format_tree(OFMT,
- fmt_list[OFMTidx]->stlen,
- tree);
- }
+ (void) force_string(t[i]);
+ else
+ t[i] = format_val(OFMT, OFMTidx, t[i]);
}
- efwrite(t1->stptr, sizeof(char), t1->stlen, fp, "print", rp, FALSE);
- free_temp(t1);
- tree = tree->rnode;
- if (tree != NULL) {
- s = OFS;
+ }
+
+ for (i = 0; i < numnodes; i++) {
+ efwrite(t[i]->stptr, sizeof(char), t[i]->stlen, fp, "print", rp, FALSE);
+ free_temp(t[i]);
+ if (i != numnodes - 1) {
if (OFSlen > 0)
- efwrite(s, sizeof(char), (size_t) OFSlen,
+ efwrite(OFS, sizeof(char), (size_t) OFSlen,
fp, "print", rp, FALSE);
}
}
- s = ORS;
if (ORSlen > 0)
- efwrite(s, sizeof(char), (size_t) ORSlen, fp, "print", rp, TRUE);
+ efwrite(ORS, sizeof(char), (size_t) ORSlen, fp, "print", rp, TRUE);
+ free(t);
}
/* do_tolower --- lower case a string */
@@ -1054,13 +1094,14 @@ do_tolower(tree)
NODE *tree;
{
NODE *t1, *t2;
- register char *cp, *cp2;
+ register unsigned char *cp, *cp2;
t1 = tree_eval(tree->lnode);
t1 = force_string(t1);
t2 = tmp_string(t1->stptr, t1->stlen);
- for (cp = t2->stptr, cp2 = t2->stptr + t2->stlen; cp < cp2; cp++)
- if (isupper(*cp))
+ for (cp = (unsigned char *)t2->stptr,
+ cp2 = (unsigned char *)(t2->stptr + t2->stlen); cp < cp2; cp++)
+ if (ISUPPER(*cp))
*cp = tolower(*cp);
free_temp(t1);
return t2;
@@ -1073,13 +1114,14 @@ do_toupper(tree)
NODE *tree;
{
NODE *t1, *t2;
- register char *cp;
+ register unsigned char *cp, *cp2;
t1 = tree_eval(tree->lnode);
t1 = force_string(t1);
t2 = tmp_string(t1->stptr, t1->stlen);
- for (cp = t2->stptr; cp < t2->stptr + t2->stlen; cp++)
- if (islower(*cp))
+ for (cp = (unsigned char *)t2->stptr,
+ cp2 = (unsigned char *)(t2->stptr + t2->stlen); cp < cp2; cp++)
+ if (ISLOWER(*cp))
*cp = toupper(*cp);
free_temp(t1);
return t2;
@@ -1211,6 +1253,65 @@ NODE *tree;
/* sub_common --- the common code (does the work) for sub, gsub, and gensub */
/*
+ * Gsub can be tricksy; particularly when handling the case of null strings.
+ * The following awk code was useful in debugging problems. It is too bad
+ * that it does not readily translate directly into the C code, below.
+ *
+ * #! /usr/local/bin/mawk -f
+ *
+ * BEGIN {
+ * TRUE = 1; FALSE = 0
+ * print "--->", mygsub("abc", "b+", "FOO")
+ * print "--->", mygsub("abc", "x*", "X")
+ * print "--->", mygsub("abc", "b*", "X")
+ * print "--->", mygsub("abc", "c", "X")
+ * print "--->", mygsub("abc", "c+", "X")
+ * print "--->", mygsub("abc", "x*$", "X")
+ * }
+ *
+ * function mygsub(str, regex, replace, origstr, newstr, eosflag, nonzeroflag)
+ * {
+ * origstr = str;
+ * eosflag = nonzeroflag = FALSE
+ * while (match(str, regex)) {
+ * if (RLENGTH > 0) { # easy case
+ * nonzeroflag = TRUE
+ * if (RSTART == 1) { # match at front of string
+ * newstr = newstr replace
+ * } else {
+ * newstr = newstr substr(str, 1, RSTART-1) replace
+ * }
+ * str = substr(str, RSTART+RLENGTH)
+ * } else if (nonzeroflag) {
+ * # last match was non-zero in length, and at the
+ * # current character, we get a zero length match,
+ * # which we don't really want, so skip over it
+ * newstr = newstr substr(str, 1, 1)
+ * str = substr(str, 2)
+ * nonzeroflag = FALSE
+ * } else {
+ * # 0-length match
+ * if (RSTART == 1) {
+ * newstr = newstr replace substr(str, 1, 1)
+ * str = substr(str, 2)
+ * } else {
+ * return newstr str replace
+ * }
+ * }
+ * if (length(str) == 0)
+ * if (eosflag)
+ * break;
+ * else
+ * eosflag = TRUE
+ * }
+ * if (length(str) > 0)
+ * newstr = newstr str # rest of string
+ *
+ * return newstr
+ * }
+ */
+
+/*
* NB: `howmany' conflicts with a SunOS macro in <sys/param.h>.
*/
@@ -1244,6 +1345,7 @@ int how_many, backdigs;
int global = (how_many == -1);
long current;
+ int lastmatchnonzero;
tmp = tree->lnode;
rp = re_update(tmp);
@@ -1298,7 +1400,7 @@ int how_many, backdigs;
ampersands++;
} else if (*scan == '\\') {
if (backdigs) { /* gensub, behave sanely */
- if (isdigit(scan[1])) {
+ if (ISDIGIT(scan[1])) {
ampersands++;
scan++;
} else { /* \q for any q --> q */
@@ -1325,6 +1427,7 @@ int how_many, backdigs;
}
}
+ lastmatchnonzero = FALSE;
bp = buf;
for (current = 1;; current++) {
matches++;
@@ -1347,6 +1450,15 @@ int how_many, backdigs;
*bp++ = *scan;
if (global || current == how_many) {
/*
+ * If the current match matched the null string,
+ * and the last match didn't and did a replacement,
+ * then skip this one.
+ */
+ if (lastmatchnonzero && matchstart == matchend) {
+ lastmatchnonzero = FALSE;
+ goto empty;
+ }
+ /*
* If replacing all occurrences, or this is the
* match we want, copy in the replacement text,
* making substitutions as we go.
@@ -1357,7 +1469,7 @@ int how_many, backdigs;
*bp++ = *cp;
else if (*scan == '\\') {
if (backdigs) { /* gensub, behave sanely */
- if (isdigit(scan[1])) {
+ if (ISDIGIT(scan[1])) {
int dig = scan[1] - '0';
char *start, *end;
@@ -1392,6 +1504,8 @@ int how_many, backdigs;
}
} else
*bp++ = *scan;
+ if (matchstart != matchend)
+ lastmatchnonzero = TRUE;
} else {
/*
* don't want this match, skip over it by copying
@@ -1400,6 +1514,7 @@ int how_many, backdigs;
for (cp = matchstart; cp < matchend; cp++)
*bp++ = *cp;
}
+ empty:
/* catch the case of gsub(//, "blah", whatever), i.e. empty regexp */
if (matchstart == matchend && matchend < text + textlen) {
*bp++ = *matchend;
@@ -1407,9 +1522,12 @@ int how_many, backdigs;
}
textlen = text + textlen - matchend;
text = matchend;
- if ((current >= how_many && !global) || (long) textlen <= 0
+
+ if ((current >= how_many && !global)
+ || ((long) textlen <= 0 && matchstart == matchend)
|| research(rp, t->stptr, text - t->stptr, textlen, TRUE) == -1)
break;
+
}
sofar = bp - buf;
if (buflen - sofar - textlen - 1) {
@@ -1486,7 +1604,7 @@ NODE *tree;
* We will then return the result string as the return value of
* this function.
*/
- target = tmp_string(tmp->stptr, tmp->stlen);
+ target = make_string(tmp->stptr, tmp->stlen);
free_temp(tmp);
n3 = *(n2.rnode->rnode);
@@ -1516,6 +1634,7 @@ NODE *tree;
* easiest thing for the programmer is to return the string, even
* if no substitutions were done.
*/
+ target->flags |= TEMP;
return target;
}
diff --git a/configh.in b/configh.in
index 02b92087..33c1371e 100644
--- a/configh.in
+++ b/configh.in
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 1995 the Free Software Foundation, Inc.
+ * Copyright (C) 1995, 96 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -66,6 +66,9 @@
/* Define if you don't have vprintf but do have _doprnt. */
#undef HAVE_DOPRNT
+/* Define if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
/* Define if your struct stat has st_blksize. */
#undef HAVE_ST_BLKSIZE
@@ -129,6 +132,12 @@
/* Define if you have the fmod function. */
#undef HAVE_FMOD
+/* Define if you have the getpagesize function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define if you have the madvise function. */
+#undef HAVE_MADVISE
+
/* Define if you have the memcmp function. */
#undef HAVE_MEMCMP
@@ -138,8 +147,8 @@
/* Define if you have the memset function. */
#undef HAVE_MEMSET
-/* Define if you have the random function. */
-#undef HAVE_RANDOM
+/* Define if you have the setlocale function. */
+#undef HAVE_SETLOCALE
/* Define if you have the strchr function. */
#undef HAVE_STRCHR
@@ -162,9 +171,15 @@
/* Define if you have the tzset function. */
#undef HAVE_TZSET
+/* Define if you have the valloc function. */
+#undef HAVE_VALLOC
+
/* Define if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
+/* Define if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
/* Define if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
@@ -186,4 +201,7 @@
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
+/* Define if you have the m library (-lm). */
+#undef HAVE_LIBM
+
#include <custom.h> /* overrides for stuff autoconf can't deal with */
diff --git a/configure b/configure
index 54eab6db..57c7250c 100755
--- a/configure
+++ b/configure
@@ -551,6 +551,26 @@ test -n "$YACC" && break
done
test -n "$YACC" || YACC="yacc"
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
@@ -641,7 +661,7 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
-#line 645 "configure"
+#line 665 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
@@ -655,7 +675,7 @@ else
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
-#line 659 "configure"
+#line 679 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
@@ -680,6 +700,10 @@ else
fi
echo "$ac_t""$CPP" 1>&6
+
+# This is a hack. Different versions of install on different systems
+# are just too different. Chuck it and use install-sh.
+INSTALL="$srcdir/install-sh -c"; export INSTALL
ac_aux_dir=
for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
if test -f $ac_dir/install-sh; then
@@ -758,6 +782,7 @@ test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
set dummy ${MAKE-make}; ac_make=$2
if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
@@ -798,7 +823,7 @@ fi
echo $ac_n "checking for AIX""... $ac_c" 1>&6
cat > conftest.$ac_ext <<EOF
-#line 802 "configure"
+#line 827 "configure"
#include "confdefs.h"
#ifdef _AIX
yes
@@ -845,7 +870,7 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 849 "configure"
+#line 874 "configure"
#include "confdefs.h"
#include <minix/config.h>
EOF
@@ -894,7 +919,7 @@ else
ac_cv_c_cross=yes
else
cat > conftest.$ac_ext <<EOF
-#line 898 "configure"
+#line 923 "configure"
#include "confdefs.h"
main(){return(0);}
EOF
@@ -911,12 +936,65 @@ fi
echo "$ac_t""$ac_cv_c_cross" 1>&6
cross_compiling=$ac_cv_c_cross
+echo $ac_n "checking whether the compiler ($CC $CFLAGS $LDFLAGS) actually works""... $ac_c" 1>&6
+
+ ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='echo $CPP $CPPFLAGS 1>&5;
+$CPP $CPPFLAGS'
+ac_compile='echo ${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5;
+${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5 2>&5'
+ac_link='echo ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5;
+${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5 2>&5'
+
+ if test "$cross_compiling" = yes; then
+ cat > conftest.$ac_ext <<EOF
+#line 953 "configure"
+#include "confdefs.h"
+
+int main() { return 0; }
+int t() {
+
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ am_cv_prog_cc_works=yes
+else
+ rm -rf conftest*
+ am_cv_prog_cc_works=no
+fi
+rm -f conftest*
+
+else
+cat > conftest.$ac_ext <<EOF
+#line 972 "configure"
+#include "confdefs.h"
+main() { exit(0); }
+EOF
+eval $ac_link
+if test -s conftest && (./conftest; exit) 2>/dev/null; then
+ am_cv_prog_cc_works=yes
+else
+ am_cv_prog_cc_works=no
+fi
+fi
+rm -fr conftest*
+
+case "$am_cv_prog_cc_works" in
+ *no) { echo "configure: error: Installation or configuration problem: C compiler cannot cr
+eate executables." 1>&2; exit 1; } ;;
+ *yes) ;;
+esac
+echo "$ac_t""yes" 1>&6
+
+
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 920 "configure"
+#line 998 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
@@ -938,7 +1016,7 @@ rm -f conftest*
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 942 "configure"
+#line 1020 "configure"
#include "confdefs.h"
#include <string.h>
EOF
@@ -956,7 +1034,7 @@ fi
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 960 "configure"
+#line 1038 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
@@ -977,7 +1055,7 @@ if test "$cross_compiling" = yes; then
:
else
cat > conftest.$ac_ext <<EOF
-#line 981 "configure"
+#line 1059 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1012,7 +1090,7 @@ if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1016 "configure"
+#line 1094 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/wait.h>
@@ -1048,7 +1126,7 @@ EOF
fi
-for ac_hdr in limits.h stdarg.h unistd.h signum.h sys/param.h string.h
+for ac_hdr in limits.h locale.h stdarg.h unistd.h signum.h sys/param.h string.h
do
ac_safe=`echo "$ac_hdr" | tr './\055' '___'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
@@ -1056,7 +1134,7 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1060 "configure"
+#line 1138 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
@@ -1094,7 +1172,7 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1098 "configure"
+#line 1176 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
@@ -1131,7 +1209,7 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1135 "configure"
+#line 1213 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
@@ -1166,7 +1244,7 @@ if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1170 "configure"
+#line 1248 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -1197,7 +1275,7 @@ if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1201 "configure"
+#line 1279 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <signal.h>
@@ -1237,7 +1315,7 @@ if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1241 "configure"
+#line 1319 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -1268,7 +1346,7 @@ if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1272 "configure"
+#line 1350 "configure"
#include "confdefs.h"
#include <sys/types.h>
EOF
@@ -1304,7 +1382,7 @@ else
ac_cv_type_getgroups=cross
else
cat > conftest.$ac_ext <<EOF
-#line 1308 "configure"
+#line 1386 "configure"
#include "confdefs.h"
/* Thanks to Mike Rendell for this test. */
@@ -1339,7 +1417,7 @@ fi
rm -fr conftest*
if test $ac_cv_type_getgroups = cross; then
cat > conftest.$ac_ext <<EOF
-#line 1343 "configure"
+#line 1421 "configure"
#include "confdefs.h"
#include <unistd.h>
EOF
@@ -1363,7 +1441,7 @@ EOF
cat > conftest.$ac_ext <<EOF
-#line 1367 "configure"
+#line 1445 "configure"
#include "confdefs.h"
#include <stdio.h>
EOF
@@ -1394,7 +1472,7 @@ if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1398 "configure"
+#line 1476 "configure"
#include "confdefs.h"
#include <alloca.h>
int main() { return 0; }
@@ -1426,7 +1504,7 @@ if eval "test \"`echo '$''{'ac_cv_func_alloca'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1430 "configure"
+#line 1508 "configure"
#include "confdefs.h"
#ifdef __GNUC__
@@ -1485,7 +1563,7 @@ if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1489 "configure"
+#line 1567 "configure"
#include "confdefs.h"
#if defined(CRAY) && ! defined(CRAY2)
webecray
@@ -1514,7 +1592,7 @@ if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1518 "configure"
+#line 1596 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -1568,7 +1646,7 @@ else
ac_cv_c_stack_direction=0
else
cat > conftest.$ac_ext <<EOF
-#line 1572 "configure"
+#line 1650 "configure"
#include "confdefs.h"
find_stack_direction ()
{
@@ -1614,7 +1692,7 @@ if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1618 "configure"
+#line 1696 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char vprintf(); below. */
@@ -1662,7 +1740,7 @@ if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1666 "configure"
+#line 1744 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char _doprnt(); below. */
@@ -1707,14 +1785,55 @@ fi
fi
-for ac_func in memset memcpy memcmp fmod random strchr strerror strftime strncasecmp strtod system tzset
+echo $ac_n "checking for -lm""... $ac_c" 1>&6
+ac_lib_var=`echo m | tr '.-/+' '___p'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lm $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1797 "configure"
+#include "confdefs.h"
+
+int main() { return 0; }
+int t() {
+fmod()
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo m | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lm $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+for ac_func in madvise memset memcpy memcmp fmod setlocale strchr strerror \
+ strftime strncasecmp strtod system tzset
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1718 "configure"
+#line 1837 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -1759,6 +1878,153 @@ fi
done
+for ac_func in valloc getpagesize
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1889 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+char $ac_func();
+
+int main() { return 0; }
+int t() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for working mmap""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_func_mmap'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_mmap=no
+else
+cat > conftest.$ac_ext <<EOF
+#line 1941 "configure"
+#include "confdefs.h"
+
+/* Thanks to Mike Haertel and Jim Avera for this test. */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#ifndef HAVE_GETPAGESIZE
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif
+# else
+# ifdef NBPC
+# define getpagesize() NBPC
+# else
+# define getpagesize() PAGESIZE /* SVR4 */
+# endif
+# endif
+# endif
+#endif
+
+#ifndef HAVE_VALLOC
+# define valloc malloc
+#endif
+
+#ifdef __cplusplus
+extern "C" { void *valloc(unsigned), *malloc(unsigned); }
+#else
+char *valloc(), *malloc();
+#endif
+
+int
+main()
+{
+ char *buf1, *buf2, *buf3;
+ int i = getpagesize(), j;
+ int i2 = i * 2;
+ int fd;
+
+ buf1 = (char *)valloc(i2);
+ buf2 = (char *)valloc(i);
+ buf3 = (char *)malloc(i2);
+ for (j = 0; j < i2; ++j)
+ *(buf1 + j) = rand();
+ fd = open("conftestmmap", O_CREAT | O_RDWR, 0666);
+ write(fd, buf1, i2);
+ mmap(buf2, i, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, fd, 0);
+ for (j = 0; j < i; ++j)
+ if (*(buf1 + j) != *(buf2 + j))
+ exit(1);
+ lseek(fd, (long)i, 0);
+ read(fd, buf2, i); /* read into mapped memory -- file should not change */
+ /* (it does in i386 SVR4.0 - Jim Avera, jima@netcom.com) */
+ lseek(fd, (long)0, 0);
+ read(fd, buf3, i2);
+ for (j = 0; j < i2; ++j)
+ if (*(buf1 + j) != *(buf3 + j))
+ exit(1);
+ exit(0);
+}
+
+EOF
+eval $ac_link
+if test -s conftest && (./conftest; exit) 2>/dev/null; then
+ ac_cv_func_mmap=yes
+else
+ ac_cv_func_mmap=no
+fi
+fi
+rm -fr conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_mmap" 1>&6
+if test $ac_cv_func_mmap = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_MMAP 1
+EOF
+
+fi
+
+
echo $ac_n "checking whether getpgrp takes no argument""... $ac_c" 1>&6
if eval "test \"`echo '$''{'ac_cv_func_getpgrp_void'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -1767,7 +2033,7 @@ else
{ echo "configure: error: cannot check getpgrp if cross compiling" 1>&2; exit 1; }
else
cat > conftest.$ac_ext <<EOF
-#line 1771 "configure"
+#line 2037 "configure"
#include "confdefs.h"
/*
@@ -1847,7 +2113,7 @@ if eval "test \"`echo '$''{'ac_cv_struct_st_blksize'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1851 "configure"
+#line 2117 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -1880,7 +2146,7 @@ if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1884 "configure"
+#line 2150 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/time.h>
@@ -1914,7 +2180,7 @@ if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1918 "configure"
+#line 2184 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <time.h>
@@ -1947,7 +2213,7 @@ if eval "test \"`echo '$''{'ac_cv_struct_tm_zone'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1951 "configure"
+#line 2217 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <$ac_cv_struct_tm>
@@ -1979,7 +2245,7 @@ if eval "test \"`echo '$''{'ac_cv_var_tzname'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1983 "configure"
+#line 2249 "configure"
#include "confdefs.h"
#include <time.h>
#ifndef tzname /* For SGI. */
@@ -2018,7 +2284,7 @@ else
if test "$GCC" = yes; then
# GCC predefines this symbol on systems where it applies.
cat > conftest.$ac_ext <<EOF
-#line 2022 "configure"
+#line 2288 "configure"
#include "confdefs.h"
#ifdef __CHAR_UNSIGNED__
yes
@@ -2040,7 +2306,7 @@ if test "$cross_compiling" = yes; then
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
else
cat > conftest.$ac_ext <<EOF
-#line 2044 "configure"
+#line 2310 "configure"
#include "confdefs.h"
/* volatile prevents gcc2 from optimizing the test away on sparcs. */
#if !defined(__STDC__) || __STDC__ != 1
@@ -2074,7 +2340,7 @@ if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2078 "configure"
+#line 2344 "configure"
#include "confdefs.h"
int main() { return 0; }
@@ -2150,7 +2416,7 @@ if eval "test \"`echo '$''{'gawk_cv_c_stringize'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2154 "configure"
+#line 2420 "configure"
#include "confdefs.h"
#define x(y) #y
@@ -2298,6 +2564,7 @@ s%@oldincludedir@%$oldincludedir%g
s%@infodir@%$infodir%g
s%@mandir@%$mandir%g
s%@YACC@%$YACC%g
+s%@LN_S@%$LN_S%g
s%@CC@%$CC%g
s%@CPP@%$CPP%g
s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
diff --git a/configure.in b/configure.in
index 735bc575..c92e6425 100644
--- a/configure.in
+++ b/configure.in
@@ -1,7 +1,7 @@
dnl
dnl configure.in --- autoconf input file for gawk
dnl
-dnl Copyright (C) 1995 the Free Software Foundation, Inc.
+dnl Copyright (C) 1995, 96 the Free Software Foundation, Inc.
dnl
dnl This file is part of GAWK, the GNU implementation of the
dnl AWK Programming Language.
@@ -33,9 +33,15 @@ AC_CONFIG_HEADER(config.h:configh.in)
dnl checks for programs
AC_PROG_YACC
+AC_PROG_LN_S
AC_PROG_CC
AC_PROG_CPP
+
+# This is a hack. Different versions of install on different systems
+# are just too different. Chuck it and use install-sh.
+INSTALL="$srcdir/install-sh -c"; export INSTALL
AC_PROG_INSTALL
+
AC_PROG_MAKE_SET
if test "$CFLAGS" = ""
@@ -56,10 +62,13 @@ AC_AIX
AC_ISC_POSIX
AC_MINIX
+dnl see if the C compiler really works
+AM_SANITY_CHECK_CC
+
dnl checks for header files
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS(limits.h stdarg.h unistd.h signum.h sys/param.h string.h)
+AC_CHECK_HEADERS(limits.h locale.h stdarg.h unistd.h signum.h sys/param.h string.h)
if test "$ac_cv_header_string_h" = yes
then
AC_CHECK_HEADERS(memory.h)
@@ -85,7 +94,12 @@ fi
AC_DEFINE(REGEX_MALLOC)
AC_FUNC_VPRINTF
-AC_CHECK_FUNCS(memset memcpy memcmp fmod random strchr strerror strftime strncasecmp strtod system tzset)
+AC_CHECK_LIB(m, fmod)
+AC_CHECK_FUNCS(madvise memset memcpy memcmp fmod setlocale strchr strerror \
+ strftime strncasecmp strtod system tzset)
+
+dnl see if we have mmap
+AC_FUNC_MMAP
dnl check for how to use getpgrp
AC_FUNC_GETPGRP
diff --git a/custom.h b/custom.h
index 051ab206..57f2724d 100644
--- a/custom.h
+++ b/custom.h
@@ -11,7 +11,7 @@
*/
/*
- * Copyright (C) 1995 the Free Software Foundation, Inc.
+ * Copyright (C) 1995, 96 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -37,7 +37,13 @@
#undef HAVE_STRERROR
#endif
+/* for VMS POSIX, from Pat Rankin, rankin@eql.caltech.edu */
#ifdef VMS_POSIX
#undef VMS
#include "vms/redirect.h"
#endif
+
+/* For QNX, based on submission from Michael Hunter, mphunter@qnx.com */
+#ifdef __QNX__
+#define GETPGRP_VOID 1
+#endif
diff --git a/dfa.c b/dfa.c
index 958d9aa8..799670df 100644
--- a/dfa.c
+++ b/dfa.c
@@ -482,12 +482,12 @@ lex()
case '`':
if (backslash && !(syntax_bits & RE_NO_GNU_OPS))
- return lasttok = BEGLINE; /* XXX should be beginning of string */
+ return lasttok = BEGLINE; /* FIXME: should be beginning of string */
goto normal_char;
case '\'':
if (backslash && !(syntax_bits & RE_NO_GNU_OPS))
- return lasttok = ENDLINE; /* XXX should be end of string */
+ return lasttok = ENDLINE; /* FIXME: should be end of string */
goto normal_char;
case '<':
diff --git a/doc/ChangeLog b/doc/ChangeLog
new file mode 100644
index 00000000..ee017484
--- /dev/null
+++ b/doc/ChangeLog
@@ -0,0 +1,48 @@
+Mon Dec 9 12:48:54 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * no.colors: new file from Michal for old troffs.
+ * Makefile.in [AWKCARD]: changes to parameterize old/new troff.
+
+Sun Dec 1 15:04:56 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * texinfo.tex: Updated to version 2.193, from Karl Berry.
+
+Tue Nov 26 22:57:15 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in ($(infodir)/gawk.info): Change option in call
+ to `install-info' to `--info-dir' from `--infodir'.
+
+Mon Nov 4 13:30:39 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in: updates for reference card.
+ (ad.block, awkcard.in, cardfonts, colors, macros, setter.outline):
+ new files for reference card.
+
+Wed Oct 16 12:43:02 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * texinfo.tex: Updated to version 2.185, from texinfo-3.9 dist.
+
+Sun Aug 11 23:12:08 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in ($(infodir)/gawk.info): correct use of
+ $(INSTALL_DATA) and remove chmod command.
+
+Thu Jul 11 22:06:50 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in ($(mandir)/gawk.$(ext), $(mandir)/igawk.$(ext)):
+ made dependant on files in $(srcdir).
+
+Fri Mar 15 06:45:35 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (clean): add `*~' to list of files to be removed.
+
+Thu Jan 25 23:40:15 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (dvi): run texindex and tex an extra time.
+ This gets the cross references right. Sigh.
+
+Wed Jan 24 11:51:54 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (maintainer-clean):
+ Depend on distclean, not the other way around.
+ Output warning message as per GNU standards.
diff --git a/doc/Makefile.in b/doc/Makefile.in
index 93278178..d634020e 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -1,6 +1,6 @@
# Makefile for GNU Awk documentation.
#
-# Copyright (C) 1993-1995 the Free Software Foundation, Inc.
+# Copyright (C) 1993-1996 the Free Software Foundation, Inc.
#
# This file is part of GAWK, the GNU implementation of the
# AWK Programming Language.
@@ -41,14 +41,31 @@ infodir = @infodir@
datadir = @datadir@/awk
TEXI2DVI = texi2dvi
+TEX = tex
MAKEINFO = makeinfo --no-split
+TROFF = groff -t -Tps
+SEDME = sed -e "s/^level0 restore/level0 restore flashme 100 72 moveto (Copyright `date '+%m-%d-%y %T'`, FSF, Inc. (all)) show/" \
+ -e "s/^\/level0 save def/\/level0 save def 30 -48 translate/"
DOCS= gawk.1 igawk.1 gawk.texi
TEXFILES= gawk.aux gawk.cp gawk.cps gawk.fn gawk.fns gawk.ky gawk.kys \
gawk.pg gawk.pgs gawk.toc gawk.tp gawk.tps gawk.vr gawk.vrs
-ALLDOC= gawk.dvi $(TEXFILES)
+ALLDOC= gawk.dvi $(TEXFILES) gawk.log awkcard.tr
+
+CARDSRC = $(srcdir)/macros $(srcdir)/cardfonts $(srcdir)/colors awkcard.tr
+CARDSRC_N = $(srcdir)/macros $(srcdir)/cardfonts $(srcdir)/no.colors awkcard.tr
+CARDFILES= $(CARDSRC) ad.block awkcard.in setter.outline
+
+# Use this if your troff can correctly handle macros from 'colors' file
+AWKCARD = awkcard.ps
+
+# Uncomment the following definition of AWKCARD if your troff can produce
+# Postscript but still has troubles with macros from 'colors'. As this
+# is not groff you will have to change TROFF macro as well. Do not forget
+# to ensure that awkcard.tr is processed by tbl.
+#AWKCARD = awkcard.nc
all: $(DOCS) info
@@ -58,18 +75,17 @@ $(infodir)/gawk.info: gawk.info
-if test -f gawk.info; then d=.; \
else d=$(srcdir); fi; \
for i in $$d/gawk.info*; do \
- $(INSTALL_DATA) $$i $(infodir) ; \
+ $(INSTALL_DATA) $$i $(infodir)/$i ; \
done; \
- chmod 644 $(infodir)/gawk.info* ; \
if $(SHELL) -c 'install-info --version' > /dev/null 2>&1 ; \
then install-info --infodir=$(infodir) gawk.info ; \
else true ; fi
$(mandir)/gawk$(manext): gawk.1
- $(INSTALL_DATA) gawk.1 $(mandir)/gawk$(manext) && chmod 644 $(mandir)/gawk$(manext)
+ $(INSTALL_DATA) $(srcdir)/gawk.1 $(mandir)/gawk$(manext) && chmod 644 $(mandir)/gawk$(manext)
$(mandir)/igawk$(manext): igawk.1
- $(INSTALL_DATA) igawk.1 $(mandir)/igawk$(manext) && chmod 644 $(mandir)/igawk$(manext)
+ $(INSTALL_DATA) $(srcdir)/igawk.1 $(mandir)/igawk$(manext) && chmod 644 $(mandir)/igawk$(manext)
uninstall:
rm -f $(mandir)/gawk$(manext) $(mandir)/igawk$(manext) $(infodir)/gawk.info*
@@ -77,23 +93,36 @@ uninstall:
dvi: gawk.dvi
gawk.dvi: gawk.texi
- TEXINPUTS=$$TEXINPUTS:$(srcdir) $(TEXI2DVI) gawk.texi
+ -TEXINPUTS=$$TEXINPUTS:$(srcdir) $(TEXI2DVI) gawk.texi
+ texindex gawk.??
+ TEXINPUTS=$$TEXINPUTS:$(srcdir) $(TEX) gawk.texi
info: gawk.info
gawk.info: gawk.texi
$(MAKEINFO) gawk.texi
-postscript: dvi gawk.1 igawk.1
+postscript: dvi gawk.1 igawk.1 $(AWKCARD)
-groff -man gawk.1 > gawk.1.ps
-groff -man igawk.1 > igawk.1.ps
dvips -o gawk.ps gawk.dvi
-clean:
- rm -f *.ps $(ALLDOC) gawk.log
+awkcard.tr: awkcard.in
+ sed 's/SRCDIR/$(srcdir)/' < $(srcdir)/awkcard.in > awkcard.tr
-maintainer-clean: clean
- rm -f gawk.info
+awkcard.ps: $(CARDFILES)
+ $(TROFF) $(CARDSRC) | $(SEDME) | cat $(srcdir)/setter.outline - > awkcard.ps
-distclean: maintainer-clean
+awkcard.nc: $(CARDFILES)
+ $(TROFF) $(CARDSRC_N) | $(SEDME) | cat $(srcdir)/setter.outline - > awkcard.ps && touch awkcard.nc
+
+clean:
+ rm -f *.ps $(ALLDOC) *~ awkcard.nc
+
+distclean: clean
rm -f Makefile
+
+maintainer-clean: distclean
+ @echo "This command is intended for maintainers to use; it"
+ @echo "deletes files that may require special tools to rebuild."
+ rm -f gawk.info
diff --git a/doc/README.card b/doc/README.card
new file mode 100644
index 00000000..ef77cdac
--- /dev/null
+++ b/doc/README.card
@@ -0,0 +1,19 @@
+Mon Dec 9 12:45:48 EST 1996
+
+The AWK reference card included here requires a modern version of troff
+(ditroff). GNU Troff (groff) is known to work.
+
+If your troff is able to produce Postscript but does not know how to
+properly use the macros from `colors' file then try to uncomment in
+Makefile the defintion which sets AWKCARD to awkcard.nc (no colors).
+This will definitely require changes to the TROFF macro and you have to
+ensure that the tbl preprocessor is called. For example, the following
+modifications on NeXT:
+
+TROFF = tbl
+SEDME = ptroff -t | sed -e \
+ "s/^level0 restore/level0 restore flashme 100 72 moveto\
+ (Copyright `date`, FSF, Inc. (all)) show/" \
+ -e "s/^\/level0 save def/\/level0 save def 30 -48 translate/"
+
+will produce a correctly formatted, albeit monochromatic, reference card.
diff --git a/doc/ad.block b/doc/ad.block
new file mode 100644
index 00000000..16a4de0f
--- /dev/null
+++ b/doc/ad.block
@@ -0,0 +1,48 @@
+.\" AWK Reference Card --- Arnold Robbins, arnold@gnu.ai.mit.edu
+.\" This file is the Ad block (included in cover)
+.\"
+.\" Copyright (C) 1996 Free Software Foundation, Inc.
+.\"
+.\" Permission is granted to make and distribute verbatim copies of
+.\" this reference card provided the copyright notice and this permission
+.\" notice are preserved on all copies.
+.\"
+.\" Permission is granted to process this file through troff and print the
+.\" results, provided the printed document carries copying permission
+.\" notice identical to this one except for the removal of this paragraph
+.\" (this paragraph not being relevant to the printed reference card).
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" reference card under the conditions for verbatim copying, provided that
+.\" the entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one.
+.\"
+.\" Permission is granted to copy and distribute translations of this
+.\" reference card into another language, under the above conditions for
+.\" modified versions, except that this permission notice may be stated in
+.\" a translation approved by the Foundation.
+.\"
+.ft HB
+.ps 10
+.vs 12
+.ES
+.nf
+.ce 6
+\*(CBFree Software Foundation, Inc.
+.ft H
+59 Temple Place \(em Suite 330
+Boston, MA 02111-1307 USA
+Phone: +1-617-542-5942
+Fax (including Japan): +1-617-542-2652
+E-mail: gnu@prep.ai.mit.edu
+
+.ce 7
+.ft HB
+\*(CGFree Software
+Source Distributions on CD-ROM
+Deluxe Distributions
+Emacs, Gawk, Make and GDB Manuals
+Emacs and GDB References\*(CX
+.EB "\f(HBOTHER FSF PRODUCTS:\*(FR"
+.ps
+.vs
diff --git a/doc/awkcard.in b/doc/awkcard.in
new file mode 100644
index 00000000..50af4aae
--- /dev/null
+++ b/doc/awkcard.in
@@ -0,0 +1,1353 @@
+.\" AWK Reference Card --- Arnold Robbins, arnold@gnu.ai.mit.edu
+.\"
+.\" Copyright (C) 1996 Free Software Foundation, Inc.
+.\"
+.\" Permission is granted to make and distribute verbatim copies of
+.\" this reference card provided the copyright notice and this permission
+.\" notice are preserved on all copies.
+.\"
+.\" Permission is granted to process this file through troff and print the
+.\" results, provided the printed document carries copying permission
+.\" notice identical to this one except for the removal of this paragraph
+.\" (this paragraph not being relevant to the printed reference card).
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" reference card under the conditions for verbatim copying, provided that
+.\" the entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one.
+.\"
+.\" Permission is granted to copy and distribute translations of this
+.\" reference card into another language, under the above conditions for
+.\" modified versions, except that this permission notice may be stated in
+.\" a translation approved by the Foundation.
+.\"
+.\" Strings to save typing
+.ds AK \*(FCawk\*(FR
+.ds GK \*(FCgawk\*(FR
+.ds NK Bell Labs \*(FCawk\*(FR
+.ds MK \*(FCmawk\*(FR
+.\"
+.\"
+
+
+.sp
+.ce
+\*(CD\f(HB\s+8AWK REFERENCE\s0\*(FR
+.sp
+.\" --- Table Of Contents
+.ta 2.4i 2.6iR
+.lc .
+.ES
+.in +.2i
+.nf
+\*(FRAWK Program Execution 4
+Action Statements 7
+Arrays 9
+Bug Reports 15
+Command Line Arguments (standard) 2
+Command Line Arguments (\*(GK) 3
+Command Line Arguments (\*(MK) 4
+Conversions And Comparisons 10
+Copying Permissions 16
+Definitions 2
+Environment Variables (\*(GK) 16
+Escape Sequences 7
+Expressions 9
+Fields 6
+FTP Information 16
+Historical Features 16
+Input Control 11
+Lines And Statements 5
+.ig
+Localization 10
+..
+Numeric Functions 13
+Output Control 11
+Pattern Elements 7
+POSIX Character Classes (\*(GK) 6
+Printf Formats 12
+Records 6
+Regular Expressions 5
+Special Filenames 13
+String Functions 14
+Time Functions 15
+User-defined Functions 15
+Variables 8\*(CX
+.in -.2i
+.EB "\s+2\f(HBCONTENTS\*(FR\s0"
+.sp
+.ta .2i .78i 1i 1.2i 1.4i 1.7i
+.fi
+\*(CD\*(FRThis reference card was written by Arnold Robbins.
+Brian Kernighan and Michael Brennan reviewed it; we thank them
+them for their help.
+.sp
+.SL
+.sp
+.so SRCDIR/ad.block
+.\" a subtlety here; this line changes color. We rely on it
+.\" also to provide a blank line.
+\*(CD
+.SL
+.nf
+\*(FR\(co Copyright, 1996 Free Software Foundation
+59 Temple Place \(em Suite 330
+Boston, MA 02111-1307 USA
+.nf
+.BT
+
+
+.\"
+.\"
+.\" --- Definitions
+.fi
+.ES
+\*(CDThis card describes POSIX AWK, as well as the three
+freely available \*(AK implementations
+(see \fHFTP Information\fP, below).
+\*(CLCommon extensions (in two or more versions) are printed in light blue.
+\*(CBFeatures specific to just one version\(emusually GNU AWK (\*(GK)\(emare
+printed in dark blue.
+\*(CRExceptions and deprecated features are printed in red.
+\*(CDFeatures mandated by POSIX are printed in black.
+.sp .5
+Several type faces are used to clarify the meaning:
+.br
+\(bu \*(FC\*(CN\fP is used for computer input.
+.br
+\(bu\|\^\*(FI\*(IN\fP is used to indicate user input and for syntactic
+.br
+\0\|\^placeholders, such as \*(FIvariable\fP or \*(FIaction\fP.
+.br
+\(bu \*(RN is used for explanatory text.
+.sp .5
+\*(FInumber\fP \- a floating point number as in ANSI C, such as
+\*(FC3\*(FR,
+\*(FC2.3\*(FR,
+\*(FC.4\*(FR,
+\*(FC1.4e2\*(FR,
+or
+\*(FC4.1E5\*(FR.
+.sp .5
+\*(FIescape sequences\fP \- a special sequence of characters beginning
+with a backslash, used to describe otherwise unprintable characters.
+See \fHEscape Sequences\fP, below.
+.sp .5
+\*(FIstring\fP \- a group of characters enclosed in double quotes.
+Strings may contain \*(FIescape sequences\*(FR.
+.sp .5
+\*(FIregexp\fP \- a regular expression, either a regexp constant
+enclosed in forward slashes, or a dynamic regexp computed at run-time.
+Regexp constants may contain \*(FIescape sequences\*(FR.
+.sp .5
+\*(FIname\fP \- a variable, array, or function name.
+.sp .5
+\*(FIentry\fP(\*(FIN\fP) \- entry \*(FIentry\fP in section \*(FIN\fP of the
+UNIX reference manual.
+.sp .5
+\*(FIpattern\fP \- an expression describing an input record to be matched.
+.sp .5
+\*(FIaction\fP \- statements to execute when an input record is matched.
+.sp .5
+\*(FIrule\fP \- a pattern-action pair, where the pattern or action may
+be missing.\*(CX
+.EB \s+2\f(HBDEFINITIONS\*(FR\s0
+
+
+.\" --- Command Line Arguments
+.ES
+.fi
+\*(CDCommand line arguments control setting the field separator,
+setting variables before the \*(FCBEGIN\fP rule is run, and
+the location of AWK program source code.
+Implementation-specific command line arguments change
+the behaviour of the running interpreter.
+.sp .5
+.nf
+\*(FC\-F \*(FIfs\*(FR use \*(FIfs\fP for the input field separator
+\*(FC\-v\*(FI var\*(FC\^=\^\*(FIval\*(FR assign the value \*(FIval\*(FR, to the variable \*(FIvar\*(FR,
+ before execution of the program begins. Such
+ variable values are available to the \*(FCBEGIN\fP rule
+\*(FC\-f \*(FIprog-file\*(FR read the AWK program source from the file
+ \*(FIprog-file\*(FR, instead of from the first command
+ line argument. Multiple \*(FC\-f\*(FR options may be used
+\*(FC\-\^\-\*(FR signal the end of options
+.sp .5
+.fi
+\*(CLThe following options are accepted by both \*(NK and \*(GK
+\*(CR(ignored by \*(GK, not in \*(MK).\*(CL
+.sp .5
+.nf
+\*(FC\-mf \*(FIval\*(FR set the maximum number of fields to \*(FIval\fP
+\*(FC\-mr \*(FIval\*(FR set the maximum record size to \*(FIval\fP\*(CX
+.EB "\s+2\f(HBCOMMAND LINE ARGUMENTS (standard)\*(FR\s0"
+
+.BT
+
+
+
+.ES
+.fi
+\*(CDThe following options are specific to \*(GK. The \*(FC\-W\*(FR
+forms are for full POSIX compliance.
+.sp .5
+.nf
+\*(FC\-\^\-field-separator \*(FIfs\*(FR
+ just like \*(FC\-F\fP
+\*(FC\-\^\-assign \*(FIvar\*(FC\^=\^\*(FIval\*(FR just like \*(FC\-v\fP
+\*(FC\-\^\-file \*(FIprog-file \*(FRjust like \*(FC\-f\fP
+\*(FC\-\^\-traditional\*(FR
+\*(FC\-\^\-compat\*(FR
+\*(FC\-W compat\*(FR
+\*(FC\-W traditional\*(FR turn off \*(GK-specific extensions
+ (\*(FC\-\^\-traditional\*(FR preferred)
+\*(FC\-\^\-copyleft\*(FR
+\*(FC\-\^\-copyright\*(FR
+\*(FC\-W copyleft\*(FR
+\*(FC\-W copyright\*(FR print the short version of the GNU
+ copyright information on \*(FCstdout\*(FR
+\*(FC\-\^\-help\*(FR
+\*(FC\-\^\-usage\*(FR
+\*(FC\-W help\*(FR
+\*(FC\-W usage\*(FR Print a short summary of the available
+ options on \*(FCstdout\*(FR, then exit zero
+\*(FC\-\^\-lint\*(FR
+\*(FC\-W lint\*(FR warn about constructs that are dubious
+ or non-portable to other \*(AKs
+\*(FC\-\^\-lint\-old\*(FR
+\*(FC\-W lint\-old\*(FR warn about constructs that are not
+ portable to the original version of
+ Unix \*(AK
+.ig
+.\" This option is left undocumented, on purpose.
+\*(FC\-\^\-nostalgia\*(FR
+\*(FC\-W nostalgia\*(FR provide a moment of nostalgia for
+ long time \*(AK users
+..
+\*(FC\-\^\-posix\*(FR
+\*(FC\-W posix\*(FR disable common and GNU extensions.
+ Enable \*(FIinterval expressions\*(FR in regular
+ expression matching (see \fHRegular
+ Expressions\fP, below)
+\*(FC\-\^\-re\-interval\*(FR
+\*(FC\-W re\-interval\*(FR enable \*(FIinterval expressions\*(FR in regular
+ expression matching (see \fHRegular
+ Expressions\fP, below). Useful if
+ \*(FC\-\^\-posix\*(FR is not specified
+\*(FC\-\^\-source '\*(FItext\*(FC'\*(FR
+\*(FC\-W source '\*(FItext\*(FC'\*(FR use \*(FItext\*(FR as AWK program source code
+\*(FC\-\^\-version\*(FR
+\*(FC\-W version\*(FR print version information on \*(FCstdout\fP
+ and exit zero
+.sp .5
+.fi
+In compatibility mode,
+any other options are flagged as illegal, but are otherwise ignored.
+In normal operation, as long as program text has been supplied, unknown
+options are passed on to the AWK program in
+\*(FCARGV\*(FR
+for processing. This is most useful for running AWK
+programs via the \*(FC#!\*(FR executable interpreter mechanism.\*(CB
+.EB "\s+2\f(HBCOMMAND LINE ARGUMENTS (\*(GK\f(HB)\*(FR\s0"
+
+.BT
+
+.ES
+.fi
+\*(CDThe following options are specific to \*(MK.
+.sp .5
+.nf
+\*(FC\-W dump\*(FR print an assembly listing of the program to
+ \*(FCstdout\fP and exit zero
+\*(FC\-W exec \*(FIfile\*(FR read program text from \*(FIfile\fP. No other
+ options are processed. Useful with \*(FC#!\fP
+\*(FC\-W interactive\*(FR unbuffer \*(FCstdout\fP and line buffer \*(FCstdin\fP.
+ Lines are always records, ignoriing \*(FCRS\fP
+\*(FC\-W posix_space\*(FR make \*(FC\en\*(FR separate fields when \*(FCRS = "\^"\fP
+\*(FC\-W sprintf=\*(FInum\*(FR adjust the size of \*(MK's internal
+ \*(FCsprintf\*(FR buffer
+\*(FC\-W version\*(FR print version and copyright information on
+ \*(FCstdout\fP and limit information on \*(FCstderr\fP
+ and exit zero
+.sp .5
+.fi
+The options may be abbreviated using just the first letter, e.g.,
+\*(FC\-We\*(FR,
+\*(FC\-Wv\*(FR,
+and so on.\*(CB
+.EB "\s+2\f(HBCOMMAND LINE ARGUMENTS (\*(MK\f(HB)\*(FR\s0"
+
+
+.\" --- Awk Program Execution
+.ES
+.fi
+\*(CDAWK programs are a sequence of pattern-action statements
+and optional function definitions.
+.sp .5
+ \*(FIpattern\*(FC { \*(FIaction statements\*(FC }\*(FR
+.br
+ \*(FCfunction \*(FIname\*(FC(\*(FIparameter list\*(FC) { \*(FIstatements\*(FC }\*(FR
+.sp .5
+\*(AK first reads the program source from the
+\*(FIprog-file\*(FR(s) if specified,
+\*(CBfrom arguments to \*(FC\-\^\-source\*(FR,\*(CD
+or from the first non-option argument on the command line.
+The program text is read as if all the \*(FIprog-file\*(FR(s)
+\*(CBand command line
+source texts\*(CD had been concatenated together.
+.sp .5
+AWK programs execute in the following order.
+First, all variable assignments specified via the \*(FC\-v\fP
+option are performed.
+Next, \*(AK executes the code in the
+\*(FCBEGIN\fP rules(s) (if any), and then proceeds to read
+the files \*(FC1\fP through \*(FCARGC \- 1\fP in the \*(FCARGV\fP array.
+(Adjusting \*(FCARGC\fP and \*(FCARGV\fP thus provides control over
+the input files that will be processed.)
+If there are no files named on the command line,
+\*(AK reads the standard input.
+.sp .5
+If a command line argument has the form
+\*(FIvar\*(FC=\*(FIval\*(FR
+it is treated as a variable assignment. The variable
+\*(FIvar\fP will be assigned the value \*(FIval\*(FR.
+(This happens after any \*(FCBEGIN\fP rule(s) have been run.)
+... delete this paragraph if no space
+Command line variable assignment
+is most useful for dynamically assigning values to the variables
+\*(AK uses to control how input is broken into fields and records. It
+is also useful for controlling state if multiple passes are needed over
+a single data file.
+.sp .5
+If the value of a particular element of \*(FCARGV\fP is empty
+(\*(FC"\^"\*(FR), \*(AK skips over it.
+.sp .5
+For each record in the input, \*(AK tests to see if it matches any
+\*(FIpattern\fP in the AWK program.
+For each pattern that the record matches, the associated
+\*(FIaction\fP is executed.
+The patterns are tested in the order they occur in the program.
+.sp .5
+Finally, after all the input is exhausted,
+\*(AK executes the code in the \*(FCEND\fP rule(s) (if any).
+.sp .5
+If a program only has a \*(FCBEGIN\fP rule, no input files are processed.
+If a program only has an \*(FCEND\fP rule, the input will be read.
+\*(CX
+.EB "\s+2\f(HBAWK PROGRAM EXECUTION\*(FR\s0"
+
+
+.BT
+
+.\" --- Lines And Statements
+.ES
+.fi
+\*(CDAWK is a line oriented language. The pattern comes first, and then the
+action. Action statements are enclosed in \*(FC{\fP and \*(FC}\*(FR.
+Either the pattern may be missing, or the action may be missing, but
+not both. If the pattern is missing, the action will be
+executed for every input record.
+A missing action is equivalent to
+.sp .5
+ \*(FC{ print }\fP
+.sp .5
+which prints the entire record.
+.sp .5
+Comments begin with the \*(FC#\*(FR character, and continue until the
+end of the line.
+Normally, a statement ends with a newline, but lines ending in
+a ``,'',
+\*(FC{\*(FR,
+\*(CB\*(FC?\*(FR,
+\*(FC:\*(FR,\*(CD
+\*(FC&&\*(FR,
+or
+\*(FC||\*(FR
+are automatically continued.
+Lines ending in \*(FCdo\fP or \*(FCelse\fP
+also have their statements automatically continued on the following line.
+In other cases, a line can be continued by ending it with a ``\e'',
+in which case the newline will be ignored. However a ``\e'' after a
+\*(FC#\*(FR is not special.
+.sp .5
+Multiple statements may be put on one line by separating them with a ``;''.
+This applies to both the statements within the action part of a
+pattern-action pair (the usual case),
+and to the pattern-action statements themselves.\*(CX
+.EB "\s+2\f(HBLINES AND STATEMENTS\*(FR\s0"
+
+
+
+.\" --- Regular Expressions
+.ES
+.fi
+\*(CDRegular expressions are the extended kind originally defined by
+\*(FCegrep\fP.
+\*(CBAdditional GNU regexp operators are supported by \*(GK.
+A \*(FIword-constituent\fP character is a letter, digit, or
+underscore (\*(FC_\fP).\*(CD
+.sp .5
+.TS
+center, tab(~);
+cp8 sp8
+cp8 sp8
+lp8|lp8.
+.\" .vs 10
+_
+Summary of Regular Expressions
+In Decreasing Precedence
+_
+\*(FC(\^\*(FIr\*(FC)\*(FR~regular expression (for grouping)
+\*(FIc\*(FR~if non-special char, matches itself
+\*(FC\e\*(FI\^c\*(FR~turn off special meaning of \*(FIc\fP
+\*(FC^\*(FR~beginning of string (note: \*(FInot\fP line)
+\*(FC$\*(FR~end of string (note: \*(FInot\fP line)
+\*(FC.\*(FR~any single character, including newline
+\*(FC[\*(FR...\*(FC]\*(FR~any one character in ... or range
+\*(FC[^\*(FR...\*(FC]\*(FR~any one character not in ... or range
+\*(CB\*(FC\ey\*(FR~word boundary
+\*(FC\eB\*(FR~middle of a word
+\*(FC\e<\*(FR~beginning of a word
+\*(FC\e>\*(FR~end of a word
+\*(FC\ew\*(FR~any word-constituent character
+\*(FC\eW\*(FR~any non-word-constituent character
+\*(FC\e`\*(FR~beginning of a buffer (string)
+\*(FC\e'\*(FR~end of a buffer (string)\*(CD
+\*(FIr\*(FC*\*(FR~zero or more occurrences of \*(FIr\*(FR
+\*(FIr\*(FC+\*(FR~one or more occurrences of \*(FIr\*(FR
+\*(FIr\*(FC?\*(FR~zero or one occurrences of \*(FIr\*(FR
+\*(FIr\*(FC{\*(FIn\*(FC,\*(FIm\*(FC}\*(FR~\*(FIn\fP to \*(FIm\fP occurrences of \*(FIr\*(FR \*(CR(POSIX: see note below)\*(CD
+\*(FIr1\*(FC|\|\*(FIr2\*(FR~\*(FIr1\*(FR or \*(FIr2\*(FR
+.TE
+.sp .5
+.fi
+\*(CRThe \*(FIr\*(FC{\*(FIn\*(FC,\*(FIm\*(FC}\*(FR notation is called an
+\*(FIinterval expression\fP. POSIX mandates it for AWK regexps, but
+most \*(AKs don't implement it. \*(CBUse \*(FC\-\^\-re\-interval\*(FR
+or \*(FC\-\^\-posix\*(FR to enable
+this feature in \*(GK.\*(CX
+.EB "\s+2\f(HBREGULAR EXPRESSIONS\*(FR\s0"
+.ta .2i .78i 1i 1.2i 1.4i 1.7i
+
+
+.BT
+
+.\" --- POSIX Character Classes (gawk)
+.ES
+.fi
+\*(CDIn regular expressions, within character ranges
+(\*(FC[\*(FR...\*(FC]\*(FR),
+the notation \*(FC[[:\*(FIclass\*(FC:]]\*(FR defines characters classes:
+.sp .5
+.TS
+center, tab(~);
+lp8 lp8 lp8 lp8.
+\*(FCalnum\*(FR~alphanumeric~\*(FClower\*(FR~lower-case
+\*(FCalpha\*(FR~alphabetic~\*(FCprint\*(FR~printable
+\*(FCblank\*(FR~space or tab~\*(FCpunct\*(FR~punctuation
+\*(FCcntrl\*(FR~control~\*(FCspace\*(FR~whitespace
+\*(FCdigit\*(FR~decimal~\*(FCupper\*(FR~upper-case
+\*(FCgraph\*(FR~non-spaces~\*(FCxdigit\*(FR~hexadecimal\*(CB
+.TE
+.fi
+.EB "\s+2\f(HBPOSIX CHARACTER CLASSES (\*(GK\f(HB)\*(FR\s0"
+.ta .2i .78i 1i 1.2i 1.4i 1.7i
+
+
+
+.\" --- Records
+.ES
+.fi
+\*(CDNormally, records are separated by newline characters.
+Assigning values to the built-in variable \*(FCRS\*(FR
+controls how records are separated.
+If \*(FCRS\fP is any single character, that character separates records.
+\*(CLOtherwise, \*(FCRS\fP is a regular expression.
+\*(CR(Not \*(NK.)\*(CL
+Text in the input that matches this
+regular expression will separate the record.
+\*(CB\*(GK sets \*(FCRT\*(FR to the value of the
+input text that matched the regular expression.
+The value of \*(FCIGNORECASE\fP
+will also affect how records are separated when
+\*(FCRS\fP is a regular expression.\*(CD
+If \*(FCRS\fP is set to the null string,
+then records are separated by one or more blank lines.
+When \*(FCRS\fP is set to the null string,
+the newline character always acts as
+a field separator, in addition to whatever value
+\*(FCFS\fP may have.
+\*(CB\*(MK does not apply exceptional rules to \*(FCFS\fP
+when \*(FCRS = "\^"\fP.\*(CX
+.EB \s+2\f(HBRECORDS\*(FR\s0
+
+
+
+.\" --- Fields
+.ES
+.fi
+\*(CDAs each input record is read, \*(AK splits the record into
+\*(FIfields\*(FR, using the value of the \*(FCFS\fP
+variable as the field separator.
+If \*(FCFS\fP is a single character,
+fields are separated by that character.
+\*(CLIf \*(FCFS\fP is the null string,
+then each individual character becomes a separate field.\*(CD
+Otherwise, \*(FCFS\fP is expected to be a full regular expression.
+In the special case that \*(FCFS\fP
+is a single space, fields are separated
+by runs of spaces and/or tabs
+\*(CLand/or newlines\*(CD.
+Leading and trailing whitespace are ignored.
+\*(CBThe value of \*(FCIGNORECASE\fP
+will also affect how fields are split when
+\*(FCFS\fP is a regular expression.\*(CD
+.sp .5
+\*(CBIf the \*(FCFIELDWIDTHS\fP
+variable is set to a space separated list of numbers, each field is
+expected to have a fixed width, and \*(GK
+will split up the record using the specified widths.
+The value of \*(FCFS\fP is ignored.
+Assigning a new value to \*(FCFS\fP
+overrides the use of \*(FCFIELDWIDTHS\*(FR,
+and restores the default behavior.\*(CD
+.sp .5
+Each field in the input record may be referenced by its position,
+\*(FC$1\*(FR, \*(FC$2\*(FR, and so on.
+\*(FC$0\fP is the whole record.
+The value of a field may be assigned to as well.
+.sp .5
+The variable \*(FCNF\fP
+is set to the total number of fields in the input record.
+.sp .5
+References to non-existent fields (i.e. fields after \*(FC$NF\*(FR)
+produce the null-string. However, assigning to a non-existent field
+(e.g., \*(FC$(NF+2) = 5\*(FR) will increase the value of
+\*(FCNF\*(FR, create any intervening fields with the null string as their value,
+and cause the value of \*(FC$0\fP
+to be recomputed, with the fields being separated by the
+value of \*(FCOFS\*(FR.
+References to negative numbered fields cause a fatal error.
+Decreasing the value of \*(FCNF\fP causes the trailing fields to be lost
+\*(CR(not \*(NK).\*(CX
+.EB \s+2\f(HBFIELDS\*(FR\s0
+
+.BT
+
+.\" --- Pattern Elements
+.ES
+.fi
+\*(CDAWK patterns may be one of the following.
+.sp .5
+.nf
+ \*(FCBEGIN
+ END
+ \*(FIexpression
+ pat1\*(FC,\*(FIpat2\*(FR
+.sp .5
+.fi
+\*(FCBEGIN\fP and \*(FCEND\fP are special patterns that provide start-up
+and clean-up actions respectively. They must have actions. There can
+be multiple \*(FCBEGIN\fP and \*(FCEND\fP rules; they are merged and
+executed as if there had just been one large rule. They may occur anywhere
+in a program, including different source files.
+.sp .5
+Expression patterns can be any expression, as described
+under \fHExpressions\fP.
+.sp .5
+The \*(FIpat1\*(FC,\*(FIpat2\*(FR pattern
+is called a \*(FIrange pattern\*(FR.
+It matches all input records starting with a record that matches
+\*(FIpat1\*(FR, and continuing until a record that matches
+\*(FIpat2\*(FR, inclusive.
+It does not combine with any other pattern expression.\*(CX
+.EB "\s+2\f(HBPATTERN ELEMENTS\*(FR\s0"
+
+
+.\" --- Action Statements
+.ES
+.nf
+\*(CD\*(FCif (\*(FIcondition\*(FC) \*(FIstatement\*(FR [ \*(FCelse\*(FI statement \*(FR]
+\*(FCwhile (\*(FIcondition\*(FC) \*(FIstatement \*(FR
+\*(FCdo \*(FIstatement \*(FCwhile (\*(FIcondition\*(FC)\*(FR
+\*(FCfor (\*(FIexpr1\*(FC; \*(FIexpr2\*(FC; \*(FIexpr3\*(FC) \*(FIstatement\*(FR
+\*(FCfor (\*(FIvar \*(FCin\*(FI array\*(FC) \*(FIstatement\*(FR
+.ig
+\*(CB\*(FCabort\*(FR [ \*(FIexpression\*(FR ]\*(CD
+..
+\*(FCbreak\*(FR
+\*(FCcontinue\*(FR
+\*(FCdelete \*(FIarray\^\*(FC[\^\*(FIindex\^\*(FC]\*(FR
+\*(CL\*(FCdelete \*(FIarray\^\*(FR\*(CD
+\*(FCexit\*(FR [ \*(FIexpression\*(FR ]
+\*(FCnext\*(FR
+\*(CL\*(FCnextfile\*(FR \*(CR(not \*(MK)\*(CD
+\*(FC{ \*(FIstatements \*(FC}\*(CX
+.EB "\s+2\f(HBACTION STATEMENTS\*(FR\s0"
+
+
+
+.\" --- Escape Sequences
+.ES
+.fi
+\*(CDWithin strings constants (\*(FC"..."\fP) and regexp
+constants (\*(FC/.../\fP), escape sequences may be used to
+generate otherwise unprintable characters. This table lists
+the available escape sequences.
+.sp .5
+.TS
+center, tab(~);
+lp8 lp8 lp8 lp8.
+\*(FC\ea\fP~alert (bell)~\*(FC\er\fP~carriage return
+\*(FC\eb\fP~backspace~\*(FC\et\fP~horizontal tab
+\*(FC\ef\fP~form feed~\*(FC\ev\fP~vertical tab
+\*(FC\en\fP~newline~\*(FC\e\e\fP~backslash
+\*(FC\e\*(FIddd\*(FR~octal value \*(FIddd\fP~\*(CL\*(FC\ex\*(FIhh\*(FR~hex value \*(FIhh\fP\*(CD
+\*(FC\e"\fP~double quote~\*(FC\e/\fP~forward slash\*(CX
+.TE
+.EB "\s+2\f(HBESCAPE SEQUENCES\*(FR\s0"
+.ta .2i .78i 1i 1.2i 1.4i 1.7i
+
+
+.BT
+
+.\" --- Variables
+.ES
+.nf
+\*(FCARGC\fP number of command line arguments
+\*(CB\*(FCARGIND\fP index in \*(FCARGV\fP of current data file\*(CD
+\*(FCARGV\fP array of command line arguments. Indexed from
+ 0 to \*(FCARGC\fP \- 1. Dynamically changing the
+ contents of \*(FCARGV\fP can control the files used
+ for data
+\*(FCCONVFMT\fP conversion format for numbers, default value
+ is \*(FC"%.6g"\*(FR
+\*(FCENVIRON\fP array containing the the current environment.
+ The array is indexed by the environment
+ variables, each element being the value of
+ that variable
+\*(CB\*(FCERRNO\fP contains a string describing the error when a
+ redirection or read for \*(FCgetline\*(FR fails, or if
+ \*(FCclose()\*(FR fails
+\*(CB\*(FCFIELDWIDTHS\fP white-space separated list of fieldwidths. Used
+ to parse the input into fields of fixed width,
+ instead of the value of \*(FCFS\fP\*(CD
+\*(FCFILENAME\fP name of the current input file. If no files given
+ on the command line, \*(FCFILENAME\fP is ``\-''.
+ \*(FCFILENAME\fP is undefined inside the \*(FCBEGIN\fP rule
+ (unless set by \*(FCgetline\fP)
+\*(FCFNR\fP number of the input record in current input file
+\*(FCFS\fP input field separator, a space by default.
+ See \fHFields\fP, above
+\*(CB\*(FCIGNORECASE\fP if non-zero, all regular expression and string
+ operations ignore case. \*(CRIn versions of \*(GK
+ prior to 3.0, \*(FCIGNORECASE\fP only affected
+ regular expression operations and \*(FCindex()\*(FR\*(CD
+\*(FCNF\fP number of fields in the current input record
+\*(FCNR\fP total number of input records seen so far
+\*(FCOFMT\fP output format for numbers, \*(FC"%.6g"\*(FR, by default.
+ \*(CROld versions of \*(AK also used this for number
+ to string conversion instead of \*(FCCONVFMT\fP\*(CD
+\*(FCOFS\fP output field separator, a space by default
+\*(FCORS\fP output record separator, a newline by default
+.ig
+\*(CB\*(FCPROCINFO\fP elements of this array provide access to info
+ about the running AWK program. See
+ \*(AM for details\*(CD
+..
+\*(FCRS\fP input record separator, a newline by default.
+ See \fHRecords\fP, above
+\*(CB\*(FCRT\fP record terminator. \*(GK sets \*(FCRT\fP to the input
+ text that matched the character or regular
+ expression specified by \*(FCRS\*(FR\*(CD
+\*(FCRSTART\fP index of the first character matched by
+ \*(FCmatch()\*(FR; 0 if no match
+\*(FCRLENGTH\fP length of the string matched by \*(FCmatch()\*(FR;
+ \-1 if no match
+\*(FCSUBSEP\fP character(s) used to separate multiple subscripts
+ in array elements, by default \*(FC"\e034"\*(FR. See
+ \fHArrays\fP, below\*(CX
+.EB \s+2\f(HBVARIABLES\*(FR\s0
+
+.BT
+
+.\" --- Arrays
+.ES
+.fi
+\*(CDArrays are subscripted with an expression between square brackets
+(\*(FC[ \*(FRand \*(FC]\*(FR).
+If the expression is an expression list
+\*(FC(\*(FIexpr\*(FC, \*(FIexpr \*(FC...)\*(FR
+then the array subscript is a string consisting of the
+concatenation of the (string) value of each expression,
+separated by the value of the \*(FCSUBSEP\fP variable.
+This facility simulates multiply dimensioned
+arrays. For example:
+.nf
+.sp .5
+ \*(FCi = "A";\^ j = "B";\^ k = "C"
+ x[i, j, k] = "hello, world\en"\*(FR
+.sp .5
+.fi
+assigns the string \*(FC"hello, world\en"\*(FR to the element of the array
+\*(FCx\fP
+which is indexed by the string \*(FC"A\e034B\e034C"\*(FR. All arrays in AWK
+are associative, i.e. indexed by string values.
+.sp .5
+The special operator \*(FCin\fP may be used in an \*(FCif\fP
+or \*(FCwhile\fP statement to see if an array has an index consisting
+of a particular value.
+.sp .5
+.nf
+ \*(FCif (val in array)
+ print array[val]\*(FR
+.sp .5
+.fi
+If the array has multiple subscripts, use
+\*(FC(i, j) in array\*(FR.
+.sp .5
+The \*(FCin\fP construct may also be used in a \*(FCfor\fP
+loop to iterate over all the elements of an array.
+.sp .5
+An element may be deleted from an array using the
+\*(FCdelete\fP statement.
+\*(CLThe \*(FCdelete\fP
+statement can also delete the entire contents of an array,
+just by specifying the array name without a subscript.\*(CX
+.EB \s+2\f(HBARRAYS\*(FR\s0
+
+
+.\" --- Expressions
+.ES
+.fi
+\*(CDExpressions are used as patterns, for controlling conditional
+statements, and to produce parameter values when calling functions.
+Expressions may also be used as simple statements,
+particularly if they have side-effects, such as assignment.
+Expressions mix \*(FIoperands\fP and \*(FIoperators\fP. Operands are
+constants, fields, variables, array elements, and the return
+values from function calls (both built-in and user-defined).
+.sp .5
+Regexp constants (\*(FC/\*(FIpat\*(FC/\*(FR), when used as simple expressions,
+i.e., not used on the right-hand side of
+\*(FC~\fP and \*(FC!~\fP, or as arguments to the
+\*(CB\*(FCgensub()\fP,\*(CD
+\*(FCgsub()\fP,
+\*(FCmatch()\fP,
+\*(FCsplit()\fP,
+and
+\*(FCsub()\fP,
+functions, mean \*(FC$0 ~ /\*(FIpat\*(FC/\*(FR.
+.sp .5
+The AWK operators, in order of decreasing precedence, are
+.sp .5
+.nf
+\*(FC(\&...)\*(FR grouping
+\*(FC$\fP field reference
+\*(FC++ \-\^\-\fP increment and decrement, both prefix and postfix
+\*(FC^\fP \*(CL\*(FC**\*(FR\*(CD exponentiation
+\*(FC+ \- !\fP unary plus, unary minus, and logical negation
+\*(FC* / %\fP multiplication, division, and modulus
+\*(FC+ \-\fP addition and subtraction
+\*(FIspace\fP string concatenation
+\*(FC< >\fP less than, greater than
+\*(FC<= >=\fP less than or equal, greater than or equal
+\*(FC!= ==\fP not equal, equal
+\*(FC~ !~\fP regular expression match, negated match
+\*(FCin\fP array membership
+\*(FC&&\fP logical AND, short circuit
+\*(FC||\fP logical OR, short circuit
+\*(FC?\^:\fP in-line conditional expression
+\*(FC=\0+=\0\-=\0*=\0/=\0%=\0^=\0\*(CL**=\*(CD\fP
+ assignment operators\*(CX
+.EB \s+2\f(HBEXPRESSIONS\*(FR\s0
+
+
+.BT
+
+.\" --- Conversions and Comparisons
+.ES
+.fi
+\*(CDVariables and fields may be (floating point) numbers, or strings, or both.
+Context determines how the value of a variable is interpreted. If used in
+a numeric expression, it will be treated as a number, if used as a string
+it will be treated as a string.
+.sp .5
+To force a variable to be treated as a number, add 0 to it; to force it
+to be treated as a string, concatenate it with the null string.
+.sp .5
+When a string must be converted to a number, the conversion is accomplished
+using \*(FIatof\*(FR(3).
+A number is converted to a string by using the value of \*(FCCONVFMT\fP
+as a format string for \*(FIsprintf\*(FR(3),
+with the numeric value of the variable as the argument.
+However, even though all numbers in AWK are floating-point,
+integral values are \*(FIalways\fP converted as integers.
+.sp .5
+Comparisons are performed as follows:
+If two variables are numeric, they are compared numerically.
+If one value is numeric and the other has a string value that is a
+``numeric string,'' then comparisons are also done numerically.
+Otherwise, the numeric value is converted to a string and a string
+comparison is performed.
+Two strings are compared, of course, as strings.
+\*(CRAccording to the POSIX standard, even if two strings are
+numeric strings, a numeric comparison is performed. However, this is
+clearly incorrect, and none of the three free \*(AK\*(FRs do this.\*(CD
+.sp .5
+Note that string constants, such as \*(FC"57"\fP, are \*(FInot\fP
+numeric strings, they are string constants. The idea of ``numeric string''
+only applies to fields, \*(FCgetline\fP input,
+\*(FCFILENAME\*(FR, \*(FCARGV\fP elements, \*(FCENVIRON\fP
+elements and the elements of an array created by
+\*(FCsplit()\fP that are numeric strings.
+The basic idea is that \*(FIuser input\*(FR,
+and only user input, that looks numeric,
+should be treated that way.
+.sp .5
+Uninitialized variables have the numeric value 0 and the string value
+\*(FC"\^"\fP
+(the null, or empty, string).\*(CX
+.EB "\s+2\f(HBCONVERSIONS AND COMPARISONS\*(FR\s0"
+
+.ig
+.\" --- Localization
+.ES
+.nf
+.ce 100
+\*(CDThis
+section
+is
+under
+construction.
+.sp .5
+This
+section
+is
+under
+construction.\*(CB
+.ce 0
+.EB "\s+2\f(HBLOCALIZATION\*(FR\s0"
+..
+
+.BT
+
+
+.\" --- Input Control
+.ES
+.nf
+\*(CD\*(FCclose(\*(FIfile\*(FC)\*(FR close input file or pipe
+\*(FCgetline\fP set \*(FC$0\fP from next input record;
+ set \*(FCNF\*(FR, \*(FCNR\*(FR, \*(FCFNR\*(FR
+\*(FCgetline < \*(FIfile\*(FR set \*(FC$0\fP from next record of \*(FIfile\*(FR; set \*(FCNF\*(FR
+\*(FCgetline \*(FIv\*(FR set \*(FIv\fP from next input record;
+ set \*(FCNR\*(FR, \*(FCFNR\*(FR
+\*(FCgetline \*(FIv \*(FC< \*(FIfile\*(FR set \*(FIv\fP from next record of \*(FIfile\*(FR
+\*(FIcmd \*(FC| getline\*(FR pipe into \*(FCgetline\*(FR; set \*(FC$0\*(FR, \*(FCNF\*(FR
+\*(FIcmd \*(FC| getline \*(FIv\*(FR pipe into \*(FCgetline\*(FR; set \*(FIv\*(FR
+\*(FCnext\fP stop processing the current input
+ record. Read next input record and
+ start over with the first pattern in the
+ program. Upon end of the input data,
+ execute any \*(FCEND\fP rule(s)
+\*(CL\*(FCnextfile\fP stop processing the current input file.
+ The next input record comes from the
+ next input file. \*(FCFILENAME\fP \*(CBand
+ \*(FCARGIND\fP\*(CL are updated, \*(FCFNR\fP is reset to 1,
+ and processing starts over with the first
+ pattern in the AWK program. Upon end
+ of input data, execute any \*(FCEND\fP rule(s).
+ \*(CREarlier versions of \*(GK used
+ \*(FCnext file\*(FR, as two words. This
+ generates a warning message and will
+ eventually be removed. \*(CR\*(MK does not
+ currently support \*(FCnextfile\*(FR\*(CD
+.sp .5
+.fi
+The \*(FCgetline\*(FR command returns 0 on end of file, and \-1 on an
+error.\*(CX
+.EB "\s+2\f(HBINPUT CONTROL\*(FR\s0"
+
+.\" --- Output Control
+.ES
+.fi
+.in +.2i
+.ti -.2i
+\*(CD\*(FCclose(\*(FIfile\*(FC)\*(FR
+.br
+close output file or pipe
+.ti -.2i
+\*(CL\*(FCfflush(\*(FR[\*(FIfile\^\*(FR]\*(FC)\*(FR
+.br
+flush any buffers associated
+with the open output file or pipe \*(FIfile\*(FR.\*(CD
+\*(CBIf \*(FIfile\fP is missing, then standard output is flushed.
+If \*(FIfile\fP is the null string, then all open output files and pipes
+are flushed \*(CR(not \*(NK)\*(CD
+.ti -.2i
+\*(FCprint\fP
+.br
+print the current record. The output record is terminated
+with the value of \*(FCORS\fP
+.ti -.2i
+\*(FCprint \*(FIexpr-list\*(FR
+.br
+print expressions. Each expression is separated
+by the value of \*(FCOFS\fP. The output record is
+terminated with the value of \*(FCORS\fP
+.ti -.2i
+\*(FCprintf \*(FIfmt\*(FC, \*(FIexpr-list\*(FR
+.br
+format and print (see \fHPrintf Formats\fP, below)
+.ti -.2i
+\*(FCsystem(\*(FIcmd\*(FC)\*(FR
+.br
+execute the command \*(FIcmd\*(FR,
+and return the exit status
+\*(CR(may not be available on non-POSIX systems)\*(CD
+.sp .5
+.in -.2i
+I/O redirections may be used with both \*(FCprint\fP and \*(FCprintf\fP.
+.sp .5
+.in +.2i
+.ti -.2i
+\*(CD\*(FCprint "hello" > \*(FIfile\*(FR
+.br
+Print data to \*(FIfile\fP. The first time the file is written to, it
+will be truncated. Subsequent commands append data.
+.ti -.2i
+\*(FCprint "hello" >> \*(FIfile\*(FR
+.br
+Append data to \*(FIfile\fP. The previous contents of the file are not lost.
+.ti -.2i
+\*(FCprint "hello" | \*(FIcmd\*(FR
+.br
+Print data down a pipeline to \*(FIcmd\*(FR.\*(CX
+.in -.2i
+.EB "\s+2\f(HBOUTPUT CONTROL\*(FR\s0"
+
+.BT
+
+
+.\" --- Printf Formats
+.ES
+.fi
+\*(CDThe \*(FCprintf\fP statement and
+\*(FCsprintf()\fP function
+accept the following conversion specification formats:
+.sp .5
+.nf
+\*(FC%c\fP an \s-1ASCII\s+1 character
+\*(FC%d\fP a decimal number (the integer part)
+\*(FC%i\fP a decimal number (the integer part)
+\*(FC%e\fP a floating point number of the form
+ \*(FC[\-]d.dddddde[+\^\-]dd\*(FR
+\*(FC%E\fP like \*(FC%e\fP, but use \*(FCE\fP instead of \*(FCe\*(FR
+\*(FC%f\fP a floating point number of the form
+ \*(FC[\-]ddd.dddddd\*(FR
+\*(FC%g\fP use \*(FC%e\fP or \*(FC%f\fP, whichever is shorter, with
+ nonsignificant zeros suppressed
+\*(FC%G\fP like \*(FC%g\fP, but use \*(FC%E\fP instead of \*(FC%e\*(FR
+\*(FC%o\fP an unsigned octal number (the integer part)
+\*(FC%s\fP a character string
+\*(FC%x\fP an unsigned hexadecimal number (integer part)
+\*(FC%X\fP like \*(FC%x\fP, but use \*(FCABCDEF\fP instead of \*(FCabcdef\*(FR
+\*(FC%%\fP A single \*(FC%\fP character; no argument is converted
+.sp .5
+.fi
+Optional, additional parameters may lie between the \*(FC%\fP
+and the control letter:
+.sp .5
+.nf
+\*(FC\-\fP left-justify the expression within its field
+\*(FIspace\fP for numeric conversions, prefix positive values
+ with a space, and negative values with a
+ minus sign
+\*(FC+\fP used before the \*(FIwidth\fP modifier means to always
+ supply a sign for numeric conversions, even if
+ the data to be formatted is positive. The \*(FC+\fP
+ overrides the space modifier
+\*(FC#\fP use an ``alternate form'' for some control letters.
+ For \*(FC%o\*(FR, supply a leading zero.
+ For \*(FC%x\*(FR, and \*(FC%X\*(FR, supply a leading \*(FC0x\*(FR or \*(FC0X\*(FR for a
+ nonzero result.
+ For \*(FC%e\*(FR, \*(FC%E\*(FR, and \*(FC%f\*(FR, the result will always
+ contain a decimal point.
+ For \*(FC%g\*(FR, and \*(FC%G\*(FR, trailing zeros are not removed
+\*(FC0\fP a leading zero acts as a flag, indicating output
+ should be padded with zeroes instead of spaces.
+ This applies even to non-numeric output formats.
+ Only has an effect when the field width is wider
+ than the value to be printed
+\*(FIwidth\fP pad the field to this width. The field is normally
+ padded with spaces. If the \*(FC0\fP flag has been used,
+ pad with zeroes
+\*(FC\&.\*(FIprec\*(FR specifies the precision to use when printing.
+ For the \*(FC%e\*(FR, \*(FC%E\*(FR, and \*(FC%f\*(FR formats, the number of
+ digits to print to the right of the decimal point.
+ For the \*(FC%g\*(FR and \*(FC%G\fP formats, the maximum
+ number of significant digits.
+ For the \*(FC%d\*(FR, \*(FC%o\*(FR, \*(FC%i\*(FR, \*(FC%u\*(FR, \*(FC%x\*(FR, and \*(FC%X\fP formats, the
+ minimum number of digits to print.
+ For the \*(FC%s\fP format, the maximum number of
+ characters to print
+.sp .5
+.fi
+The dynamic \*(FIwidth\fP and \*(FIprec\fP capabilities of the ANSI C
+\*(FCprintf()\fP routines are supported.
+A \*(FC*\fP in place of either the \*(FIwidth\fP or \*(FIprec\fP
+specifications will cause their values to be taken from
+the argument list to \*(FCprintf\fP or \*(FCsprintf()\*(FR.\*(CX
+.EB "\s+2\f(HBPRINTF FORMATS\*(FR\s0"
+
+
+
+.BT
+
+.\" --- Special Filenames
+.ES
+.fi
+\*(CDWhen doing I/O redirection from either \*(FCprint\fP
+or \*(FCprintf\fP into a file, or via \*(FCgetline\fP
+from a file, all three implementations of \*(FCawk\fP
+recognize certain special filenames internally. These filenames
+allow access to open file descriptors inherited from the
+parent process (usually the shell).
+These file names may also be used on the command line to name data files.
+The filenames are:
+.sp .5
+.nf
+\*(FC"-"\fP standard input
+\*(FC/dev/stdin\fP standard input \*(CR(not \*(MK)\*(CD
+\*(FC/dev/stdout\fP standard output
+\*(FC/dev/stderr\fP standard error output
+.sp .5
+.fi
+\*(CBThe following names are specific to \*(GK.
+.sp .5
+.nf
+\*(FC/dev/fd/\^\*(FIn\*(FR file associated with the open file descriptor \*(FIn\*(FR
+.sp .5
+.fi
+Other special filenames provide access to information about the running
+\*(FCgawk\fP process.
+The filenames are:\*(FR
+.sp .5
+.nf
+\*(FC/dev/pid\fP returns process ID of current process
+\*(FC/dev/ppid\fP returns parent process ID of current process
+\*(FC/dev/pgrpid\fP returns process group ID of current process
+\*(FC/dev/user\fP returns a single newline-terminated record.
+ The fields are separated with spaces.
+ \*(FC$1\fP is the return value of \*(FIgetuid\*(FR(2),
+ \*(FC$2\fP is the return value of \*(FIgeteuid\*(FR(2),
+ \*(FC$3\fP is the return value of \*(FIgetgid\*(FR(2) , and
+ \*(FC$4\fP is the return value of \*(FIgetegid\*(FR(2).
+ Any additional fields are the group IDs returned
+ by \*(FIgetgroups\*(FR(2). Multiple groups may not be
+ supported on all systems
+.sp .5
+.fi
+.ig
+\*(CRThese filenames are now obsolete.
+Use the \*(FCPROCINFO\fP array to obtain the information they provide.\*(CL
+..
+.\" BEGIN FOR 3.0.x
+\*(CRThese filenames will become obsolete in \*(GK 3.1.
+Be aware that you will have to change your programs.\*(CL
+.\" END FOR 3.0.x
+.EB "\s+2\f(HBSPECIAL FILENAMES\*(FR\s0"
+
+
+
+
+.\" --- Builtin Numeric Functions
+.ES
+.nf
+\*(CD\*(FCatan2(\*(FIy\*(FC, \*(FIx\*(FC)\*(FR returns the arctangent of \*(FIy/x\fP in radians
+\*(FCcos(\*(FIexpr\*(FC)\*(FR the cosine of \*(FIexpr\fP, which is in radians
+\*(FCexp(\*(FIexpr\*(FC)\*(FR the exponential function (\*(FIe \*(FC^ \*(FIx\*(FR)
+\*(FCint(\*(FIexpr\*(FC)\*(FR truncates to integer
+\*(FClog(\*(FIexpr\*(FC)\*(FR the natural logarithm function (base \*(FIe\^\*(FR)
+\*(FCrand()\fP returns a random number between 0 and 1
+\*(FCsin(\*(FIexpr\*(FC)\*(FR the sine of \*(FIexpr\fP, which is in radians
+\*(FCsqrt(\*(FIexpr\*(FC)\*(FR the square root function
+\&\*(FCsrand(\*(FR[\*(FIexpr\^\*(FR]\*(FC)\*(FR uses \*(FIexpr\fP as a new seed for the random number
+ generator. If no \*(FIexpr\fP, the time of day is used.
+ Returns previous seed for the random number
+ generator\*(CX
+.EB "\s+2\f(HBNUMERIC FUNCTIONS\*(FR\s0"
+
+
+.BT
+
+
+.\" --- Builtin String Functions
+.ES
+.fi
+.in +.2i
+.ti -.2i
+\*(CB\*(FCgensub(\*(FIr\*(FC, \*(FIs\*(FC, \*(FIh \*(FR[\*(FC, \*(FIt\*(FR]\*(FC)\*(FR
+.br
+search the target string
+\*(FIt\fP for matches of the regular expression \*(FIr\*(FR. If
+\*(FIh\fP is a string beginning with \*(FCg\fP or \*(FCG\*(FR,
+replace all matches of \*(FIr\fP with \*(FIs\*(FR. Otherwise, \*(FIh\fP
+is a number indicating which match of \*(FIr\fP to replace. If no
+\*(FIt\fP is supplied, \*(FC$0\fP is used instead. Within the
+replacement text \*(FIs\*(FR, the sequence \*(FC\e\*(FIn\*(FR,
+where \*(FIn\fP is a digit from 1 to 9, may be used to indicate just
+the text that matched the \*(FIn\*(FR'th parenthesized subexpression.
+The sequence \*(FC\e0\fP represents the entire matched text, as does
+the character \*(FC&\*(FR. Unlike \*(FCsub()\fP and \*(FCgsub()\*(FR,
+the modified string is returned as the result of the function,
+and the original target string is \*(FInot\fP changed\*(CD
+.ti -.2i
+\*(FCgsub(\*(FIr\*(FC, \*(FIs \*(FR[\*(FC, \*(FIt\*(FR]\*(FC)\*(FR
+.br
+for each substring matching the
+regular expression \*(FIr\fP in the string \*(FIt\*(FR, substitute the
+string \*(FIs\*(FR, and return the number of substitutions. If
+\*(FIt\fP is not supplied, use \*(FC$0\*(FR. An \*(FC&\fP in the
+replacement text is replaced with the text that was actually matched.
+Use \*(FC\e&\fP to get a literal \*(FC&\*(FR. See \*(AM
+for a fuller discussion of the rules for \*(FC&\*(FR's and backslashes
+in the replacement text of \*(CB\*(FCgensub()\*(FR,\*(CD \*(FCsub()\*(FR,
+and \*(FCgsub()\*(FR
+.ti -.2i
+\*(FCindex(\*(FIs\*(FC, \*(FIt\*(FC)\*(FR
+.br
+returns the index of the string
+\*(FIt\fP in the string \*(FIs\*(FR, or 0 if \*(FIt\fP is not present
+.ti -.2i
+\*(FClength(\*(FR[\*(FIs\*(FR]\*(FC)\*(FR
+.br
+returns the length of the string
+\*(FIs\*(FR, or the length of \*(FC$0\fP if \*(FIs\fP is not supplied
+.ti -.2i
+\*(FCmatch(\*(FIs\*(FC, \*(FIr\*(FC)\*(FR
+.br
+returns the position in
+\*(FIs\fP where the regular expression \*(FIr\fP occurs, or 0 if
+\*(FIr\fP is not present, and sets the values of \*(FCRSTART\fP
+and \*(FCRLENGTH\*(FR
+.ti -.2i
+\*(FCsplit(\*(FIs\*(FC, \*(FIa \*(FR[\*(FC, \*(FIr\*(FR]\*(FC)\*(FR
+.br
+splits the string
+\*(FIs\fP into the array \*(FIa\fP on the regular expression \*(FIr\*(FR,
+and returns the number of fields. If \*(FIr\fP is omitted, \*(FCFS\fP
+is used instead. The array \*(FIa\fP is cleared first.
+Splitting behaves identically to field splitting.
+See \fHFields\fP, above
+.ti -.2i
+\*(FCsprintf(\*(FIfmt\*(FC, \*(FIexpr-list\*(FC)\*(FR
+.br
+prints \*(FIexpr-list\fP
+according to \*(FIfmt\*(FR, and returns the resulting string
+.ti -.2i
+\*(FCsub(\*(FIr\*(FC, \*(FIs \*(FR[\*(FC, \*(FIt\*(FR]\*(FC)\*(FR
+.br
+just like
+\*(FCgsub()\*(FR, but only the first matching substring is replaced
+.ti -.2i
+\*(FCsubstr(\*(FIs\*(FC, \*(FIi \*(FR[\*(FC, \*(FIn\*(FR]\*(FC)\*(FR
+.br
+returns the at most
+\*(FIn\*(FR-character substring of \*(FIs\fP starting at \*(FIi\*(FR.
+If \*(FIn\fP is omitted, the rest of \*(FIs\fP is used
+.ti -.2i
+\*(FCtolower(\*(FIstr\*(FC)\*(FR
+.br
+returns a copy of the string \*(FIstr\*(FR,
+with all the upper-case characters in \*(FIstr\fP translated to their
+corresponding lower-case counterparts. Non-alphabetic characters are
+left unchanged
+.ti -.2i
+\*(FCtoupper(\*(FIstr\*(FC)\*(FR
+.br
+returns a copy of the string \*(FIstr\*(FR,
+with all the lower-case characters in \*(FIstr\fP translated to their
+corresponding upper-case counterparts. Non-alphabetic characters are
+left unchanged\*(CX
+.in -.2i
+.EB "\s+2\f(HBSTRING FUNCTIONS\*(FR\s0"
+
+
+
+.BT
+
+
+.\" --- Builtin Time Functions
+.ES
+.fi
+\*(CD\*(GK
+provides the following functions for obtaining time stamps and
+formatting them.
+.sp .5
+.fi
+.in +.2i
+.ig
+.ti -.2i
+\*(FCmktime(\*(FIdatespec\*(FC)\*(FR
+.br
+turns \*(FIdatespec\fP into a time
+stamp of the same form as returned by \*(FCsystime()\*(FR.
+The \*(FIdatespec\fP is a string of the form
+\*(FC"\*(FIYYYY MM DD HH MM SS\*(FC"\*(FR
+..
+.ti -.2i
+\*(FCstrftime(\*(FR[\*(FIformat \*(FR[\*(FC, \*(FItimestamp\*(FR]]\*(FC)\*(FR
+.br
+formats \*(FItimestamp\fP
+according to the specification in \*(FIformat\*(FR. The
+\*(FItimestamp\fP should be of the same form as returned by
+\*(FCsystime()\*(FR.
+If \*(FItimestamp\fP is missing, the current time of day is used. If
+\*(FIformat\fP is missing, a default format equivalent to the output
+of \*(FIdate\*(FR(1) will be used
+.ti -.2i
+\*(FCsystime()\fP
+.br
+returns the current time of day as the number of
+seconds since the Epoch\*(CB
+.in -.2i
+.EB "\s+2\f(HBTIME FUNCTIONS\*(FR\s0"
+
+
+
+.\" --- User-defined Functions
+.ES
+.fi
+\*(CDFunctions in AWK are defined as follows:
+.sp .5
+.nf
+ \*(FCfunction \*(FIname\*(FC(\*(FIparameter list\*(FC)
+ {
+ \*(FIstatements
+ \*(FC}\*(FR
+.sp .5
+.fi
+Functions are executed when they are called from within expressions
+in either patterns or actions. Actual parameters supplied in the function
+call instantiate the formal parameters declared in the function.
+Arrays are passed by reference, other variables are passed by value.
+.sp .5
+Local variables are declared as extra parameters
+in the parameter list. The convention is to separate local variables from
+real parameters by extra spaces in the parameter list. For example:
+.sp .5
+.nf
+ \*(FC# a & b are local
+ function f(p, q, a, b)
+ {
+ \&.....
+ }
+.sp .3
+ /abc/ { ... ; f(1, 2) ; ... }\*(FR
+.fi
+.sp .5
+The left parenthesis in a function call is required
+to immediately follow the function name,
+without any intervening white space.
+This is to avoid a syntactic ambiguity with the concatenation operator.
+This restriction does not apply to the built-in functions.
+.sp .5
+Functions may call each other and may be recursive.
+Function parameters used as local variables are initialized
+to the null string and the number zero upon function invocation.
+.sp .5
+\*(CLThe word
+\*(FCfunc\fP
+may be used in place of
+\*(FCfunction\*(FR.
+\*(CRNote: This usage is deprecated.\*(CX
+.EB "\s+2\f(HBUSER-DEFINED FUNCTIONS\*(FR\s0"
+
+
+
+.\" --- Bug Reports
+.ES
+.fi
+\*(CDIf you find a bug in this reference card, please report it via electronic
+mail to \*(FCarnold@gnu.ai.mit.edu\*(FR.\*(CX
+.EB "\s+2\f(HBBUG REPORTS\*(FR\s0"
+
+.BT
+
+.\" --- Environment Variables
+.ES
+.fi
+\*(CDThe environment variable \*(FCAWKPATH\fP specifies a search path to use
+when finding source files named with the \*(FC\-f\fP
+option.
+The default path is
+\*(FC".:/usr/local/share/awk"\*(FR,
+if this variable does not exist.
+(The actual directory may vary,
+depending upon how \*(GK was built and installed.)
+If a file name given to the \*(FC\-f\fP option contains a ``/'' character,
+no path search is performed.
+.sp .5
+If \*(FCPOSIXLY_CORRECT\fP exists in the environment, then \*(GK
+behaves exactly as if \*(FC\-\^\-posix\fP had been specified on the
+command line.\*(CB
+.EB "\s+2\f(HBENVIRONMENT VARIABLES (\*(GK\f(HB)\*(FR\s0"
+
+.\" --- Historical Features
+.ES
+.fi
+\*(CD\*(GK supports two features of historical AWK implementations.
+First, it is possible to call the \*(FClength()\fP
+built-in function not only with no argument, but even without parentheses.
+This feature is marked as ``deprecated'' in the POSIX standard, and \*(GK
+will issue a warning about its use if \*(FC\-\^\-lint\fP
+is specified on the command line.
+.sp .5
+The other feature is the use of \*(FCcontinue\fP
+or \*(FCbreak\fP statements outside the body of a
+\*(FCwhile\*(FR, \*(FCfor\*(FR, or \*(FCdo\fP loop.
+Historical AWK implementations have treated such usage as
+equivalent to the \*(FCnext\fP statement.
+\*(GK will support this usage if \*(FC\-\^\-traditional\fP
+has been specified.\*(CB
+.EB "\s+2\f(HBHISTORICAL FEATURES\*(FR\s0"
+
+
+.\" --- FTP Information
+.ES
+.nf
+\*(CDHost: \*(FCftp.gnu.ai.mit.edu\*(FR
+File: \*(FC/pub/gnu/gawk-3.0.1.tar.gz\fP
+ GNU \*(AK (\*(GK). There may be a later version
+.sp .5
+Host: \*(FCnetlib.bell-labs.com\*(FR
+File: \*(FC/netlib/research/awk.bundle.Z\fP
+ \*(NK. This version requires an ANSI C compiler;
+ GCC (the GNU C compiler) works well
+.sp .5
+Host: \*(FCftp.whidbey.net\*(FR
+File: \*(FC/pub/brennan/mawk1.3.3.tar.gz\fP
+ Michael Brennan's \*(MK. There may be a newer version\*(CX
+.EB "\s+2\f(HBFTP INFORMATION\*(FR\s0"
+
+.\" --- Copying Permissions
+.ES
+.fi
+\*(CDCopyright \(co 1996 Free Software Foundation, Inc.
+.sp .5
+Permission is granted to make and distribute verbatim copies of this
+reference card provided the copyright notice and this permission notice
+are preserved on all copies.
+.sp .5
+Permission is granted to copy and distribute modified versions of this
+reference card under the conditions for verbatim copying, provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+.sp .5
+Permission is granted to copy and distribute translations of this
+reference card into another language, under the above conditions for
+modified versions, except that this permission notice may be stated in a
+translation approved by the Foundation.\*(CX
+.EB "\s+2\f(HBCOPYING PERMISSIONS\*(FR\s0"
+.BT
diff --git a/doc/awkforai.txt b/doc/awkforai.txt
new file mode 100644
index 00000000..3fca3204
--- /dev/null
+++ b/doc/awkforai.txt
@@ -0,0 +1,150 @@
+Draft for ACM SIGPLAN Patterns (Language Trends)
+
+1996
+
+Why GAWK for AI?
+
+Ronald P. Loui
+
+Most people are surprised when I tell them what language we use in our
+undergraduate AI programming class. That's understandable. We use
+GAWK. GAWK, Gnu's version of Aho, Weinberger, and Kernighan's old
+pattern scanning language isn't even viewed as a programming language by
+most people. Like PERL and TCL, most prefer to view it as a "scripting
+language." It has no objects; it is not functional; it does no built-in
+logic programming. Their surprise turns to puzzlement when I confide
+that (a) while the students are allowed to use any language they want;
+(b) with a single exception, the best work consistently results from
+those working in GAWK. (footnote: The exception was a PASCAL
+programmer who is now an NSF graduate fellow getting a Ph.D. in
+mathematics at Harvard.) Programmers in C, C++, and LISP haven't even
+been close (we have not seen work in PROLOG or JAVA).
+
+Why GAWK?
+
+There are some quick answers that have to do with the pragmatics of
+undergraduate programming. Then there are more instructive answers that
+might be valuable to those who debate programming paradigms or to those
+who study the history of AI languages. And there are some deep
+philosophical answers that expose the nature of reasoning and symbolic
+AI. I think the answers, especially the last ones, can be even more
+surprising than the observed effectiveness of GAWK for AI.
+
+First it must be confessed that PERL programmers can cobble together AI
+projects well, too. Most of GAWK's attractiveness is reproduced in
+PERL, and the success of PERL forebodes some of the success of GAWK.
+Both are powerful string-processing languages that allow the programmer
+to exploit many of the features of a UNIX environment. Both provide
+powerful constructions for manipulating a wide variety of data in
+reasonably efficient ways. Both are interpreted, which can reduce
+development time. Both have short learning curves. The GAWK manual can
+be consumed in a single lab session and the language can be mastered by
+the next morning by the average student. GAWK's automatic
+initialization, implicit coercion, I/O support and lack of pointers
+forgive many of the mistakes that young programmers are likely to make.
+Those who have seen C but not mastered it are happy to see that GAWK
+retains some of the same sensibilities while adding what must be
+regarded as spoonsful of syntactic sugar. Some will argue that
+PERL has superior functionality, but for quick AI applications, the
+additional functionality is rarely missed. In fact, PERL's terse syntax
+is not friendly when regular expressions begin to proliferate and
+strings contain fragments of HTML, WWW addresses, or shell commands.
+PERL provides new ways of doing things, but not necessarily ways of
+doing new things.
+
+In the end, despite minor difference, both PERL and GAWK minimize
+programmer time. Neither really provides the programmer the setting in
+which to worry about minimizing run-time.
+
+There are further simple answers. Probably the best is the fact that
+increasingly, undergraduate AI programming is involving the Web. Oren
+Etzioni (University of Washington, Seattle) has for a while been arguing
+that the "softbot" is replacing the mechanical engineers' robot as the
+most glamorous AI testbed. If the artifact whose behavior needs to be
+controlled in an intelligent way is the software agent, then a language
+that is well-suited to controlling the software environment is the
+appropriate language. That would imply a scripting language. If the
+robot is KAREL, then the right language is "turn left; turn right." If
+the robot is Netscape, then the right language is something that can
+generate "netscape -remote 'openURL(http://cs.wustl.edu/~loui)'" with
+elan.
+
+Of course, there are deeper answers. Jon Bentley found two pearls in
+GAWK: its regular expressions and its associative arrays. GAWK asks
+the programmer to use the file system for data organization and the
+operating system for debugging tools and subroutine libraries. There is
+no issue of user-interface. This forces the programmer to return to the
+question of what the program does, not how it looks. There is no time
+spent programming a binsort when the data can be shipped to /bin/sort
+in no time. (footnote: I am reminded of my IBM colleague Ben Grosof's
+advice for Palo Alto: Don't worry about whether it's highway 101 or 280.
+Don't worry if you have to head south for an entrance to go north. Just
+get on the highway as quickly as possible.)
+
+There are some similarities between GAWK and LISP that are illuminating.
+Both provided a powerful uniform data structure (the associative array
+implemented as a hash table for GAWK and the S-expression, or list of
+lists, for LISP). Both were well-supported in their environments (GAWK
+being a child of UNIX, and LISP being the heart of lisp machines). Both
+have trivial syntax and find their power in the programmer's willingness
+to use the simple blocks to build a complex approach.
+
+Deeper still, is the nature of AI programming. AI is about
+functionality and exploratory programming. It is about bottom-up design
+and the building of ambitions as greater behaviors can be demonstrated.
+Woe be to the top-down AI programmer who finds that the bottom-level
+refinements, "this subroutine parses the sentence," cannot actually be
+implemented. Woe be to the programmer who perfects the data structures
+for that heapsort when the whole approach to the high-level problem
+needs to be rethought, and the code is sent to the junkheap the next day.
+
+AI programming requires high-level thinking. There have always been a few
+gifted programmers who can write high-level programs in assembly language.
+Most however need the ambient abstraction to have a higher floor.
+
+Now for the surprising philosophical answers. First, AI has discovered
+that brute-force combinatorics, as an approach to generating intelligent
+behavior, does not often provide the solution. Chess, neural nets, and
+genetic programming show the limits of brute computation. The
+alternative is clever program organization. (footnote: One might add
+that the former are the AI approaches that work, but that is easily
+dismissed: those are the AI approaches that work in general, precisely
+because cleverness is problem-specific.) So AI programmers always want
+to maximize the content of their program, not optimize the efficiency
+of an approach. They want minds, not insects. Instead of enumerating
+large search spaces, they define ways of reducing search, ways of
+bringing different knowledge to the task. A language that maximizes
+what the programmer can attempt rather than one that provides tremendous
+control over how to attempt it, will be the AI choice in the end.
+
+Second, inference is merely the expansion of notation. No matter whether
+the logic that underlies an AI program is fuzzy, probabilistic, deontic,
+defeasible, or deductive, the logic merely defines how strings can be
+transformed into other strings. A language that provides the best
+support for string processing in the end provides the best support for
+logic, for the exploration of various logics, and for most forms of
+symbolic processing that AI might choose to call "reasoning" instead of
+"logic." The implication is that PROLOG, which saves the AI programmer
+from having to write a unifier, saves perhaps two dozen lines of GAWK
+code at the expense of strongly biasing the logic and representational
+expressiveness of any approach.
+
+I view these last two points as news not only to the programming language
+community, but also to much of the AI community that has not reflected on
+the past decade's lessons.
+
+In the puny language, GAWK, which Aho, Weinberger, and Kernighan thought
+not much more important than grep or sed, I find lessons in AI's trends,
+AI's history, and the foundations of AI. What I have found not only
+surprising but also hopeful, is that when I have approached the AI
+people who still enjoy programming, some of them are not the least bit
+surprised.
+
+
+R. Loui (loui@ai.wustl.edu) is Associate Professor of Computer Science,
+at Washington University in St. Louis. He has published in AI Journal,
+Computational Intelligence, ACM SIGART, AI Magazine, AI and Law, the ACM
+Computing Surveys Symposium on AI, Cognitive Science, Minds and
+Machines, Journal of Philosophy, and is on this year's program
+committees for AAAI (National AI conference) and KR (Knowledge
+Representation and Reasoning).
diff --git a/doc/cardfonts b/doc/cardfonts
new file mode 100644
index 00000000..66367eef
--- /dev/null
+++ b/doc/cardfonts
@@ -0,0 +1,37 @@
+.\" AWK Reference Card --- Arnold Robbins, arnold@gnu.ai.mit.edu
+.\" cardfonts --- this file sets the fonts to use for the reference card
+.\"
+.\" Copyright (C) 1996 Free Software Foundation, Inc.
+.\"
+.\" Permission is granted to make and distribute verbatim copies of
+.\" this reference card provided the copyright notice and this permission
+.\" notice are preserved on all copies.
+.\"
+.\" Permission is granted to process this file through troff and print the
+.\" results, provided the printed document carries copying permission
+.\" notice identical to this one except for the removal of this paragraph
+.\" (this paragraph not being relevant to the printed reference card).
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" reference card under the conditions for verbatim copying, provided that
+.\" the entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one.
+.\"
+.\" Permission is granted to copy and distribute translations of this
+.\" reference card into another language, under the above conditions for
+.\" modified versions, except that this permission notice may be stated in
+.\" a translation approved by the Foundation.
+.\"
+.ig
+Strings for inline font change.
+FR - font roman
+FI - font italic
+FC - font courier
+..
+.ds FR \fR
+.ds FI \fI
+.ds FC \f(CB
+.ds RN Times Roman
+.ds IN Times Italic
+.ds CN Courier Bold
+.ds AM \fIThe GNU Awk User's Guide\fP
diff --git a/doc/colors b/doc/colors
new file mode 100644
index 00000000..e600f64c
--- /dev/null
+++ b/doc/colors
@@ -0,0 +1,42 @@
+.\" AWK Reference Card --- Arnold Robbins, arnold@gnu.ai.mit.edu
+.\" This file sets the colors to use.
+.\"
+.\" Copyright (C) 1996 Free Software Foundation, Inc.
+.\"
+.\" Permission is granted to make and distribute verbatim copies of
+.\" this reference card provided the copyright notice and this permission
+.\" notice are preserved on all copies.
+.\"
+.\" Permission is granted to process this file through troff and print the
+.\" results, provided the printed document carries copying permission
+.\" notice identical to this one except for the removal of this paragraph
+.\" (this paragraph not being relevant to the printed reference card).
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" reference card under the conditions for verbatim copying, provided that
+.\" the entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one.
+.\"
+.\" Permission is granted to copy and distribute translations of this
+.\" reference card into another language, under the above conditions for
+.\" modified versions, except that this permission notice may be stated in
+.\" a translation approved by the Foundation.
+.\"
+.ig
+Strings for inline color change.
+CR - color red
+CG - color green
+CL - color light blue
+CB - color blue
+CD - color dark, i.e. black
+CX - color boX, i.e. for the surrounding boxes (red for now)
+..
+.ds CR \X'ps: exec .768 0 .047 setrgbcolor'
+.ds CG \X'ps: exec 0 .819 .259 setrgbcolor'
+.\" this is deepskyblue3, pretty good
+...ds CL \X'ps: exec 0 .604 .804 setrgbcolor'
+.\" this is deepskyblue2, even better, use this for now
+.ds CL \X'ps: exec 0 .698 .933 setrgbcolor'
+.ds CB \X'ps: exec 0 .219 .941 setrgbcolor'
+.ds CD \X'ps: exec 0 0 0 setrgbcolor'
+.ds CX \*(CG
diff --git a/doc/gawk.1 b/doc/gawk.1
index 89150bab..44ac8c19 100644
--- a/doc/gawk.1
+++ b/doc/gawk.1
@@ -1,7 +1,7 @@
.ds PX \s-1POSIX\s+1
.ds UX \s-1UNIX\s+1
.ds AN \s-1ANSI\s+1
-.TH GAWK 1 "Dec 28 1995" "Free Software Foundation" "Utility Commands"
+.TH GAWK 1 "Dec 09 1996" "Free Software Foundation" "Utility Commands"
.SH NAME
gawk \- pattern scanning and processing language
.SH SYNOPSIS
@@ -63,12 +63,7 @@ options are supplied via arguments to the
.B \-W
option. Multiple
.B \-W
-options may be supplied, or multiple arguments may be supplied together
-if they are separated by commas, or enclosed in quotes and separated
-by white space.
-Case is ignored in arguments to the
-.B \-W
-option.
+options may be supplied
Each
.B \-W
option has a corresponding long option, as detailed below.
@@ -125,10 +120,10 @@ Multiple
options may be used.
.TP
.PD 0
-.BI \-mf= NNN
+.BI \-mf " NNN"
.TP
.PD
-.BI \-mr= NNN
+.BI \-mr " NNN"
Set various memory limits to the value
.IR NNN .
The
@@ -182,7 +177,7 @@ below, for more information.
.PD
.B \-\^\-copyright
Print the short version of the GNU copyright information message on
-the error output.
+the standard output, and exits successfully.
.TP
.PD 0
.B "\-W help"
@@ -196,7 +191,7 @@ the error output.
.PD
.B \-\^\-usage
Print a relatively short summary of the available options on
-the error output.
+the standard output.
(Per the
.IR "GNU Coding Standards" ,
these options cause an immediate, successful exit.)
@@ -245,6 +240,11 @@ mode, with the following additional restrictions:
escape sequences are not recognized.
.TP
\(bu
+Only space and tab act as field separators when
+.B FS
+is set to a single space, newline does not.
+.TP
+\(bu
The synonym
.B func
for the keyword
@@ -306,14 +306,6 @@ and
options) with source code entered on the command line.
It is intended primarily for medium to large AWK programs used
in shell scripts.
-.sp .5
-The
-.B "\-W source="
-form of this option uses the rest of the command line argument for
-.IR program-text ;
-no other options to
-.B \-W
-will be recognized in the same argument.
.TP
.PD 0
.B "\-W version"
@@ -322,7 +314,7 @@ will be recognized in the same argument.
.B \-\^\-version
Print version information for this particular copy of
.I gawk
-on the error output.
+on the standard output.
This is useful mainly for knowing if the current copy of
.I gawk
on your system
@@ -504,7 +496,10 @@ is expected to be a full regular expression.
In the special case that
.B FS
is a single space, fields are separated
-by runs of spaces and/or tabs.
+by runs of spaces and/or tabs and/or newlines.
+(But see the discussion of
+.BR \-\-posix ,
+below).
Note that the value of
.B IGNORECASE
(see below) will also affect how fields are split when
@@ -561,6 +556,12 @@ cause the value of
to be recomputed, with the fields being separated by the value of
.BR OFS .
References to negative numbered fields cause a fatal error.
+Decrementing
+.B NF
+causes the values of fields past the new value to be lost, and the value of
+.B $0
+to be recomputed, with the fields being separated by the value of
+.BR OFS .
.SS Built-in Variables
.PP
.IR Gawk 's
@@ -1017,8 +1018,7 @@ character list, matches any of the characters
.TP
.BI [^ abc... ]
negated character list, matches any character except
-.I abc...
-and newline.
+.IR abc... .
.TP
.IB r1 | r2
alternation: matches either
@@ -1203,16 +1203,23 @@ or
.BR h .
.TP
Equivalence Classes
-An equivalence class is a list of equivalent characters enclosed in
+An equivalence class is a locale-specific name for a list of
+characters that are equivalent. The name is enclosed in
.B [=
and
.BR =] .
-Thus,
-.B [[=ee\`=]]
-is regexp that matches either
+For example, the name
.B e
+might be used to represent all of
+``e,'' ``e\`,'' and ``e\`.''
+In this case,
+.B [[=e]]
+is a regexp
+that matches any of
+ .BR e ,
+ .BR e\' ,
or
-.B e\` .
+ .BR e\` .
.PP
These features are very valuable in non-English speaking locales.
The library functions that
@@ -1415,7 +1422,7 @@ set
Set
.I var
from next input record; set
-.BR NF ,
+.BR NR ,
.BR FNR .
.TP
.BI getline " var" " <" file
@@ -1800,7 +1807,9 @@ returns the arctangent of
in radians.
.TP
.BI cos( expr )
-returns the cosine in radians.
+returns the cosine of
+.IR expr ,
+which is in radians.
.TP
.BI exp( expr )
the exponential function.
@@ -1815,7 +1824,9 @@ the natural logarithm function.
returns a random number between 0 and 1.
.TP
.BI sin( expr )
-returns the sine in radians.
+returns the sine of
+.IR expr ,
+which is in radians.
.TP
.BI sqrt( expr )
the square root function.
@@ -2387,10 +2398,19 @@ argument to the
option is ``t'', then
.B FS
will be set to the tab character.
+Note that typing
+.B "gawk \-F\et \&..."
+simply causes the shell to quote the ``t,'', and does not pass
+``\et'' to the
+.B \-F
+option.
Since this is a rather ugly special case, it is not the default behavior.
This behavior also does not occur if
.B \-\^\-posix
has been specified.
+To really get a tab character as the field separator, it is best to use
+quotes:
+.BR "gawk \-F'\et' \&..." .
.ig
.PP
If
@@ -2512,13 +2532,10 @@ Syntactically invalid single character programs tend to overflow
the parse stack, generating a rather unhelpful message. Such programs
are surprisingly difficult to diagnose in the completely general case,
and the effort to do so really is not worth it.
-.PP
-The word ``GNU'' is incorrectly capitalized in at least one file
-in the source code.
.SH VERSION INFORMATION
This man page documents
.IR gawk ,
-version 3.0.
+version 3.0.1.
.SH AUTHORS
The original version of \*(UX
.I awk
@@ -2580,3 +2597,25 @@ addresses given above.
Brian Kernighan of Bell Labs
provided valuable assistance during testing and debugging.
We thank him.
+.SH COPYING PERMISSIONS
+Copyright \(co) 1996 Free Software Foundation, Inc.
+.PP
+Permission is granted to make and distribute verbatim copies of
+this manual page provided the copyright notice and this permission
+notice are preserved on all copies.
+.ig
+Permission is granted to process this file through troff and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual page).
+..
+.PP
+Permission is granted to copy and distribute modified versions of this
+manual page under the conditions for verbatim copying, provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+.PP
+Permission is granted to copy and distribute translations of this
+manual page into another language, under the above conditions for
+modified versions, except that this permission notice may be stated in
+a translation approved by the Foundation.
diff --git a/doc/gawk.texi b/doc/gawk.texi
index 6227ac32..75bf11f0 100644
--- a/doc/gawk.texi
+++ b/doc/gawk.texi
@@ -1,18 +1,17 @@
\input texinfo @c -*-texinfo-*-
@c %**start of header (This is for running Texinfo on a region.)
@setfilename gawk.info
-@settitle AWK Language Programming
+@settitle The GNU Awk User's Guide
@c %**end of header (This is for running Texinfo on a region.)
-@ignore
+@c inside ifinfo for older versions of texinfo.tex
@ifinfo
-@format
-START-INFO-DIR-ENTRY
+@c I hope this is the right category
+@dircategory Programming Languages
+@direntry
* Gawk: (gawk.info). A Text Scanning and Processing Language.
-END-INFO-DIR-ENTRY
-@end format
+@end direntry
@end ifinfo
-@end ignore
@c @set xref-automatic-section-title
@c @set DRAFT
@@ -20,10 +19,12 @@ END-INFO-DIR-ENTRY
@c The following information should be updated here only!
@c This sets the edition of the document, the version of gawk it
@c applies to, and when the document was updated.
-@set TITLE AWK Language Programming
-@set EDITION 1.0
+@set TITLE The GNU Awk User's Guide
+@set SUBTITLE Effective AWK Programming
+@set EDITION 1.0.1
@set VERSION 3.0
-@set UPDATE-MONTH January 1996
+@set PATCHLEVEL 1
+@set UPDATE-MONTH December 1996
@iftex
@set DOCUMENT book
@end iftex
@@ -33,9 +34,9 @@ END-INFO-DIR-ENTRY
@ignore
Some comments on the layout for TeX.
-1. Use the texinfo.tex from the gawk distribution. It contains fixes that
+1. Use at least texinfo.tex 2.159. It contains fixes that
are needed to get the footings for draft mode to not appear.
-2. I have done A LOT of work to make this look good. There `@page' commands
+2. I have done A LOT of work to make this look good. There are `@page' commands
and use of `@group ... @end group' in a number of places. If you muck
with anything, it's your responsibility not to break the layout.
@end ignore
@@ -63,7 +64,7 @@ Some comments on the layout for TeX.
@smallbook
@iftex
-@cropmarks
+@c @cropmarks
@end iftex
@ifinfo
@@ -71,9 +72,9 @@ This file documents @code{awk}, a program that you can use to select
particular records in a file and perform operations upon them.
This is Edition @value{EDITION} of @cite{@value{TITLE}},
-for the @value{VERSION} version of the GNU implementation of AWK.
+for the @value{VERSION}.@value{PATCHLEVEL} version of the GNU implementation of AWK.
-Copyright (C) 1989, 1991 - 1996 Free Software Foundation, Inc.
+Copyright (C) 1989, 1991, 92, 93, 96 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@@ -101,7 +102,7 @@ by the Foundation.
@titlepage
@title @value{TITLE}
-@subtitle A User's Guide for GNU AWK
+@subtitle @value{SUBTITLE}
@subtitle Edition @value{EDITION}
@subtitle @value{UPDATE-MONTH}
@author Arnold D. Robbins
@@ -135,11 +136,11 @@ Corporation. @*
Registered Trademark of Paramount Pictures Corporation. @*
@c sorry, i couldn't resist
@sp 3
-Copyright @copyright{} 1989, 1991 - 1996 Free Software Foundation, Inc.
+Copyright @copyright{} 1989, 1991, 92, 93, 96 Free Software Foundation, Inc.
@sp 2
This is Edition @value{EDITION} of @cite{@value{TITLE}}, @*
-for the @value{VERSION} (or later) version of the GNU implementation of AWK.
+for the @value{VERSION}.@value{PATCHLEVEL} (or later) version of the GNU implementation of AWK.
@sp 2
Published by the Free Software Foundation @*
@@ -180,6 +181,8 @@ Cover art by Etienne Suvasa.
@center @i{To Chana, for the joy you bring us.}
@sp
@center @i{To Rivka, for the exponential increase.}
+@sp
+@center @i{To Nachum, for the added dimension.}
@page
@w{ }
@page
@@ -188,8 +191,8 @@ Cover art by Etienne Suvasa.
@iftex
@headings off
-@evenheading @thispage@ @ @ @b{@thistitle} @| @|
-@oddheading @| @| @b{@thischapter}@ @ @ @thispage
+@evenheading @thispage@ @ @ @strong{@thistitle} @| @|
+@oddheading @| @| @strong{@thischapter}@ @ @ @thispage
@ifset DRAFT
@evenfooting @today{} @| @emph{DRAFT!} @| Please Do Not Redistribute
@oddfooting Please Do Not Redistribute @| @emph{DRAFT!} @| @today{}
@@ -206,7 +209,7 @@ This file documents @code{awk}, a program that you can use to select
particular records in a file and perform operations upon them.
This is Edition @value{EDITION} of @cite{@value{TITLE}}, @*
-for the @value{VERSION} version of the GNU implementation @*
+for the @value{VERSION}.@value{PATCHLEVEL} version of the GNU implementation @*
of AWK.
@end ifinfo
@@ -420,6 +423,8 @@ of AWK.
function.
* Assert Function:: A function for assertions in @code{awk}
programs.
+* Round Function:: A function for rounding if @code{sprintf} does
+ not do it correctly.
* Ordinal Functions:: Functions for using characters as numbers and
vice versa.
* Join Function:: A function to join an array into a string.
@@ -457,7 +462,7 @@ of AWK.
* SVR4:: Minor changes between System V Releases 3.1
and 4.
* POSIX:: New features from the POSIX standard.
-* BTL:: New features from the AT&T Bell Laboratories
+* BTL:: New features from the Bell Laboratories
version of @code{awk}.
* POSIX/GNU:: The extensions in @code{gawk} not in POSIX
@code{awk}.
@@ -521,6 +526,8 @@ of AWK.
@center To Chana, for the joy you bring us.
@sp 1
@center To Rivka, for the exponential increase.
+@sp 1
+@center To Nachum, for the added dimension.
@end ifinfo
@node Preface, What Is Awk, Top, Top
@@ -534,7 +541,7 @@ how you can use it effectively. You should already be familiar with basic
system commands, such as @code{cat} and @code{ls},@footnote{These commands
are available on POSIX compliant systems, as well as on traditional Unix
based systems. If you are using some other operating system, you still need to
-be familiar with the ideas of I/O redirection and pipes} and basic shell
+be familiar with the ideas of I/O redirection and pipes.} and basic shell
facilities, such as Input/Output (I/O) redirection and pipes.
Implementations of the @code{awk} language are available for many different
@@ -587,6 +594,7 @@ performance improvements, standards compliance, and occasionally, new features.
@unnumberedsec The GNU Project and This Book
@cindex Free Software Foundation
+@cindex Stallman, Richard
The Free Software Foundation (FSF) is a non-profit organization dedicated
to the production and distribution of freely distributable software.
It was founded by Richard M.@: Stallman, the author of the original
@@ -677,6 +685,7 @@ problem reports electronically, or write to me in care of the FSF.
@node Acknowledgements, , Manual History, Preface
@unnumberedsec Acknowledgements
+@cindex Stallman, Richard
I would like to acknowledge Richard M.@: Stallman, for his vision of a
better world, and for his courage in founding the FSF and starting the
GNU project.
@@ -1196,9 +1205,6 @@ reliable since there are no other files to misplace.
@ref{One-liners, , Useful One Line Programs}, presents several short,
self-contained programs.
-@iftex
-@page
-@end iftex
As an interesting side point, the command
@example
@@ -1343,7 +1349,7 @@ BEGIN @{ print "Don't Panic!" @}
@noindent
After making this file executable (with the @code{chmod} utility), you
can simply type @samp{advice}
-at the shell, and the system will arrange to run @code{awk} @footnote{The
+at the shell, and the system will arrange to run @code{awk}@footnote{The
line beginning with @samp{#!} lists the full file name of an interpreter
to be run, and an optional initial command line argument to pass to that
interpreter. The operating system then runs the interpreter with the given
@@ -1353,8 +1359,10 @@ argument list will either be options to @code{awk}, or data files,
or both.} as if you had typed @samp{awk -f advice}.
@example
+@group
$ advice
@print{} Don't Panic!
+@end group
@end example
@noindent
@@ -1695,6 +1703,28 @@ begin on the same line as the pattern. To have the pattern and action
on separate lines, you @emph{must} use backslash continuation---there
is no other way.
+@cindex backslash continuation and comments
+@cindex comments and backslash continuation
+Note that backslash continuation and comments do not mix. As soon
+as @code{awk} sees the @samp{#} that starts a comment, it ignores
+@emph{everything} on the rest of the line. For example:
+
+@example
+@group
+$ gawk 'BEGIN @{ print "dont panic" # a friendly \
+> BEGIN rule
+> @}'
+@error{} gawk: cmd. line:2: BEGIN rule
+@error{} gawk: cmd. line:2: ^ parse error
+@end group
+@end example
+
+@noindent
+Here, it looks like the backslash would continue the comment onto the
+next line. However, the backslash-newline combination is never even
+noticed, since it is ``hidden'' inside the comment. Thus, the
+@samp{BEGIN} is noted as a syntax error.
+
@cindex multiple statements on one line
When @code{awk} statements within one rule are short, you might want to put
more than one of them on a line. You do this by separating the statements
@@ -1840,10 +1870,10 @@ This program prints a sorted list of the login names of all users.
@item awk 'END @{ print NR @}' data
This program counts lines in a file.
-@item awk 'NR % 2' data
+@item awk 'NR % 2 == 0' data
This program prints the even numbered lines in the data file.
If you were to use the expression @samp{NR % 2 == 1} instead,
-it would print the odd number lines.
+it would print the odd numbered lines.
@end table
@node Regexp, Reading Files, One-liners, Top
@@ -2001,9 +2031,6 @@ Here is a table of all the escape sequences used in @code{awk}, and
what they represent. Unless noted otherwise, all of these escape
sequences apply to both string constants and regexp constants.
-@iftex
-@page
-@end iftex
@c @cartouche
@table @code
@item \\
@@ -2151,9 +2178,6 @@ the very first step in processing regexps.
Here is a table of metacharacters. All characters that are not escape
sequences and that are not listed in the table stand for themselves.
-@iftex
-@page
-@end iftex
@table @code
@item \
This is used to suppress the special meaning of a character when
@@ -2166,6 +2190,8 @@ matching. For example:
@noindent
matches the character @samp{$}.
+@c NEEDED
+@page
@cindex anchors in regexps
@cindex regexp, anchors
@item ^
@@ -2345,14 +2371,7 @@ These apply to non-ASCII character sets, which can have single symbols
(called @dfn{collating elements}) that are represented with more than one
character, as well as several characters that are equivalent for
@dfn{collating}, or sorting, purposes. (E.g., in French, a plain ``e''
-and a grave-accented
-@iftex
-``@`e''
-@end iftex
-@ifinfo
-``e''
-@end ifinfo
-are equivalent.)
+and a grave-accented ``@`e'' are equivalent.)
@table @asis
@cindex collating symbols
@@ -2364,15 +2383,12 @@ then @code{[[.ch.]]} is a regexp that matches this collating element, while
@cindex equivalence classes
@item Equivalence Classes
-An @dfn{equivalence class} is a list of equivalent characters enclosed in
+An @dfn{equivalence class} is a locale-specific name for a list of
+characters that are equivalent. The name is enclosed in
@samp{[=} and @samp{=]}.
-@iftex
-Thus, @code{[[=e@`e=]]} is regexp that matches either @samp{e} or @samp{@`e}.
-@end iftex
-@ifinfo
-Because Info files use plain ASCII characters, it is not possible to present
-a realistic equivalence class example here.
-@end ifinfo
+For example, the name @samp{e} might be used to represent all of
+``e,'' ``@`e,'' and ``@'e.'' In this case, @code{[[=e]]} is a regexp
+that matches any of @samp{e}, @samp{@'e}, or @samp{@`e}.
@end table
These features are very valuable in non-English speaking locales.
@@ -2387,7 +2403,7 @@ they do not recognize collating symbols or equivalence classes.
@item [^ @dots{}]
This is a @dfn{complemented character list}. The first character after
the @samp{[} @emph{must} be a @samp{^}. It matches any characters
-@emph{except} those in the square brackets, or newline. For example:
+@emph{except} those in the square brackets. For example:
@example
[^0-9]
@@ -3111,8 +3127,10 @@ When @code{awk} reads an input record, the record is
automatically separated or @dfn{parsed} by the interpreter into chunks
called @dfn{fields}. By default, fields are separated by whitespace,
like words in a line.
-Whitespace in @code{awk} means any string of one or more spaces and/or
-tabs; other characters such as newline, formfeed, and so on, that are
+Whitespace in @code{awk} means any string of one or more spaces,
+tabs or newlines;@footnote{In POSIX @code{awk}, newlines are not
+considered whitespace for separating fields.} other characters such as
+formfeed, and so on, that are
considered whitespace by other languages are @emph{not} considered
whitespace by @code{awk}.
@@ -3346,8 +3364,8 @@ else
should print @samp{everything is normal}, because @code{NF+1} is certain
to be out of range. (@xref{If Statement, ,The @code{if}-@code{else} Statement},
for more information about @code{awk}'s @code{if-else} statements.
-@xref{Typing and Comparison, ,Variable Typing and Comparison Expressions}, for more information
-about the @samp{!=} operator.)
+@xref{Typing and Comparison, ,Variable Typing and Comparison Expressions},
+for more information about the @samp{!=} operator.)
It is important to note that making an assignment to an existing field
will change the
@@ -3381,6 +3399,17 @@ The intervening field, @code{$5} is created with an empty value
(indicated by the second pair of adjacent colons),
and @code{NF} is updated with the value six.
+Finally, decrementing @code{NF} will lose the values of the fields
+after the new value of @code{NF}, and @code{$0} will be recomputed.
+Here is an example:
+
+@example
+$ echo a b c d e f | ../gawk '@{ print "NF =", NF;
+> NF = 3; print $0 @}'
+@print{} NF = 6
+@print{} a b c
+@end example
+
@node Field Separators, Constant Size, Changing Fields, Reading Files
@section Specifying How Fields are Separated
@@ -3481,7 +3510,7 @@ As you know, normally,
Normally,
@end ifinfo
fields are separated by whitespace sequences
-(spaces and tabs), not by single spaces: two spaces in a row do not
+(spaces, tabs and newlines), not by single spaces: two spaces in a row do not
delimit an empty field. The default value of the field separator @code{FS}
is a string containing a single space, @w{@code{" "}}. If this value were
interpreted in the usual way, each space character would separate
@@ -3531,12 +3560,13 @@ bracket). This regular expression matches a single space and nothing else
(@pxref{Regexp, ,Regular Expressions}).
There is an important difference between the two cases of @samp{FS = @w{" "}}
-(a single space) and @samp{FS = @w{"[ \t]+"}} (left bracket, space, backslash,
-``t'', right bracket, which is a regular expression
-matching one or more spaces or tabs). For both values of @code{FS}, fields
-are separated by runs of spaces and/or tabs. However, when the value of
-@code{FS} is @w{@code{" "}}, @code{awk} will first strip leading and trailing
-whitespace from the record, and then decide where the fields are.
+(a single space) and @samp{FS = @w{"[ \t\n]+"}} (left bracket, space,
+backslash, ``t'', backslash, ``n'', right bracket, which is a regular
+expression matching one or more spaces, tabs, or newlines). For both
+values of @code{FS}, fields are separated by runs of spaces, tabs
+and/or newlines. However, when the value of @code{FS} is @w{@code{"
+"}}, @code{awk} will first strip leading and trailing whitespace from
+the record, and then decide where the fields are.
For example, the following pipeline prints @samp{b}:
@@ -4078,11 +4108,11 @@ can be used to read input under your explicit control.
* Plain Getline:: Using @code{getline} with no arguments.
* Getline/Variable:: Using @code{getline} into a variable.
* Getline/File:: Using @code{getline} from a file.
-* Getline/Variable/File:: Using @code{getline} into a variable from a
- file.
+* Getline/Variable/File:: Using @code{getline} into a variable from a
+ file.
* Getline/Pipe:: Using @code{getline} from a pipe.
-* Getline/Variable/Pipe:: Using @code{getline} into a variable from a
- pipe.
+* Getline/Variable/Pipe:: Using @code{getline} into a variable from a
+ pipe.
* Getline Summary:: Summary Of @code{getline} Variants.
@end menu
@@ -4258,6 +4288,14 @@ Since the main input stream is not used, the values of @code{NR} and
the normal manner, so the values of @code{$0} and other fields are
changed. So is the value of @code{NF}.
+@c Thanks to Paul Eggert for initial wording here
+According to POSIX, @samp{getline < @var{expression}} is ambiguous if
+@var{expression} contains unparenthesized operators other than
+@samp{$}; for example, @samp{getline < dir "/" file} is ambiguous
+because the concatenation operator is not parenthesized, and you should
+write it as @samp{getline < (dir "/" file)} if you want your program
+to be portable to other @code{awk} implementations.
+
@node Getline/Variable/File, Getline/Pipe, Getline/File, Getline
@subsection Using @code{getline} Into a Variable from a File
@@ -4270,6 +4308,16 @@ In this version of @code{getline}, none of the built-in variables are
changed, and the record is not split into fields. The only variable
changed is @var{var}.
+@ifinfo
+@c Thanks to Paul Eggert for initial wording here
+According to POSIX, @samp{getline @var{var} < @var{expression}} is ambiguous if
+@var{expression} contains unparenthesized operators other than
+@samp{$}; for example, @samp{getline < dir "/" file} is ambiguous
+because the concatenation operator is not parenthesized, and you should
+write it as @samp{getline < (dir "/" file)} if you want your program
+to be portable to other @code{awk} implementations.
+@end ifinfo
+
For example, the following program copies all the input files to the
output, except for records that say @w{@samp{@@include @var{filename}}}.
Such a record is replaced by the contents of the file
@@ -4341,6 +4389,8 @@ each one.
@c Exercise!!
@c This example is unrealistic, since you could just use system
+@c NEEDED
+@page
Given the input:
@example
@@ -4377,6 +4427,14 @@ This variation of @code{getline} splits the record into fields, sets the
value of @code{NF} and recomputes the value of @code{$0}. The values of
@code{NR} and @code{FNR} are not changed.
+@c Thanks to Paul Eggert for initial wording here
+According to POSIX, @samp{@var{expression} | getline} is ambiguous if
+@var{expression} contains unparenthesized operators other than
+@samp{$}; for example, @samp{"echo " "date" | getline} is ambiguous
+because the concatenation operator is not parenthesized, and you should
+write it as @samp{("echo " "date") | getline} if you want your program
+to be portable to other @code{awk} implementations.
+
@node Getline/Variable/Pipe, Getline Summary, Getline/Pipe, Getline
@subsection Using @code{getline} Into a Variable from a Pipe
@@ -4400,6 +4458,16 @@ awk 'BEGIN @{
In this version of @code{getline}, none of the built-in variables are
changed, and the record is not split into fields.
+@ifinfo
+@c Thanks to Paul Eggert for initial wording here
+According to POSIX, @samp{@var{expression} | getline @var{var}} is ambiguous if
+@var{expression} contains unparenthesized operators other than
+@samp{$}; for example, @samp{"echo " "date" | getline @var{var}} is ambiguous
+because the concatenation operator is not parenthesized, and you should
+write it as @samp{("echo " "date") | getline @var{var}} if you want your
+program to be portable to other @code{awk} implementations.
+@end ifinfo
+
@node Getline Summary, , Getline/Variable/Pipe, Getline
@subsection Summary of @code{getline} Variants
@@ -4417,12 +4485,22 @@ program may have open to just one! In @code{gawk}, there is no such limit.
You can open as many pipelines as the underlying operating system will
permit.
+@vindex FILENAME
+@cindex dark corner
+@cindex @code{getline}, setting @code{FILENAME}
+@cindex @code{FILENAME}, being set by @code{getline}
+An interesting side-effect occurs if you use @code{getline} (without a
+redirection) inside a @code{BEGIN} rule. Since an unredirected @code{getline}
+reads from the command line data files, the first @code{getline} command
+causes @code{awk} to set the value of @code{FILENAME}. Normally,
+@code{FILENAME} does not have a value inside @code{BEGIN} rules, since you
+have not yet started to process the command line data files (d.c.).
+(@xref{BEGIN/END, , The @code{BEGIN} and @code{END} Special Patterns},
+also @pxref{Auto-set, , Built-in Variables that Convey Information}.)
+
The following table summarizes the six variants of @code{getline},
listing which built-in variables are set by each one.
-@iftex
-@page
-@end iftex
@c @cartouche
@table @code
@item getline
@@ -4809,9 +4887,6 @@ This prints a number as an ASCII character. Thus, @samp{printf "%c",
65} outputs the letter @samp{A}. The output for a string value is
the first character of the string.
-@iftex
-@page
-@end iftex
@item d
@itemx i
These are equivalent. They both print a decimal integer.
@@ -5706,6 +5781,7 @@ as arguments to user defined functions
For example:
@example
+@group
function mysub(pat, repl, str, global)
@{
if (global)
@@ -5714,13 +5790,16 @@ function mysub(pat, repl, str, global)
sub(pat, repl, str)
return str
@}
+@end group
+@group
@{
@dots{}
text = "hi! hi yourself!"
mysub(/hi/, "howdy", text, 1)
@dots{}
@}
+@end group
@end example
In this example, the programmer wishes to pass a regexp constant to the
@@ -5967,10 +6046,6 @@ $ awk '@{ sum = $2 + $3 + $4 ; avg = sum / 3
This table lists the arithmetic operators in @code{awk}, in order from
highest precedence to lowest:
-@c sigh. this seems necessary
-@iftex
-@page
-@end iftex
@c @cartouche
@table @code
@item - @var{x}
@@ -6366,6 +6441,7 @@ string, @code{""}) is false. The following program will print @samp{A strange
truth value} three times:
@example
+@group
BEGIN @{
if (3.1415927)
print "A strange truth value"
@@ -6374,6 +6450,7 @@ BEGIN @{
if (j = 57)
print "A strange truth value"
@}
+@end group
@end example
@cindex dark corner
@@ -6975,6 +7052,8 @@ while @samp{$} has higher precedence.
Here is a table of @code{awk}'s operators, in order from highest
precedence to lowest:
+@c NEEDED
+@page
@c use @code in the items, looks better in TeX w/o all the quotes
@table @code
@item (@dots{})
@@ -7678,9 +7757,11 @@ The @code{do} loop executes the @var{body} once, and then repeats @var{body}
as long as @var{condition} is true. It looks like this:
@example
+@group
do
@var{body}
while (@var{condition})
+@end group
@end example
Even if @var{condition} is false at the start, @var{body} is executed at
@@ -8048,6 +8129,12 @@ If the @code{next} statement causes the end of the input to be reached,
then the code in any @code{END} rules will be executed.
@xref{BEGIN/END, ,The @code{BEGIN} and @code{END} Special Patterns}.
+@cindex @code{next}, inside a user-defined function
+@strong{Caution:} Some @code{awk} implementations generate a run-time
+error if you use the @code{next} statement inside a user-defined function
+(@pxref{User-defined, , User-defined Functions}).
+@code{gawk} does not have this problem.
+
@node Nextfile Statement, Exit Statement, Next Statement, Statements
@section The @code{nextfile} Statement
@cindex @code{nextfile} statement
@@ -8221,8 +8308,9 @@ character in the record becomes a separate field.
The default value is @w{@code{" "}}, a string consisting of a single
space. As a special exception, this value means that any
-sequence of spaces and tabs is a single separator. It also causes
-spaces and tabs at the beginning and end of a record to be ignored.
+sequence of spaces, tabs, and/or newlines is a single separator.@footnote{In
+POSIX @code{awk}, newline does not count as whitespace.} It also causes
+spaces, tabs, and newlines at the beginning and end of a record to be ignored.
You can set the value of @code{FS} on the command line using the
@samp{-F} option:
@@ -9080,6 +9168,7 @@ A reasonable attempt at a program to do so (with some test
data) might look like this:
@example
+@group
$ echo 'line 1
> line 2
> line 3' | awk '@{ l[lines] = $0; ++lines @}
@@ -9089,6 +9178,7 @@ $ echo 'line 1
> @}'
@print{} line 3
@print{} line 2
+@end group
@end example
Unfortunately, the very first line of input data did not come out in the
@@ -9646,7 +9736,7 @@ returns the string @w{@code{"pi = 3.14 (approx.)"}}.
null string when using closures like *. E.g.,
$ echo abc | awk '{ gsub(/m*/, "X"); print }'
- @print{} XaXbXc
+ @print{} XaXbXcX
Although this makes a certain amount of sense, it can be very
suprising.
@@ -9721,6 +9811,8 @@ an @samp{&}:
awk '@{ sub(/\|/, "\\&"); print @}'
@end example
+@cindex @code{sub}, third argument of
+@cindex @code{gsub}, third argument of
@strong{Note:} As mentioned above, the third argument to @code{sub} must
be a variable, field or array reference.
Some versions of @code{awk} allow the third argument to
@@ -9735,7 +9827,10 @@ sub(/USA/, "United States", "the USA and Canada")
@end example
@noindent
-This is considered erroneous in @code{gawk}.
+For historical compatibility, @code{gawk} will accept erroneous code,
+such as in the above example. However, using any other non-changeable
+object as the third parameter will cause a fatal error, and your program
+will not run.
@item gsub(@var{regexp}, @var{replacement} @r{[}, @var{target}@r{]})
@findex gsub
@@ -9834,6 +9929,23 @@ suffix is also returned
if @var{length} is greater than the number of characters remaining
in the string, counting from character number @var{start}.
+@strong{Note:} The string returned by @code{substr} @emph{cannot} be
+assigned to. Thus, it is a mistake to attempt to change a portion of
+a string, like this:
+
+@example
+string = "abcdef"
+# try to get "abCDEf", won't work
+substr(string, 3, 3) = "CDE"
+@end example
+
+@noindent
+or to use @code{substr} as the third agument of @code{sub} or @code{gsub}:
+
+@example
+gsub(/xyz/, "pdq", substr($0, 5, 20)) # WRONG
+@end example
+
@cindex case conversion
@cindex conversion of case
@item tolower(@var{string})
@@ -10117,7 +10229,7 @@ version of @code{awk}; it is not part of the POSIX standard, and will
not be available if @samp{--posix} has been specified on the command
line (@pxref{Options, ,Command Line Options}).
-@code{gawk} extends the @code{fflush} function in two ways. This first
+@code{gawk} extends the @code{fflush} function in two ways. The first
is to allow no argument at all. In this case, the buffer for the
standard output is flushed. The second way is to allow the null string
(@w{@code{""}}) as the argument. In this case, the buffers for
@@ -10157,6 +10269,53 @@ Some operating systems cannot implement the @code{system} function.
@end table
@c fakenode --- for prepinfo
+@subheading Interactive vs. Non-Interactive Buffering
+@cindex buffering, interactive vs. non-interactive
+@cindex buffering, non-interactive vs. interactive
+@cindex interactive buffering vs. non-interactive
+@cindex non-interactive buffering vs. interactive
+
+As a side point, buffering issues can be even more confusing depending
+upon whether or not your program is @dfn{interactive}, i.e., communicating
+with a user sitting at a keyboard.@footnote{A program is interactive
+if the standard output is connected
+to a terminal device.}
+
+Interactive programs generally @dfn{line buffer} their output; they
+write out every line. Non-interactive programs wait until they have
+a full buffer, which may be many lines of output.
+
+@c Thanks to Walter.Mecky@dresdnerbank.de for this example, and for
+@c motivating me to write this section.
+Here is an example of the difference.
+
+@example
+$ awk '@{ print $1 + $2 @}'
+1 1
+@print{} 2
+2 3
+@print{} 5
+@kbd{Control-d}
+@end example
+
+@noindent
+Each line of output is printed immediately. Compare that behavior
+with this example.
+
+@example
+$ awk '@{ print $1 + $2 @}' | cat
+1 1
+2 3
+@kbd{Control-d}
+@print{} 2
+@print{} 5
+@end example
+
+@noindent
+Here, no output is printed until after the @kbd{Control-D} is typed, since
+it is all buffered, and sent down the pipe to @code{cat} in one shot.
+
+@c fakenode --- for prepinfo
@subheading Controlling Output Buffering with @code{system}
@cindex flushing buffers
@cindex buffers, flushing
@@ -10311,9 +10470,9 @@ The locale's equivalent of the AM/PM designations associated
with a 12-hour clock.
@item %S
-The second as a decimal number (00--61).@footnote{Occasionally there are
-minutes in a year with one or two leap seconds, which is why the
-seconds can go up to 61.}
+The second as a decimal number (00--60).@footnote{Occasionally there are
+minutes in a year with a leap second, which is why the
+seconds can go up to 60.}
@item %U
The week number of the year (the first Sunday as the first day of week one)
@@ -10649,9 +10808,11 @@ This program prints, in our special format, all the third fields that
contain a positive number in our input. Therefore, when given:
@example
+@group
1.2 3.4 5.6 7.8
9.10 11.12 -13.14 15.16
17.18 19.20 21.22 23.24
+@end group
@end example
@noindent
@@ -10860,6 +11021,12 @@ If @samp{--lint} has been specified
(@pxref{Options, ,Command Line Options}),
@code{gawk} will report about calls to undefined functions.
+Some @code{awk} implementations generate a run-time
+error if you use the @code{next} statement
+(@pxref{Next Statement, , The @code{next} Statement})
+inside a user-defined function.
+@code{gawk} does not have this problem.
+
@node Return Statement, , Function Caveats, User-defined
@section The @code{return} Statement
@cindex @code{return} statement
@@ -11046,8 +11213,8 @@ The @samp{-v} option can only set one variable, but you can use
it more than once, setting another variable each time, like this:
@samp{awk @w{-v foo=1} @w{-v bar=2} @dots{}}.
-@item -mf=@var{NNN}
-@itemx -mr=@var{NNN}
+@item -mf @var{NNN}
+@itemx -mr @var{NNN}
Set various memory limits to the value @var{NNN}. The @samp{f} flag sets
the maximum number of fields, and the @samp{r} flag sets the maximum
record size. These two flags and the @samp{-m} option are from the
@@ -11058,9 +11225,7 @@ for compatibility, but otherwise ignored by
@item -W @var{gawk-opt}
@cindex @code{-W} option
Following the POSIX standard, options that are implementation
-specific are supplied as arguments to the @samp{-W} option. With @code{gawk},
-these arguments may be separated by commas, or quoted and separated by
-whitespace. Case is ignored when processing these options. These options
+specific are supplied as arguments to the @samp{-W} option. These options
also have corresponding GNU style long options.
See below.
@@ -11099,7 +11264,7 @@ which summarizes the extensions. Also see
@itemx --copyright
@cindex @code{--copyleft} option
@cindex @code{--copyright} option
-Print the short version of the General Public License.
+Print the short version of the General Public License, and then exit.
This option may disappear in a future version of @code{gawk}.
@item -W help
@@ -11142,6 +11307,10 @@ restrictions:
(@pxref{Escape Sequences}).
@item
+Newlines do not act as whitespace to separate fields when @code{FS} is
+equal to a single space.
+
+@item
The synonym @code{func} for the keyword @code{function} is not
recognized (@pxref{Definition Syntax, ,Function Definition Syntax}).
@@ -11396,7 +11565,8 @@ they will @emph{not} be in the next release).
@c update this section for each release!
-For version @value{VERSION} of @code{gawk}, there are no command line options
+For version @value{VERSION}.@value{PATCHLEVEL} of @code{gawk}, there are no
+command line options
or other deprecated features from the previous version of @code{gawk}.
@iftex
This section
@@ -11496,10 +11666,6 @@ Syntactically invalid single character programs tend to overflow
the parse stack, generating a rather unhelpful message. Such programs
are surprisingly difficult to diagnose in the completely general case,
and the effort to do so really is not worth it.
-
-@item
-The word ``GNU'' is incorrectly capitalized in at least one
-file in the source code.
@end itemize
@node Library Functions, Sample Programs, Invoking Gawk, Top
@@ -11532,6 +11698,8 @@ or assign the copyright in it to the Free Software Foundation.
function.
* Assert Function:: A function for assertions in @code{awk}
programs.
+* Round Function:: A function for rounding if @code{sprintf} does
+ not do it correctly.
* Ordinal Functions:: Functions for using characters as numbers and
vice versa.
* Join Function:: A function to join an array into a string.
@@ -11698,7 +11866,7 @@ next one, saving a lot of time. This is particularly important in
they spend most of their time doing input and output, instead of performing
computations).
-@node Assert Function, Ordinal Functions, Nextfile Function, Library Functions
+@node Assert Function, Round Function, Nextfile Function, Library Functions
@section Assertions
@cindex assertions
@@ -11804,19 +11972,63 @@ will attempt to read the input data files, or standard input
(@pxref{Using BEGIN/END, , Startup and Cleanup Actions}),
most likely causing the program to hang, waiting for input.
-@cindex backslash continuation
-Just a note on programming style. You may have noticed that the @code{END}
-rule uses backslash continuation, with the open brace on a line by
-itself. This is so that it more closely resembles the way functions
-are written. Many of the examples
-@iftex
-in this chapter and the next one
-@end iftex
-use this style. You can decide for yourself if you like writing
-your @code{BEGIN} and @code{END} rules this way,
-or not.
+@node Round Function, Ordinal Functions, Assert Function, Library Functions
+@section Rounding Numbers
+
+@cindex rounding
+The way @code{printf} and @code{sprintf}
+(@pxref{Printf, , Using @code{printf} Statements for Fancier Printing})
+do rounding will often depend
+upon the system's C @code{sprintf} subroutine.
+On many machines,
+@code{sprintf} rounding is ``unbiased,'' which means it doesn't always
+round a trailing @samp{.5} up, contrary to naive expectations. In unbiased
+rounding, @samp{.5} rounds to even, rather than always up, so 1.5 rounds to
+2 but 4.5 rounds to 4.
+The result is that if you are using a format that does
+rounding (e.g., @code{"%.0f"}) you should check what your system does.
+The following function does traditional rounding;
+it might be useful if your awk's @code{printf} does unbiased rounding.
+
+@findex round
+@example
+@c file eg/lib/round.awk
+# round --- do normal rounding
+#
+# Arnold Robbins, arnold@@gnu.ai.mit.edu, August, 1996
+# Public Domain
+
+function round(x, ival, aval, fraction)
+@{
+ ival = int(x) # integer part, int() truncates
+
+ # see if fractional part
+ if (ival == x) # no fraction
+ return x
+
+ if (x < 0) @{
+ aval = -x # absolute value
+ ival = int(aval)
+ fraction = aval - ival
+ if (fraction >= .5)
+ return int(x) - 1 # -2.5 --> -3
+ else
+ return int(x) # -2.3 --> -2
+ @} else @{
+ fraction = x - ival
+ if (fraction >= .5)
+ return ival + 1
+ else
+ return ival
+ @}
+@}
+
+# test harness
+@{ print $0, round($0) @}
+@c endfile
+@end example
-@node Ordinal Functions, Join Function, Assert Function, Library Functions
+@node Ordinal Functions, Join Function, Round Function, Library Functions
@section Translating Between Characters and Numbers
@cindex numeric character values
@@ -11835,7 +12047,7 @@ reason to build them into the @code{awk} interpreter.
@findex ord
@findex chr
@example
-@c @group
+@group
@c file eg/lib/ord.awk
# ord.awk --- do ord and chr
#
@@ -11851,7 +12063,7 @@ reason to build them into the @code{awk} interpreter.
BEGIN @{ _ord_init() @}
@c endfile
-@c @end group
+@end group
@c @group
@c file eg/lib/ord.awk
@@ -12202,7 +12414,7 @@ function mktime(str, res1, res2, a, b, i, j, t, diff)
a[3] < 1 || a[3] > 31 ||
a[4] < 0 || a[4] > 23 ||
a[5] < 0 || a[5] > 59 ||
- a[6] < 0 || a[6] > 61 )
+ a[6] < 0 || a[6] > 60 )
return -1
@end group
@@ -12649,11 +12861,13 @@ The discussion walks through the code a bit at a time.
# Initial version: March, 1991
# Revised: May, 1993
+@group
# External variables:
# Optind -- index of ARGV for first non-option argument
# Optarg -- string value of argument to current option
# Opterr -- if non-zero, print our own diagnostic
# Optopt -- current option letter
+@end group
# Returns
# -1 at end of options
@@ -12987,6 +13201,7 @@ $ pwcat
@print{} bin:*:3:3::/bin:
@print{} arnold:xyzzy:2076:10:Arnold Robbins:/home/arnold:/bin/sh
@print{} miriam:yxaay:112:10:Miriam Robbins:/home/miriam:/bin/sh
+@print{} andy:abcca2:113:10:Andy Jacobs:/home/andy:/bin/sh
@dots{}
@c @end group
@end example
@@ -13009,6 +13224,7 @@ BEGIN @{
@}
@end group
+@group
function _pw_init( oldfs, oldrs, olddol0, pwcat)
@{
if (_pw_inited)
@@ -13032,7 +13248,7 @@ function _pw_init( oldfs, oldrs, olddol0, pwcat)
$0 = olddol0
@}
@c endfile
-@c @end group
+@end group
@end example
The @code{BEGIN} rule sets a private variable to the directory where
@@ -13245,9 +13461,6 @@ return those group-id numbers in @code{$5} through @code{$NF}.
@pxref{Special Files, ,Special File Names in @code{gawk}}.)
@end table
-@iftex
-@page
-@end iftex
Here is what running @code{grcat} might produce:
@example
@@ -13713,6 +13926,7 @@ BEGIN \
if (c == "f") @{
by_fields = 1
fieldlist = Optarg
+@group
@} else if (c == "c") @{
by_chars = 1
fieldlist = Optarg
@@ -13732,6 +13946,7 @@ BEGIN \
else
usage()
@}
+@end group
for (i = 1; i < Optind; i++)
ARGV[i] = ""
@@ -13742,7 +13957,7 @@ BEGIN \
Special care is taken when the field delimiter is a space. Using
@code{@w{" "}} (a single space) for the value of @code{FS} is
incorrect---@code{awk} would
-separate fields with runs of spaces and/or tabs, and we want them to be
+separate fields with runs of spaces, tabs and/or newlines, and we want them to be
separated with individual spaces. Also, note that after @code{getopt} is
through, we have to clear out all the elements of @code{ARGV} from one to
@code{Optind}, so that @code{awk} will not try to process the command line
@@ -13845,7 +14060,7 @@ function set_charlist( field, i, j, f, g, t,
if (index(f[i], "-") != 0) @{ # range
m = split(f[i], g, "-")
if (m != 2 || g[1] >= g[2]) @{
- printf(bad character list: %s\n",
+ printf("bad character list: %s\n",
f[i]) > "/dev/stderr"
exit 1
@}
@@ -13941,6 +14156,8 @@ Normally, @code{egrep} prints the
lines that matched. If multiple file names are provided on the command
line, each output line is preceded by the name of the file and a colon.
+@c NEEDED
+@page
The options are:
@table @code
@@ -14072,14 +14289,14 @@ does is initialize a variable @code{fcount} to zero. @code{fcount} tracks
how many lines in the current file matched the pattern.
@example
-@c @group
+@group
@c file eg/prog/egrep.awk
function beginfile(junk)
@{
fcount = 0
@}
@c endfile
-@c @end group
+@end group
@end example
The @code{endfile} function is called after each file has been processed.
@@ -14155,8 +14372,10 @@ necessary.
fcount += matches # 1 or 0
+@group
if (! matches)
next
+@end group
if (no_print && ! count_only)
nextfile
@@ -14212,6 +14431,18 @@ function usage( e)
The variable @code{e} is used so that the function fits nicely
on the printed page.
+@cindex backslash continuation
+Just a note on programming style. You may have noticed that the @code{END}
+rule uses backslash continuation, with the open brace on a line by
+itself. This is so that it more closely resembles the way functions
+are written. Many of the examples
+@iftex
+in this chapter
+@end iftex
+use this style. You can decide for yourself if you like writing
+your @code{BEGIN} and @code{END} rules this way,
+or not.
+
@node Id Program, Split Program, Egrep Program, Clones
@subsection Printing Out User Information
@@ -14597,9 +14828,9 @@ Count lines. This option overrides @samp{-d} and @samp{-u}. Both repeated
and non-repeated lines are counted.
@item -@var{n}
-Skip @var{n} fields before comparing lines. The definition of fields is the
-same as @code{awk}'s default: non-whitespace characters separated by runs of
-spaces and/or tabs.
+Skip @var{n} fields before comparing lines. The definition of fields
+is similar to @code{awk}'s default: non-whitespace characters separated
+by runs of spaces and/or tabs.
@item +@var{n}
Skip @var{n} characters before comparing lines. Any fields specified with
@@ -14650,18 +14881,22 @@ standard output, @file{/dev/stdout}.
# Arnold Robbins, arnold@@gnu.ai.mit.edu, Public Domain
# May 1993
+@group
function usage( e)
@{
e = "Usage: uniq [-udc [-n]] [+n] [ in [ out ]]"
print e > "/dev/stderr"
exit 1
@}
+@end group
+@group
# -c count lines. overrides -d and -u
# -d only repeated lines
# -u only non-repeated lines
# -n skip n fields
# +n skip n characters, skip fields first
+@end group
BEGIN \
@{
@@ -14699,13 +14934,14 @@ BEGIN \
if (repeated_only == 0 && non_repeated_only == 0)
repeated_only = non_repeated_only = 1
+@group
if (ARGC - Optind == 2) @{
outputfile = ARGV[ARGC - 1]
ARGV[ARGC - 1] = ""
@}
@}
@c endfile
-@c @end group
+@end group
@end example
The following function, @code{are_equal}, compares the current line,
@@ -14906,7 +15142,7 @@ BEGIN @{
if (! do_lines && ! do_words && ! do_chars)
do_lines = do_words = do_chars = 1
- print_total = (ARC - i > 2)
+ print_total = (ARGC - i > 2)
@}
@c endfile
@c @end group
@@ -15029,6 +15265,7 @@ that punctuation does not affect the comparison either. This sometimes
leads to reports of duplicated words that really are different, but this is
unusual.
+@c FIXME: add check for $i != ""
@findex dupword.awk
@example
@group
@@ -15495,9 +15732,6 @@ as the same word. This is undesirable since, in normal text, words
are capitalized if they begin sentences, and a frequency analyzer should not
be sensitive to capitalization.
-@iftex
-@page
-@end iftex
@item
The output does not come out in any useful order. You're more likely to be
interested in which words occur most frequently, or having an alphabetized
@@ -15782,9 +16016,9 @@ line. That line is then printed to the output file.
@example
@c @group
@c file eg/prog/extract.awk
+@group
/^@@c(omment)?[ \t]+file/ \
@{
-@group
if (NF != 3) @{
e = (FILENAME ":" FNR ": badly formed `file' line")
print e > "/dev/stderr"
@@ -15899,11 +16133,13 @@ are provided, the standard input is used.
# Arnold Robbins, arnold@@gnu.ai.mit.edu, Public Domain
# August 1995
+@group
function usage()
@{
print "usage: awksed pat repl [files...]" > "/dev/stderr"
exit 1
@}
+@end group
BEGIN @{
# validate arguments
@@ -16096,9 +16332,6 @@ argument (e.g., @samp{--file=}).
@itemx -Wsource=
The source text is echoed into @file{/tmp/ig.s.$$}.
-@iftex
-@page
-@end iftex
@item --version
@itemx --version
@itemx -Wversion
@@ -16160,8 +16393,10 @@ do
-f) echo @@include "$2" >> /tmp/ig.s.$$
shift;;
+@group
-f*) f=`echo "$1" | sed 's/-f//'`
echo @@include "$f" >> /tmp/ig.s.$$ ;;
+@end group
-?file=*) # -Wfile or --file
f=`echo "$1" | sed 's/-.file=//'`
@@ -16270,7 +16505,7 @@ splitting the path on @samp{:}, null elements are replaced with @code{"."},
which represents the current directory.
@example
-@c @group
+@group
@c file eg/prog/igawk.sh
BEGIN @{
path = ENVIRON["AWKPATH"]
@@ -16280,7 +16515,7 @@ BEGIN @{
pathlist[i] = "."
@}
@c endfile
-@c @end group
+@end group
@end example
The stack is initialized with @code{ARGV[1]}, which will be @file{/tmp/ig.s.$$}.
@@ -16443,7 +16678,7 @@ of the @value{DOCUMENT} where you can find more information.
* SVR4:: Minor changes between System V Releases 3.1
and 4.
* POSIX:: New features from the POSIX standard.
-* BTL:: New features from the AT&T Bell Laboratories
+* BTL:: New features from the Bell Laboratories
version of @code{awk}.
* POSIX/GNU:: The extensions in @code{gawk} not in POSIX
@code{awk}.
@@ -16617,6 +16852,10 @@ standard:
(@pxref{Escape Sequences}).
@item
+Newlines do not act as whitespace to separate fields when @code{FS} is
+equal to a single space.
+
+@item
The synonym @code{func} for the keyword @code{function} is not
recognized (@pxref{Definition Syntax, ,Function Definition Syntax}).
@@ -16636,7 +16875,7 @@ The @code{fflush} built-in function is not supported
@end itemize
@node BTL, POSIX/GNU, POSIX, Language History
-@section Extensions in the AT&T Bell Laboratories @code{awk}
+@section Extensions in the Bell Laboratories @code{awk}
@cindex Kernighan, Brian
Brian Kernighan, one of the original designers of Unix @code{awk},
@@ -16647,7 +16886,7 @@ not in POSIX @code{awk}.
@itemize @bullet
@item
-The @samp{-mf=@var{NNN}} and @samp{-mr=@var{NNN}} command line options
+The @samp{-mf @var{NNN}} and @samp{-mr @var{NNN}} command line options
to set the maximum number of fields, and the maximum
record size, respectively
(@pxref{Options, ,Command Line Options}).
@@ -16868,8 +17107,8 @@ predefined variable).
Read the @code{awk} program source from the file @var{program-file}, instead
of from the first command line argument.
-@item -mf=@var{NNN}
-@itemx -mr=@var{NNN}
+@item -mf @var{NNN}
+@itemx -mr @var{NNN}
The @samp{f} flag sets
the maximum number of fields, and the @samp{r} flag sets the maximum
record size. These options are ignored by @code{gawk}, since @code{gawk}
@@ -16892,14 +17131,15 @@ off.
@itemx -W copyright
@itemx --copyleft
@itemx --copyright
-Print the short version of the General Public License on the error
-output. This option may disappear in a future version of @code{gawk}.
+Print the short version of the General Public License on the standard
+output, and exit. This option may disappear in a future version of @code{gawk}.
@item -W help
@itemx -W usage
@itemx --help
@itemx --usage
-Print a relatively short summary of the available options on the error output.
+Print a relatively short summary of the available options on the standard
+output, and exit.
@item -W lint
@itemx --lint
@@ -17019,7 +17259,8 @@ As each input line is read, @code{gawk} splits the line into
separator. If @code{FS} is a single character, fields are separated by
that character. Otherwise, @code{FS} is expected to be a full regular
expression. In the special case that @code{FS} is a single space,
-fields are separated by runs of spaces and/or tabs.
+fields are separated by runs of spaces, tabs and/or newlines.@footnote{In
+POSIX @code{awk}, newline does not separate fields.}
If @code{FS} is the null string (@code{""}), then each individual
character in the record becomes a separate field.
Note that the value
@@ -17045,6 +17286,9 @@ the null string. However, assigning to a non-existent field (e.g.,
intervening fields with the null string as their value, and causes the
value of @code{$0} to be recomputed, with the fields being separated by
the value of @code{OFS}.
+Decrementing @code{NF} causes the values of fields past the new value to
+be lost, and the value of @code{$0} to be recomputed, with the fields being
+separated by the value of @code{OFS}.
@xref{Reading Files, ,Reading Input Files}.
@node Built-in Summary, Arrays Summary, Fields Summary, Variables/Fields
@@ -17361,12 +17605,13 @@ are @code{alnum}, @code{alpha}, @code{blank}, @code{cntrl},
matches the multi-character collating symbol @var{symbol}.
@code{gawk} does not currently support collating symbols.
-@item [[=@var{chars}=]]
-matches any of the equivalent characters in @var{chars}.
+@item [[=@var{classname}=]]
+matches any of the equivalent characters in the current locale named by the
+equivalence class @var{classname}.
@code{gawk} does not currently support equivalence classes.
@item [^@var{abc}@dots{}]
-matches any character except @var{abc}@dots{} and newline (negated
+matches any character except @var{abc}@dots{} (negated
character list).
@item @var{r1}|@var{r2}
@@ -17586,7 +17831,7 @@ Set @code{$0} from next input record; set @code{NF}, @code{NR}, @code{FNR}.
Set @code{$0} from next record of @var{file}; set @code{NF}.
@item getline @var{var}
-Set @var{var} from next input record; set @code{NF}, @code{FNR}.
+Set @var{var} from next input record; set @code{NR}, @code{FNR}.
@item getline @var{var} <@var{file}
Set @var{var} from next record of @var{file}.
@@ -17832,7 +18077,7 @@ The built-in arithmetic functions are:
the arctangent of @var{y/x} in radians.
@item cos(@var{expr})
-the cosine in radians.
+the cosine of @var{expr}, which is in radians.
@item exp(@var{expr})
the exponential function (@code{e ^ @var{expr}}).
@@ -17847,7 +18092,7 @@ the natural logarithm of @code{expr}.
a random number between zero and one.
@item sin(@var{expr})
-the sine in radians.
+the sine of @var{expr}, which is in radians.
@item sqrt(@var{expr})
the square root function.
@@ -17858,9 +18103,6 @@ is provided, the time of day is used. The return value is the previous
seed for the random number generator.
@end table
-@iftex
-@page
-@end iftex
@code{awk} has the following built-in string functions:
@table @code
@@ -17873,6 +18115,7 @@ original @var{target} is not modified. Within @var{subst},
@samp{\@var{n}}, where @var{n} is a digit from one to nine, can be used to
indicate the text that matched the @var{n}'th parenthesized
subexpression.
+This function is @code{gawk}-specific.
@item gsub(@var{regex}, @var{subst} @r{[}, @var{target}@r{]})
for each substring matching the regular expression @var{regex} in the string
@@ -17946,6 +18189,7 @@ output. This is more portable, but less obvious, than calling @code{fflush}.
The following two functions are available for getting the current
time of day, and for formatting time stamps.
+They are specific to @code{gawk}.
@table @code
@item systime()
@@ -18247,9 +18491,8 @@ You should use a site that is geographically close to you.
@itemx ftp.kpc.com:/pub/mirror/gnu
@end table
-@iftex
+@c NEEDED
@page
-@end iftex
@item USA (continued):
@table @code
@itemx ftp.uu.net:/systems/gnu
@@ -18269,17 +18512,17 @@ You should use a site that is geographically close to you.
GNU Zip program, @code{gzip}.
Once you have the distribution (for example,
-@file{gawk-@value{VERSION}.0.tar.gz}), first use @code{gzip} to expand the
+@file{gawk-@value{VERSION}.@value{PATCHLEVEL}.tar.gz}), first use @code{gzip} to expand the
file, and then use @code{tar} to extract it. You can use the following
pipeline to produce the @code{gawk} distribution:
@example
# Under System V, add 'o' to the tar flags
-gzip -d -c gawk-@value{VERSION}.0.tar.gz | tar -xvpf -
+gzip -d -c gawk-@value{VERSION}.@value{PATCHLEVEL}.tar.gz | tar -xvpf -
@end example
@noindent
-This will create a directory named @file{gawk-@value{VERSION}.0} in the current
+This will create a directory named @file{gawk-@value{VERSION}.@value{PATCHLEVEL}} in the current
directory.
The distribution file name is of the form
@@ -18312,9 +18555,6 @@ operating systems.
These files are the actual @code{gawk} source code.
@end table
-@iftex
-@page
-@end iftex
@table @file
@item README
@itemx README_d/README.*
@@ -18357,6 +18597,25 @@ incorrect, and how @code{gawk} handles the problem.
@item PROBLEMS
A file describing known problems with the current release.
+@cindex artificial intelligence, using @code{gawk}
+@cindex AI programming, using @code{gawk}
+@item doc/awkforai.txt
+A short article describing why @code{gawk} is a good language for
+AI (Artificial Intelligence) programming.
+
+@item doc/README.card
+@itemx doc/ad.block
+@itemx doc/awkcard.in
+@itemx doc/cardfonts
+@itemx doc/colors
+@itemx doc/macros
+@itemx doc/no.colors
+@itemx doc/setter.outline
+The @code{troff} source for a five-color @code{awk} reference card.
+A modern version of @code{troff}, such as GNU Troff (@code{groff}) is
+needed to produce the color version. See the file @file{README.card}
+for instructions if you have an older @code{troff}.
+
@item doc/gawk.1
The @code{troff} source for a manual page describing @code{gawk}.
This is distributed for the convenience of Unix users.
@@ -18445,7 +18704,7 @@ to configure @code{gawk} for your system yourself.
@cindex installation, unix
After you have extracted the @code{gawk} distribution, @code{cd}
-to @file{gawk-@value{VERSION}.0}. Like most GNU software,
+to @file{gawk-@value{VERSION}.@value{PATCHLEVEL}}. Like most GNU software,
@code{gawk} is configured
automatically for your Unix system by running the @code{configure} program.
This program is a Bourne shell script that was generated automatically using
@@ -18699,33 +18958,29 @@ translation, and not a multi-translation @code{RMS} searchlist.
@appendixsubsec Building and Using @code{gawk} on VMS POSIX
Ignore the instructions above, although @file{vms/gawk.hlp} should still
-be made available in a help library. Make sure that the @code{configure}
-script is executable; use @samp{chmod +x}
-on it if necessary. Then execute the following commands:
+be made available in a help library. The source tree should be unpacked
+into a container file subsystem rather than into the ordinary VMS file
+system. Make sure that the two scripts, @file{configure} and
+@file{vms/posix-cc.sh}, are executable; use @samp{chmod +x} on them if
+necessary. Then execute the following two commands:
@example
@group
-$ POSIX
psx> CC=vms/posix-cc.sh configure
-psx> CC=c89 make gawk
+psx> make CC=c89 gawk
@end group
@end example
@noindent
-The first command will construct files @file{config.h} and @file{Makefile}
-out of templates. The second command will compile and link @code{gawk}.
-@ignore
-Due to a @code{make} bug in VMS POSIX V1.0 and V1.1,
-the file @file{awktab.c} must be given as an explicit target or it will
-not be built and the final link step will fail.
-@end ignore
-Ignore the warning
-@code{"Could not find lib m in lib list"}; it is harmless, caused by the
-explicit use of @samp{-lm} as a linker option which is not needed
-under VMS POSIX. Under V1.1 (but not V1.0) a problem with the @code{yacc}
-skeleton @file{/etc/yyparse.c} will cause a compiler warning for
-@file{awktab.c}, followed by a linker warning about compilation warnings
-in the resulting object module. These warnings can be ignored.
+The first command will construct files @file{config.h} and @file{Makefile} out
+of templates, using a script to make the C compiler fit @code{configure}'s
+expectations. The second command will compile and link @code{gawk} using
+the C compiler directly; ignore any warnings from @code{make} about being
+unable to redefine @code{CC}. @code{configure} will take a very long
+time to execute, but at least it provides incremental feedback as it
+runs.
+
+This has been tested with VAX/VMS V6.2, VMS POSIX V2.0, and DEC C V5.2.
Once built, @code{gawk} will work like any other shell utility. Unlike
the normal VMS port of @code{gawk}, no special command line manipulation is
@@ -18774,7 +19029,8 @@ Microsoft C can be used to build 16-bit versions for MS-DOS and OS/2. The file
@file{README_d/README.pc} in the @code{gawk} distribution contains additional
notes, and @file{pc/Makefile} contains important notes on compilation options.
-To build @code{gawk}, copy the files in the @file{pc} directory to the
+To build @code{gawk}, copy the files in the @file{pc} directory (@emph{except}
+for @file{ChangeLog}) to the
directory with the rest of the @code{gawk} sources. The @file{Makefile}
contains a configuration section with comments, and may need to be
edited in order to work with your @code{make} utility.
@@ -18926,12 +19182,15 @@ A more complete distribution for the Amiga is available on
the FreshFish CD-ROM from:
@quotation
-Amiga Library Services @*
-610 North Alma School Road, Suite 18 @*
-Chandler, AZ 85224 USA @*
-Phone: +1-602-491-0048 @*
+CRONUS @*
+1840 E. Warner Road #105-265 @*
+Tempe, AZ 85284 USA @*
+US Toll Free: (800) 804-0833 @*
+Phone: +1-602-491-0442 @*
FAX: +1-602-491-0048 @*
-E-mail: @code{orders@@amigalib.com}
+Email: @code{info@@ninemoons.com} @*
+WWW: @code{http://www.ninemoons.com} @*
+Anonymous @code{ftp} site: @code{ftp.ninemoons.com} @*
@end quotation
Once you have the distribution, you can configure @code{gawk} simply by
@@ -18997,7 +19256,7 @@ mail at the Internet address above.
If you find bugs in one of the non-Unix ports of @code{gawk}, please send
an electronic mail message to the person who maintains that port. They
are listed below, and also in the @file{README} file in the @code{gawk}
-distribution. Information in the @code{README} file should be considered
+distribution. Information in the @file{README} file should be considered
authoritative if it conflicts with this @value{DOCUMENT}.
The people maintaining the non-Unix ports of @code{gawk} are:
@@ -19023,7 +19282,7 @@ Pat Rankin, @samp{rankin@@eql.caltech.edu}.
Michal Jaegermann, @samp{michal@@gortel.phys.ualberta.ca}.
@item Amiga
-Fred Fish, @samp{fnf@@amigalib.com}.
+Fred Fish, @samp{fnf@@ninemoons.com}.
@end table
If your bug is also reproducible under Unix, please send copies of your
@@ -19033,6 +19292,20 @@ addresses listed above.
@node Other Versions, , Bugs, Installation
@appendixsec Other Freely Available @code{awk} Implementations
+@cindex Brennan, Michael
+@display
+@ignore
+From: emory!amc.com!brennan (Michael Brennan)
+Subject: C++ comments in awk programs
+To: arnold@gnu.ai.mit.edu (Arnold Robbins)
+Date: Wed, 4 Sep 1996 08:11:48 -0700 (PDT)
+
+@end ignore
+@i{It's kind of fun to put comments like this in your awk code.}
+ @code{// Do C++ comments work? answer: yes! of course}
+Michael Brennan
+@end display
+
There are two other freely available @code{awk} implementations.
This section briefly describes where to get them.
@@ -19063,9 +19336,9 @@ called @code{mawk}. It is available under the GPL
just as @code{gawk} is.
You can get it via anonymous @code{ftp} to the host
-@code{@w{oxy.edu}}. Change directory to @file{/public}. Use ``binary''
-or ``image'' mode, and retrieve @file{mawk1.2.1.tar.gz} (or the latest
-version that is there).
+@code{@w{ftp.whidbey.net}}. Change directory to @file{/pub/brennan}.
+Use ``binary'' or ``image'' mode, and retrieve @file{mawk1.3.3.tar.gz}
+(or the latest version that is there).
@code{gunzip} may be used to decompress this file. Installation
is similar to @code{gawk}'s
@@ -19215,6 +19488,11 @@ Provide one-line descriptive comments for each function.
@item
Do not use @samp{#elif}. Many older Unix C compilers cannot handle it.
+
+@item
+Do not use the @code{alloca} function for allocating memory off the stack.
+Its use causes more portability trouble than the minor benefit of not having
+to free the storage. Instead, use @code{malloc} and @code{free}.
@end itemize
If I have to reformat your code to follow the coding style used in
@@ -19359,10 +19637,6 @@ operating systems that is already there.
In the code that you supply, and that you maintain, feel free to use a
coding style and brace layout that suits your taste.
-@c why should this be needed? sigh
-@iftex
-@page
-@end iftex
@node Future Extensions, Improvements, Additions, Notes
@appendixsec Probable Future Extensions
@@ -19486,10 +19760,6 @@ The @code{dfa} pattern matcher from GNU @code{grep} has some
problems. Either a new version or a fixed one will deal with some
important regexp matching issues.
-@item Use of @code{mmap}
-On systems that support the @code{mmap} system call, its use would provide
-much faster file input, and considerably simplified input buffer management.
-
@item Use of GNU @code{malloc}
The GNU version of @code{malloc} could potentially speed up @code{gawk},
since it relies heavily on the use of dynamic memory allocation.
@@ -19967,8 +20237,8 @@ versions of Unix, as well as several work-alike systems whose source code
is freely available (such as Linux, NetBSD, and FreeBSD).
@item Whitespace
-A sequence of space or tab characters occurring inside an input record or a
-string.
+A sequence of space, tab, or newline characters occurring inside an input
+record or a string.
@end table
@node Copying, Index, Glossary, Top
@@ -20410,8 +20680,7 @@ Consistency issues:
Use alphanumeric, not alpha-numeric
Use --foo, not -Wfoo when describing long options
Use findex for all programs and functions in the example chapters
- Use "Bell Labs" or "AT&T Bell Laboratories", but not
- "AT&T Bell Labs".
+ Use "Bell Laboratories", but not "Bell Labs".
Use "behavior" instead of "behaviour".
Use "zeros" instead of "zeroes".
Use "Input/Output", not "input/output". Also "I/O", not "i/o".
diff --git a/doc/macros b/doc/macros
new file mode 100644
index 00000000..bdfc5c8c
--- /dev/null
+++ b/doc/macros
@@ -0,0 +1,211 @@
+.\" SSC Reference card macros
+.\"
+.\" Copyright (C) 1996, Specialized System Consultants Inc. (SSC)
+.\"
+.\" These macros are free software; you can redistribute them and/or modify
+.\" them under the terms of the GNU General Public License as published by
+.\" the Free Software Foundation; either version 2 of the License, or
+.\" (at your option) any later version.
+.\"
+.\" These macros are distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program; if not, write to the Free Software
+.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+.\"
+.\" Generic SSC "card" macros
+.\" based on lots of other macros
+.\" Last update: 4-25-91 ph
+.\" attempting to get margins in the boxes Aug 3 09:43:48 PDT 1994
+.ll 3i \" length of text line
+.lt 3.2i \" length of title line
+.de BT \" bottom of page trap
+.sp |8.2i \" go to where we put footer
+.ie \\n(CL=1 \{\
+. nr CL 2
+.tl ''\\*(CD\\n+(PN'' \" footer is just page number
+. po 4i \" go to second column
+.TP \" print header if any
+\}
+.el \{\
+. nr CL 1
+.tl ''\\*(CD\\n+(PN'' \" footer is just page number
+. po .5i \" go to first column
+. bp \" force a new page (which will force header)
+. TP
+\}
+..
+.de TP \" top of page
+.\" .sp |.2i
+.sp |0
+.\" put page header stuff here
+.\" for example: .tl ''WOW!''
+.\".sp
+..
+.\" .wh 8.1i BT \" set bottom of column trap
+.nf \" don't fill lines
+.nh \" no hyphenation
+.nr CL 1 \" start with column = 1
+.po .5i \" offset for first column
+.vs 9 \" line spacing
+.ps 8 \" point size
+.de ST \" set tabs to normal places
+.ta .2i .78i 1.2i 1.7i \" set tabs
+..
+.ig
+ From: bryang@chinet.chi.il.us (Bryan Glennon)
+ Box macro. Do a .mk z where the box is to start, and a .eb
+ where it is to end. Optional argument is a title to be centered
+ within the top box line.
+
+ Usage:
+
+ .mk z
+ Text, etc to be boxed...
+ .eb "Optional title goes here"
+
+ ~or~
+
+ .mk z
+ Text, etc to be boxed...
+ .eb
+
+
+ Some explanation:
+ The macro name is eb <.de eb>. First thing we do is to go up on line
+ <.sp -1> and turn off fill mode <.nf>. Now it gets interesting: the
+ .ie is the if/else construct. We check the number of arguments provided
+ to the macro <\\n(.$> and if it is greater than 0 (meaning we have a title),
+ we do the rest of the .ie line, as follows:
+
+ \h'-.5n' - move left one-half of an n
+ \L'|\\nzu-1' - draw a vertical line <\L> to the
+ absolute position (|) given by \\nzu-1,
+ which is the position set with the .mk
+ command into register z <\\nz> in base
+ units <u> minus 1.
+ \l'(\\n(.lu+1n-\w'\\$1'u/2u)\(ul' - Draw a horizontal line <\l> with length
+ equal to the current line length
+ <\\n(.l> in base units <u> plus the
+ space required for an 'n' <1n>, minus
+ the width <\w> of the title string
+ <\\$1> in base units <u> divided by 2
+ <in base units <u>>. Draw the line
+ using the underline character, <\(ul>.
+ \v'.3m'\|\\$1\|\v'-.3m' - Move down the page 3/10 of an m,
+ <\v'.3m'>, output a 1/6 of an m space
+ <\|>, output the title <\\$1>, another
+ 1/6 of an m space <\|>, and then move
+ up the page 3/10 of an m <\v'-.3m'>.
+ \l'...\(ul' - Draw the second part of the line, just
+ like the corresponding left half done
+ before.
+ \L'-|\\nzu+1' - Draw a verticle line <\L> going down
+ the absolute distance <-|> from where
+ the macro was given to where the start
+ point was marked <\\nz> in base units
+ <u> plus one line <+1>
+ \l'|0u-.5n\(ul' - Draw a horizontal line to the absolute
+ position (|0) when the macro was
+ invoked, minus half an n <-.5n> using
+ the underline character <\(ul>.
+
+ The .el beings the else part, which is identical to the above, except
+ the string dosen't get printed. This makes the printing of the top
+ line much easier: just draw a line <\l> with width equal to the
+ current line plus the witdh of an n <\\n(.l+1n> using the underline
+ character <.\(ul>.
+..
+.de ES \" start "text in a box"
+.mk z
+.in +.5n
+.ll -.5n
+.sp 1.3
+..
+.de EB \" end "text in a box" -- optional box title as argument
+.sp -.6
+.nf
+.in -.5n
+.ll +.5n
+.ie \\n(.$\
+\L'|\\nzu'\
+\l'(\\n(.lu-\w'\\$1'u)/2u-.33m\(ul'\
+\v'.3m'\|\\$1\|\v'-.3m'\
+\l'(\\n(.lu-\w'\\$1'u)/2u\(ul'\
+\L'-|\\nzu'\
+\l'|0u\(ul'
+.el \h'-.5n'\L'|\\nzu-1'\l'\\n(.lu+1n\(ul'\L'-|\\nzu+1'\l'|0u-.5n\(ul'
+.in 0
+..
+.de SL \" draw single line (works in non-fill mode only)
+.sp -.8
+.ti 0
+\l'\\n(.lu\(ul'
+..
+.de Hl \" draw horizontal line
+.br
+.ti 0
+\l'\\n(.lu-\\n(.iu'
+.br
+..
+.de DL \" draw double line (works in non-fill mode only)
+.sp -.8
+.ti 0
+\l'\\n(.lu\(ul'
+.sp -.8
+.ti 0
+\l'\\n(.lu\(ul'
+..
+.ST
+.nr PN 0 1 \" sets starting page number and auto-increment
+.\" must define page header (if any) before here
+.TP
+.ds 3) \|\v'3p'\s+5\z\(sq\s0\v'-3p'\h'1.25p'\v'-.5p'3\v'.5p'\h'2p'
+.\" old one .ds 2) \h'-1.5p'\v'1p'\s+4\z\(ci\s0\v'-1p'\h'3.25p'2
+.ds 2) \|\v'-2.4p'\D'c.095id'\h'-5.15p'\v'2.4p'2\h'1.9p'
+.ds dC \v'1p'\s+5\(bu\s0\v'-1p'\" for development commands
+.ds tC \s+2\(dm\s0\" (for DWB) should be a triangle
+.ds tP \s+2\(dm\s0\" (for other text processing) should be a triangle
+.\" various trademark symbols
+.ds Tm \v'-0.5m'\s8TM\s0\v'0.5m'
+.ds Ts \v'-0.5m'\s4TM\s0\v'0.5m'
+.ig ++
+.\" mount Serifa fonts
+.fp 5 SR
+.fp 6 SB
+.fp 4 Si
+.++
+.\" other assorted junk
+.lg 0
+.\" Fl requires extended version of troff
+.de Fl \" draw fat horizontal line
+.br
+.ti 0
+.ruw 1.5p
+\l'\\n(.lu-\\n(.iu'
+.br
+.ruw
+..
+.de Bx \" box for keys in text
+\\$3\&\|\&\c
+\s-3\(br\|\fH\v'.18n'\\$1\v'-.18n\fP\|\(br\l'|0\(rn'\l'|0\(ul'\&\s0\|\\$2
+..
+.de Fn \" function name - left justified, gray background
+.\" bold with gray for function name
+.ns
+.br
+\
+.ns
+.br
+\!! gsave ( ) stringwidth neg 0 rmoveto
+\!! /Serifa-Bold findfont 8 scalefont setfont
+\!! (\\$1) dup stringwidth pop 6 gsave dup 0 exch rlineto neg exch 0 rlineto
+\!! 0 exch rlineto closepath .9 setgray fill grestore show
+\!! grestore
+.nf
+.rs
+..
+.rs
diff --git a/doc/no.colors b/doc/no.colors
new file mode 100644
index 00000000..4e0d0c62
--- /dev/null
+++ b/doc/no.colors
@@ -0,0 +1,31 @@
+.\" AWK Reference Card --- Arnold Robbins, arnold@gnu.ai.mit.edu
+.\" This file is for troff which does not know what to do
+.\" with a literal Poscript and cannot use macros from 'colors'.
+.\"
+.\" Copyright (C) 1996 Free Software Foundation, Inc.
+.\"
+.\" Permission is granted to make and distribute verbatim copies of
+.\" this reference card provided the copyright notice and this permission
+.\" notice are preserved on all copies.
+.\"
+.\" Permission is granted to process this file through troff and print the
+.\" results, provided the printed document carries copying permission
+.\" notice identical to this one except for the removal of this paragraph
+.\" (this paragraph not being relevant to the printed reference card).
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" reference card under the conditions for verbatim copying, provided that
+.\" the entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one.
+.\"
+.\" Permission is granted to copy and distribute translations of this
+.\" reference card into another language, under the above conditions for
+.\" modified versions, except that this permission notice may be stated in
+.\" a translation approved by the Foundation.
+.\"
+.ds CR
+.ds CG
+.ds CL
+.ds CB
+.ds CD
+.ds CX
diff --git a/doc/setter.outline b/doc/setter.outline
new file mode 100644
index 00000000..67ade73a
--- /dev/null
+++ b/doc/setter.outline
@@ -0,0 +1,77 @@
+%!PS-Adobe-3.0
+% SSC Reference card typesetter outline / cut marks
+%
+% Copyright (C) 1996, Specialized System Consultants Inc. (SSC)
+%
+% This file is free software; you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation; either version 2 of the License, or
+% (at your option) any later version.
+%
+% This file is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program; if not, write to the Free Software
+% Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+%
+%! page cut marks and stuff for Pocket References - 10-26-88 - ph
+%! modified to move the cut marks onto the page
+%! center a string
+/inch {72 mul} def
+/cshow % stk: string
+ % center string in space (space us variable)
+ {
+ dup stringwidth pop % get length of string
+ space exch sub 2 div % compute initial space needed
+ 0 rmoveto % move over
+ show
+ } def
+
+/flashme
+{ /space 612 def
+ 0 0 0 setrgbcolor % always print this stuff
+
+ /Helvetica findfont 12 scalefont setfont
+ gsave
+% for groff (I hope)
+ -6 -6 translate
+ 0.2 setlinewidth
+
+ 0.25 inch 10.5 inch moveto
+ 0.5 inch 10.5 inch lineto
+ .75 inch 10.75 inch moveto
+ .75 inch 11 inch lineto
+ stroke
+
+ 0.25 inch 2 inch moveto
+ 0.5 inch 2 inch lineto
+ .75 inch 1.75 inch moveto
+ .75 inch 1.50 inch lineto
+ stroke
+ 4.25 inch 11 inch moveto
+ 4.25 inch 10.75 inch lineto
+ stroke
+
+ 4.25 inch 1.75 inch moveto
+ 4.25 inch 1.5 inch lineto
+ stroke
+
+ 7.75 inch 1.5 inch moveto
+ 7.75 inch 1.75 inch lineto
+ 8 inch 2 inch moveto
+ 8.25 inch 2 inch lineto
+ stroke
+
+ 7.75 inch 11 inch moveto
+ 7.75 inch 10.75 inch lineto
+ 8 inch 10.5 inch moveto
+ 8.25 inch 10.5 inch lineto
+ stroke
+ grestore
+ } def
+
+% actually do something
+
diff --git a/doc/texinfo.tex b/doc/texinfo.tex
index ea80e1d0..f9254e77 100644
--- a/doc/texinfo.tex
+++ b/doc/texinfo.tex
@@ -1,6 +1,8 @@
-%% TeX macros to handle texinfo files
+%% TeX macros to handle Texinfo files.
+%% $Id: texinfo.tex,v 2.193 1996/11/19 21:11:43 karl Exp $
-% Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 1994 Free Software Foundation, Inc.
+% Copyright (C) 1985, 86, 88, 90, 91, 92, 93,
+% 94, 95, 1996 Free Software Foundation, Inc.
%This texinfo.tex file is free software; you can redistribute it and/or
%modify it under the terms of the GNU General Public License as
@@ -34,7 +36,7 @@
% This automatically updates the version number based on RCS.
\def\deftexinfoversion$#1: #2 ${\def\texinfoversion{#2}}
-\deftexinfoversion$Revision: 2.159 $
+\deftexinfoversion$Revision: 2.193 $
\message{Loading texinfo package [Version \texinfoversion]:}
% If in a .fmt file, print the version number
@@ -45,20 +47,20 @@
% Save some parts of plain tex whose names we will redefine.
-\let\ptextilde=\~
-\let\ptexlbrace=\{
-\let\ptexrbrace=\}
-\let\ptexdots=\dots
-\let\ptexdot=\.
-\let\ptexstar=\*
-\let\ptexend=\end
-\let\ptexbullet=\bullet
\let\ptexb=\b
+\let\ptexbullet=\bullet
\let\ptexc=\c
+\let\ptexcomma=\,
+\let\ptexdot=\.
+\let\ptexdots=\dots
+\let\ptexend=\end
+\let\ptexequiv = \equiv
\let\ptexi=\i
+\let\ptexlbrace=\{
+\let\ptexrbrace=\}
+\let\ptexstar=\*
\let\ptext=\t
-\let\ptexl=\l
-\let\ptexL=\L
+\let\ptextilde=\~
% Be sure we're in horizontal mode when doing a tie, since we make space
% equivalent to this in @example-like environments. Otherwise, a space
@@ -73,6 +75,7 @@
}
\let\~ = \tie % And make it available as @~.
+
\message{Basics,}
\chardef\other=12
@@ -102,10 +105,9 @@
\hyphenation{eshell}
% Margin to add to right of even pages, to left of odd pages.
-\newdimen \bindingoffset \bindingoffset=0pt
-\newdimen \normaloffset \normaloffset=\hoffset
+\newdimen \bindingoffset
+\newdimen \normaloffset
\newdimen\pagewidth \newdimen\pageheight
-\pagewidth=\hsize \pageheight=\vsize
% Sometimes it is convenient to have everything in the transcript file
% and nothing on the terminal. We don't just call \tracingall here,
@@ -126,7 +128,7 @@
\newdimen\cornerlong \newdimen\cornerthick
\newdimen \topandbottommargin
\newdimen \outerhsize \newdimen \outervsize
-\cornerlong=1pc\cornerthick=.3pt % These set size of cropmarks
+\cornerlong=1pc\cornerthick=.3pt % These set size of cropmarks
\outerhsize=7in
%\outervsize=9.5in
% Alternative @smallbook page size is 9.25in
@@ -135,16 +137,42 @@
%
%---------------------End change-----------------------
+% Main output routine.
+\chardef\PAGE = 255
+\output = {\onepageout{\pagecontents\PAGE}}
+
+\newbox\headlinebox \newbox\footlinebox
+
% \onepageout takes a vbox as an argument. Note that \pagecontents
-% does insertions itself, but you have to call it yourself.
-\chardef\PAGE=255 \output={\onepageout{\pagecontents\PAGE}}
-\def\onepageout#1{\hoffset=\normaloffset
-\ifodd\pageno \advance\hoffset by \bindingoffset
-\else \advance\hoffset by -\bindingoffset\fi
-{\escapechar=`\\\relax % makes sure backslash is used in output files.
-\shipout\vbox{{\let\hsize=\pagewidth \makeheadline} \pagebody{#1}%
-{\let\hsize=\pagewidth \makefootline}}}%
-\advancepageno \ifnum\outputpenalty>-20000 \else\dosupereject\fi}
+% does insertions, but you have to call it yourself.
+\def\onepageout#1{%
+ \hoffset=\normaloffset
+ \ifodd\pageno \advance\hoffset by \bindingoffset
+ \else \advance\hoffset by -\bindingoffset\fi
+ %
+ % Do this outside of the \shipout so @code etc. will be expanded in
+ % the headline as they should be, not taken literally (outputting ''code).
+ \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
+ \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
+ %
+ {%
+ % Have to do this stuff outside the \shipout because we want it to
+ % take effect in \write's, yet the group defined by the \vbox ends
+ % before the \shipout runs.
+ %
+ \escapechar = `\\ % use backslash in output files.
+ \indexdummies % don't expand commands in the output.
+ \normalturnoffactive % \ in index entries must not stay \, e.g., if
+ % the page break happens to be in the middle of an example.
+ \shipout\vbox{%
+ \unvbox\headlinebox
+ \pagebody{#1}%
+ \unvbox\footlinebox
+ }%
+ }%
+ \advancepageno
+ \ifnum\outputpenalty>-20000 \else\dosupereject\fi
+}
%%%% For @cropmarks command %%%%
@@ -156,8 +184,8 @@
%
\def\croppageout#1{\hoffset=0pt % make sure this doesn't mess things up
{\escapechar=`\\\relax % makes sure backslash is used in output files.
- \shipout
- \vbox to \outervsize{\hsize=\outerhsize
+ \shipout
+ \vbox to \outervsize{\hsize=\outerhsize
\vbox{\line{\ewtop\hfill\ewtop}}
\nointerlineskip
\line{\vbox{\moveleft\cornerthick\nstop}
@@ -165,19 +193,19 @@
\vbox{\moveright\cornerthick\nstop}}
\vskip \topandbottommargin
\centerline{\ifodd\pageno\hskip\bindingoffset\fi
- \vbox{
- {\let\hsize=\pagewidth \makeheadline}
- \pagebody{#1}
- {\let\hsize=\pagewidth \makefootline}}
- \ifodd\pageno\else\hskip\bindingoffset\fi}
- \vskip \topandbottommargin plus1fill minus1fill
+ \vbox{
+ {\let\hsize=\pagewidth \makeheadline}
+ \pagebody{#1}
+ {\let\hsize=\pagewidth \makefootline}}
+ \ifodd\pageno\else\hskip\bindingoffset\fi}
+ \vskip \topandbottommargin plus1fill minus1fill
\boxmaxdepth\cornerthick
\line{\vbox{\moveleft\cornerthick\nsbot}
\hfill
\vbox{\moveright\cornerthick\nsbot}}
\nointerlineskip
\vbox{\line{\ewbot\hfill\ewbot}}
- }}
+ }}
\advancepageno
\ifnum\outputpenalty>-20000 \else\dosupereject\fi}
%
@@ -365,11 +393,43 @@
%\def\'{{'}}
% Used to generate quoted braces.
-
\def\mylbrace {{\tt \char '173}}
\def\myrbrace {{\tt \char '175}}
\let\{=\mylbrace
\let\}=\myrbrace
+\begingroup
+ % Definitions to produce actual \{ & \} command in an index.
+ \catcode`\{ = 12 \catcode`\} = 12
+ \catcode`\[ = 1 \catcode`\] = 2
+ \catcode`\@ = 0 \catcode`\\ = 12
+ @gdef@lbracecmd[\{]%
+ @gdef@rbracecmd[\}]%
+@endgroup
+
+% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
+% Others are defined by plain TeX: @` @' @" @^ @~ @= @v @H.
+\let\, = \c
+\let\dotaccent = \.
+\def\ringaccent#1{{\accent23 #1}}
+\let\tieaccent = \t
+\let\ubaraccent = \b
+\let\udotaccent = \d
+
+% Other special characters: @questiondown @exclamdown
+% Plain TeX defines: @AA @AE @O @OE @L (and lowercase versions) @ss.
+\def\questiondown{?`}
+\def\exclamdown{!`}
+
+% Dotless i and dotless j, used for accents.
+\def\imacro{i}
+\def\jmacro{j}
+\def\dotless#1{%
+ \def\temp{#1}%
+ \ifx\temp\imacro \ptexi
+ \else\ifx\temp\jmacro \j
+ \else \errmessage{@dotless can be used only with i or j}%
+ \fi\fi
+}
% @: forces normal size whitespace following.
\def\:{\spacefactor=1000 }
@@ -548,14 +608,22 @@ where each line of input produces a line of output.}
%\hbox{{\rm#1}}\hfil\break}}
% @include file insert text of that file as input.
-
-\def\include{\parsearg\includezzz}
-%Use \input\thisfile to avoid blank after \input, which may be an active
-%char (in which case the blank would become the \input argument).
-%The grouping keeps the value of \thisfile correct even when @include
-%is nested.
-\def\includezzz #1{\begingroup
-\def\thisfile{#1}\input\thisfile
+% Allow normal characters that we make active in the argument (a file name).
+\def\include{\begingroup
+ \catcode`\\=12
+ \catcode`~=12
+ \catcode`^=12
+ \catcode`_=12
+ \catcode`|=12
+ \catcode`<=12
+ \catcode`>=12
+ \catcode`+=12
+ \parsearg\includezzz}
+% Restore active chars for included file.
+\def\includezzz#1{\endgroup\begingroup
+ % Read the included file in a group so nested @include's work.
+ \def\thisfile{#1}%
+ \input\thisfile
\endgroup}
\def\thisfile{}
@@ -570,7 +638,7 @@ where each line of input produces a line of output.}
% @sp n outputs n lines of vertical space
\def\sp{\parsearg\spxxx}
-\def\spxxx #1{\par \vskip #1\baselineskip}
+\def\spxxx #1{\vskip #1\baselineskip}
% @comment ...line which is ignored...
% @c is the same as @comment
@@ -583,6 +651,9 @@ where each line of input produces a line of output.}
\let\c=\comment
+% @paragraphindent is defined for the Info formatting commands only.
+\let\paragraphindent=\comment
+
% Prevent errors for section commands.
% Used in @ignore and in failing conditionals.
\def\ignoresections{%
@@ -617,6 +688,7 @@ where each line of input produces a line of output.}
% incorrectly.
%
\def\ignoremorecommands{%
+ \let\defcodeindex = \relax
\let\defcv = \relax
\let\deffn = \relax
\let\deffnx = \relax
@@ -657,7 +729,6 @@ where each line of input produces a line of output.}
\let\set = \relax
\let\clear = \relax
\let\item = \relax
- \let\message = \relax
}
% Ignore @ignore ... @end ignore.
@@ -672,10 +743,15 @@ where each line of input produces a line of output.}
\def\menu{\doignore{menu}}
\def\direntry{\doignore{direntry}}
+% Also ignore @macro ... @end macro. The user must run texi2dvi,
+% which runs makeinfo to do macro expansion. Ignore @unmacro, too.
+\def\macro{\doignore{macro}}
+\let\unmacro = \comment
+
+
% @dircategory CATEGORY -- specify a category of the dir file
% which this file should belong to. Ignore this in TeX.
-
-\def\dircategory{\comment}
+\let\dircategory = \comment
% Ignore text until a line `@end #1'.
%
@@ -708,11 +784,12 @@ where each line of input produces a line of output.}
\immediate\write16{If you are running another version of TeX, relax.}
\immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.}
\immediate\write16{ Then upgrade your TeX installation if you can.}
+ \immediate\write16{ (See ftp://ftp.gnu.ai.mit.edu/pub/gnu/TeX.README.)}
\immediate\write16{If you are stuck with version 3.0, run the}
\immediate\write16{ script ``tex3patch'' from the Texinfo distribution}
\immediate\write16{ to use a workaround.}
\immediate\write16{}
- \warnedobstrue
+ \global\warnedobstrue
\fi
}
@@ -788,15 +865,19 @@ where each line of input produces a line of output.}
% Since we want to separate VAR from REST-OF-LINE (which might be
% empty), we can't just use \parsearg; we have to insert a space of our
% own to delimit the rest of the line, and then take it out again if we
-% didn't need it.
+% didn't need it. Make sure the catcode of space is correct to avoid
+% losing inside @example, for instance.
%
-\def\set{\parsearg\setxxx}
+\def\set{\begingroup\catcode` =10
+ \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR.
+ \parsearg\setxxx}
\def\setxxx#1{\setyyy#1 \endsetyyy}
\def\setyyy#1 #2\endsetyyy{%
\def\temp{#2}%
\ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty
\else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted.
\fi
+ \endgroup
}
% Can't use \xdef to pre-expand #2 and save some time, since \temp or
% \next or other control sequences that we've defined might get us into
@@ -810,10 +891,16 @@ where each line of input produces a line of output.}
% @value{foo} gets the text saved in variable foo.
%
-\def\value#1{\expandafter
- \ifx\csname SET#1\endcsname\relax
- {\{No value for ``#1''\}}
- \else \csname SET#1\endcsname \fi}
+\def\value{\begingroup
+ \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR.
+ \valuexxx}
+\def\valuexxx#1{%
+ \expandafter\ifx\csname SET#1\endcsname\relax
+ {\{No value for ``#1''\}}%
+ \else
+ \csname SET#1\endcsname
+ \fi
+\endgroup}
% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
% with @set.
@@ -913,6 +1000,7 @@ where each line of input produces a line of output.}
\expandafter\expandafter\expandafter\appendixsetref{\lastnode}\fi
\global\let\lastnode=\relax}
+% @refill is a no-op.
\let\refill=\relax
% @setfilename is done at the beginning of every texinfo file.
@@ -927,11 +1015,24 @@ where each line of input produces a line of output.}
\comment % Ignore the actual filename.
}
+% @bye.
\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
-\def\inforef #1{\inforefzzz #1,,,,**}
-\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
- node \samp{\ignorespaces#1{}}}
+% \def\macro#1{\begingroup\ignoresections\catcode`\#=6\def\macrotemp{#1}\parsearg\macroxxx}
+% \def\macroxxx#1#2 \end macro{%
+% \expandafter\gdef\macrotemp#1{#2}%
+% \endgroup}
+
+%\def\linemacro#1{\begingroup\ignoresections\catcode`\#=6\def\macrotemp{#1}\parsearg\linemacroxxx}
+%\def\linemacroxxx#1#2 \end linemacro{%
+%\let\parsearg=\relax
+%\edef\macrotempx{\csname M\butfirst\expandafter\string\macrotemp\endcsname}%
+%\expandafter\xdef\macrotemp{\parsearg\macrotempx}%
+%\expandafter\gdef\macrotempx#1{#2}%
+%\endgroup}
+
+%\def\butfirst#1{}
+
\message{fonts,}
@@ -943,12 +1044,16 @@ where each line of input produces a line of output.}
\def\sf{\fam=\sffam \tensf}
\let\li = \sf % Sometimes we call it \li, not \sf.
+% We don't need math for this one.
+\def\ttsl{\tenttsl}
+
%% Try out Computer Modern fonts at \magstephalf
\let\mainmagstep=\magstephalf
% Set the font macro #1 to the font named #2, adding on the
% specified font prefix (normally `cm').
-\def\setfont#1#2{\font#1=\fontprefix#2}
+% #3 is the font's design size, #4 is a scale factor
+\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4}
% Use cm as the default font prefix.
% To specify the font prefix, you must define \fontprefix
@@ -956,96 +1061,119 @@ where each line of input produces a line of output.}
\ifx\fontprefix\undefined
\def\fontprefix{cm}
\fi
+% Support font families that don't use the same naming scheme as CM.
+\def\rmshape{r}
+\def\rmbshape{bx} %where the normal face is bold
+\def\bfshape{b}
+\def\bxshape{bx}
+\def\ttshape{tt}
+\def\ttbshape{tt}
+\def\ttslshape{sltt}
+\def\itshape{ti}
+\def\itbshape{bxti}
+\def\slshape{sl}
+\def\slbshape{bxsl}
+\def\sfshape{ss}
+\def\sfbshape{ss}
+\def\scshape{csc}
+\def\scbshape{csc}
\ifx\bigger\relax
\let\mainmagstep=\magstep1
-\setfont\textrm{r12}
-\setfont\texttt{tt12}
+\setfont\textrm\rmshape{12}{1000}
+\setfont\texttt\ttshape{12}{1000}
\else
-\setfont\textrm{r10 scaled \mainmagstep}
-\setfont\texttt{tt10 scaled \mainmagstep}
+\setfont\textrm\rmshape{10}{\mainmagstep}
+\setfont\texttt\ttshape{10}{\mainmagstep}
\fi
% Instead of cmb10, you many want to use cmbx10.
% cmbx10 is a prettier font on its own, but cmb10
% looks better when embedded in a line with cmr10.
-\setfont\textbf{b10 scaled \mainmagstep}
-\setfont\textit{ti10 scaled \mainmagstep}
-\setfont\textsl{sl10 scaled \mainmagstep}
-\setfont\textsf{ss10 scaled \mainmagstep}
-\setfont\textsc{csc10 scaled \mainmagstep}
+\setfont\textbf\bfshape{10}{\mainmagstep}
+\setfont\textit\itshape{10}{\mainmagstep}
+\setfont\textsl\slshape{10}{\mainmagstep}
+\setfont\textsf\sfshape{10}{\mainmagstep}
+\setfont\textsc\scshape{10}{\mainmagstep}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}
\font\texti=cmmi10 scaled \mainmagstep
\font\textsy=cmsy10 scaled \mainmagstep
% A few fonts for @defun, etc.
-\setfont\defbf{bx10 scaled \magstep1} %was 1314
-\setfont\deftt{tt10 scaled \magstep1}
+\setfont\defbf\bxshape{10}{\magstep1} %was 1314
+\setfont\deftt\ttshape{10}{\magstep1}
\def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf}
-% Fonts for indices and small examples.
+% Fonts for indices and small examples (9pt).
% We actually use the slanted font rather than the italic,
% because texinfo normally uses the slanted fonts for that.
% Do not make many font distinctions in general in the index, since they
% aren't very useful.
-\setfont\ninett{tt9}
-\setfont\indrm{r9}
-\setfont\indit{sl9}
+\setfont\ninett\ttshape{9}{1000}
+\setfont\indrm\rmshape{9}{1000}
+\setfont\indit\slshape{9}{1000}
\let\indsl=\indit
\let\indtt=\ninett
+\let\indttsl=\ninett
\let\indsf=\indrm
\let\indbf=\indrm
-\setfont\indsc{csc10 at 9pt}
+\setfont\indsc\scshape{10}{900}
\font\indi=cmmi9
\font\indsy=cmsy9
-% Fonts for headings
-\setfont\chaprm{bx12 scaled \magstep2}
-\setfont\chapit{ti12 scaled \magstep2}
-\setfont\chapsl{sl12 scaled \magstep2}
-\setfont\chaptt{tt12 scaled \magstep2}
-\setfont\chapsf{ss12 scaled \magstep2}
+% Chapter (and unnumbered) fonts (17.28pt).
+\setfont\chaprm\rmbshape{12}{\magstep2}
+\setfont\chapit\itbshape{10}{\magstep3}
+\setfont\chapsl\slbshape{10}{\magstep3}
+\setfont\chaptt\ttbshape{12}{\magstep2}
+\setfont\chapttsl\ttslshape{10}{\magstep3}
+\setfont\chapsf\sfbshape{12}{\magstep2}
\let\chapbf=\chaprm
-\setfont\chapsc{csc10 scaled\magstep3}
+\setfont\chapsc\scbshape{10}{\magstep3}
\font\chapi=cmmi12 scaled \magstep2
\font\chapsy=cmsy10 scaled \magstep3
-\setfont\secrm{bx12 scaled \magstep1}
-\setfont\secit{ti12 scaled \magstep1}
-\setfont\secsl{sl12 scaled \magstep1}
-\setfont\sectt{tt12 scaled \magstep1}
-\setfont\secsf{ss12 scaled \magstep1}
-\setfont\secbf{bx12 scaled \magstep1}
-\setfont\secsc{csc10 scaled\magstep2}
+% Section fonts (14.4pt).
+\setfont\secrm\rmbshape{12}{\magstep1}
+\setfont\secit\itbshape{10}{\magstep2}
+\setfont\secsl\slbshape{10}{\magstep2}
+\setfont\sectt\ttbshape{12}{\magstep1}
+\setfont\secttsl\ttslshape{10}{\magstep2}
+\setfont\secsf\sfbshape{12}{\magstep1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep2}
\font\seci=cmmi12 scaled \magstep1
\font\secsy=cmsy10 scaled \magstep2
-% \setfont\ssecrm{bx10 scaled \magstep1} % This size an font looked bad.
-% \setfont\ssecit{cmti10 scaled \magstep1} % The letters were too crowded.
-% \setfont\ssecsl{sl10 scaled \magstep1}
-% \setfont\ssectt{tt10 scaled \magstep1}
-% \setfont\ssecsf{ss10 scaled \magstep1}
+% \setfont\ssecrm\bxshape{10}{\magstep1} % This size an font looked bad.
+% \setfont\ssecit\itshape{10}{\magstep1} % The letters were too crowded.
+% \setfont\ssecsl\slshape{10}{\magstep1}
+% \setfont\ssectt\ttshape{10}{\magstep1}
+% \setfont\ssecsf\sfshape{10}{\magstep1}
-%\setfont\ssecrm{b10 scaled 1315} % Note the use of cmb rather than cmbx.
-%\setfont\ssecit{ti10 scaled 1315} % Also, the size is a little larger than
-%\setfont\ssecsl{sl10 scaled 1315} % being scaled magstep1.
-%\setfont\ssectt{tt10 scaled 1315}
-%\setfont\ssecsf{ss10 scaled 1315}
+%\setfont\ssecrm\bfshape{10}{1315} % Note the use of cmb rather than cmbx.
+%\setfont\ssecit\itshape{10}{1315} % Also, the size is a little larger than
+%\setfont\ssecsl\slshape{10}{1315} % being scaled magstep1.
+%\setfont\ssectt\ttshape{10}{1315}
+%\setfont\ssecsf\sfshape{10}{1315}
%\let\ssecbf=\ssecrm
-\setfont\ssecrm{bx12 scaled \magstephalf}
-\setfont\ssecit{ti12 scaled \magstephalf}
-\setfont\ssecsl{sl12 scaled \magstephalf}
-\setfont\ssectt{tt12 scaled \magstephalf}
-\setfont\ssecsf{ss12 scaled \magstephalf}
-\setfont\ssecbf{bx12 scaled \magstephalf}
-\setfont\ssecsc{csc10 scaled \magstep1}
+% Subsection fonts (13.15pt).
+\setfont\ssecrm\rmbshape{12}{\magstephalf}
+\setfont\ssecit\itbshape{10}{1315}
+\setfont\ssecsl\slbshape{10}{1315}
+\setfont\ssectt\ttbshape{12}{\magstephalf}
+\setfont\ssecttsl\ttslshape{10}{\magstep1}
+\setfont\ssecsf\sfbshape{12}{\magstephalf}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{\magstep1}
\font\sseci=cmmi12 scaled \magstephalf
\font\ssecsy=cmsy10 scaled \magstep1
% The smallcaps and symbol fonts should actually be scaled \magstep1.5,
% but that is not a standard magnification.
% Fonts for title page:
-\setfont\titlerm{bx12 scaled \magstep3}
+\setfont\titlerm\rmbshape{12}{\magstep3}
\let\authorrm = \secrm
% In order for the font changes to affect most math symbols and letters,
@@ -1064,34 +1192,35 @@ where each line of input produces a line of output.}
% The font-changing commands redefine the meanings of \tenSTYLE, instead
% of just \STYLE. We do this so that font changes will continue to work
% in math mode, where it is the current \fam that is relevant in most
-% cases, not the current. Plain TeX does, for example,
-% \def\bf{\fam=\bffam \tenbf} By redefining \tenbf, we obviate the need
-% to redefine \bf itself.
+% cases, not the current font. Plain TeX does \def\bf{\fam=\bffam
+% \tenbf}, for example. By redefining \tenbf, we obviate the need to
+% redefine \bf itself.
\def\textfonts{%
\let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
\let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
- \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy
+ \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl
\resetmathfonts}
\def\chapfonts{%
\let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
\let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
- \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy
- \resetmathfonts}
+ \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl
+ \resetmathfonts \setleading{19pt}}
\def\secfonts{%
\let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
\let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
- \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy
- \resetmathfonts}
+ \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl
+ \resetmathfonts \setleading{16pt}}
\def\subsecfonts{%
\let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
\let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
- \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy
- \resetmathfonts}
+ \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl
+ \resetmathfonts \setleading{15pt}}
+\let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf?
\def\indexfonts{%
\let\tenrm=\indrm \let\tenit=\indit \let\tensl=\indsl
\let\tenbf=\indbf \let\tentt=\indtt \let\smallcaps=\indsc
- \let\tensf=\indsf \let\teni=\indi \let\tensy=\indsy
- \resetmathfonts}
+ \let\tensf=\indsf \let\teni=\indi \let\tensy=\indsy \let\tenttsl=\indttsl
+ \resetmathfonts \setleading{12pt}}
% Set up the default fonts, so we can use them for creating boxes.
%
@@ -1101,9 +1230,9 @@ where each line of input produces a line of output.}
\newcount\fontdepth \fontdepth=0
% Fonts for short table of contents.
-\setfont\shortcontrm{r12}
-\setfont\shortcontbf{bx12}
-\setfont\shortcontsl{sl12}
+\setfont\shortcontrm\rmshape{12}{1000}
+\setfont\shortcontbf\bxshape{12}{1000}
+\setfont\shortcontsl\slshape{12}{1000}
%% Add scribe-like font environments, plus @l for inline lisp (usually sans
%% serif) and @ii for TeX italic
@@ -1135,10 +1264,21 @@ where each line of input produces a line of output.}
}
\let\ttfont=\t
\def\samp #1{`\tclose{#1}'\null}
-\def\key #1{{\tt \nohyphenation \uppercase{#1}}\null}
+\setfont\smallrm\rmshape{8}{1000}
+\font\smallsy=cmsy9
+\def\key#1{{\smallrm\textfont2=\smallsy \leavevmode\hbox{%
+ \raise0.4pt\hbox{$\langle$}\kern-.08em\vtop{%
+ \vbox{\hrule\kern-0.4pt
+ \hbox{\raise0.4pt\hbox{\vphantom{$\langle$}}#1}}%
+ \kern-0.4pt\hrule}%
+ \kern-.06em\raise0.4pt\hbox{$\rangle$}}}}
+% The old definition, with no lozenge:
+%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null}
\def\ctrl #1{{\tt \rawbackslash \hat}#1}
\let\file=\samp
+\let\url=\samp % perhaps include a hypertex \special eventually
+\def\email#1{$\langle${\tt #1}$\rangle$}
% @code is a modification of @t,
% which makes spaces the same size as normal in the surrounding text.
@@ -1170,21 +1310,26 @@ where each line of input produces a line of output.}
% Unfortunately, TeX uses one parameter (\hyphenchar) to control
% both hyphenation at - and hyphenation within words.
% We must therefore turn them both off (\tclose does that)
-% and arrange explicitly to hyphenate an a dash.
+% and arrange explicitly to hyphenate at a dash.
% -- rms.
{
\catcode`\-=\active
\catcode`\_=\active
+\catcode`\|=\active
\global\def\code{\begingroup \catcode`\-=\active \let-\codedash \catcode`\_=\active \let_\codeunder \codex}
% The following is used by \doprintindex to insure that long function names
% wrap around. It is necessary for - and _ to be active before the index is
% read from the file, as \entry parses the arguments long before \code is
% ever called. -- mycroft
-\global\def\indexbreaks{\catcode`\-=\active \let-\realdash \catcode`\_=\active \let_\realunder}
+% _ is always active; and it shouldn't be \let = to an _ that is a
+% subscript character anyway. Then, @cindex @samp{_} (for example)
+% fails. --karl
+\global\def\indexbreaks{%
+ \catcode`\-=\active \let-\realdash
+}
}
\def\realdash{-}
-\def\realunder{_}
\def\codedash{-\discretionary{}{}{}}
\def\codeunder{\normalunderscore\discretionary{}{}{}}
\def\codex #1{\tclose{#1}\endgroup}
@@ -1193,12 +1338,19 @@ where each line of input produces a line of output.}
% @kbd is like @code, except that if the argument is just one @key command,
% then @kbd has no effect.
-
+%
\def\xkey{\key}
\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
\ifx\one\xkey\ifx\threex\three \key{#2}%
-\else\tclose{\look}\fi
-\else\tclose{\look}\fi}
+\else{\tclose{\ttsl\look}}\fi
+\else{\tclose{\ttsl\look}}\fi}
+
+% Check if we are currently using a typewriter font. Since all the
+% Computer Modern typewriter fonts have zero interword stretch (and
+% shrink), and it is reasonable to expect all typewriter fonts to have
+% this property, we can check that font parameter.
+%
+\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
% Typeset a dimension, e.g., `in' or `pt'. The only reason for the
% argument is to make the input look right: @dmn{pt} instead of
@@ -1208,12 +1360,19 @@ where each line of input produces a line of output.}
\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par}
-\def\l#1{{\li #1}\null} %
+% @l was never documented to mean ``switch to the Lisp font'',
+% and it is not used as such in any manual I can find. We need it for
+% Polish suppressed-l. --karl, 22sep96.
+%\def\l#1{{\li #1}\null}
-\def\r#1{{\rm #1}} % roman font
+\def\r#1{{\rm #1}} % roman font
% Use of \lowercase was suggested.
-\def\sc#1{{\smallcaps#1}} % smallcaps font
-\def\ii#1{{\it #1}} % italic font
+\def\sc#1{{\smallcaps#1}} % smallcaps font
+\def\ii#1{{\it #1}} % italic font
+
+% @pounds{} is a sterling sign.
+\def\pounds{{\it\$}}
+
\message{page headings,}
@@ -1228,7 +1387,7 @@ where each line of input produces a line of output.}
\def\shorttitlepage{\parsearg\shorttitlepagezzz}
\def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
- \endgroup\page\hbox{}\page}
+ \endgroup\page\hbox{}\page}
\def\titlepage{\begingroup \parindent=0pt \textfonts
\let\subtitlerm=\tenrm
@@ -1245,9 +1404,9 @@ where each line of input produces a line of output.}
% Now you can print the title using @title.
\def\title{\parsearg\titlezzz}%
\def\titlezzz##1{\leftline{\titlefont{##1}}
- % print a rule at the page bottom also.
- \finishedtitlepagefalse
- \vskip4pt \hrule height 4pt width \hsize \vskip4pt}%
+ % print a rule at the page bottom also.
+ \finishedtitlepagefalse
+ \vskip4pt \hrule height 4pt width \hsize \vskip4pt}%
% No rule at page bottom unless we print one at the top with @title.
\finishedtitlepagetrue
%
@@ -1265,7 +1424,7 @@ where each line of input produces a line of output.}
\let\oldpage = \page
\def\page{%
\iffinishedtitlepage\else
- \finishtitlepage
+ \finishtitlepage
\fi
\oldpage
\let\page = \oldpage
@@ -1353,14 +1512,15 @@ where each line of input produces a line of output.}
%
}% unbind the catcode of @.
-% @headings double turns headings on for double-sided printing.
-% @headings single turns headings on for single-sided printing.
-% @headings off turns them off.
-% @headings on same as @headings double, retained for compatibility.
-% @headings after turns on double-sided headings after this page.
-% @headings doubleafter turns on double-sided headings after this page.
+% @headings double turns headings on for double-sided printing.
+% @headings single turns headings on for single-sided printing.
+% @headings off turns them off.
+% @headings on same as @headings double, retained for compatibility.
+% @headings after turns on double-sided headings after this page.
+% @headings doubleafter turns on double-sided headings after this page.
% @headings singleafter turns on single-sided headings after this page.
-% By default, they are off.
+% By default, they are off at the start of a document,
+% and turned `on' after @end titlepage.
\def\headings #1 {\csname HEADINGS#1\endcsname}
@@ -1374,22 +1534,24 @@ where each line of input produces a line of output.}
% title on inside top of left hand pages, and page numbers on outside top
% edge of all pages.
\def\HEADINGSdouble{
-%\pagealignmacro
\global\pageno=1
\global\evenfootline={\hfil}
\global\oddfootline={\hfil}
\global\evenheadline={\line{\folio\hfil\thistitle}}
\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
}
+\let\contentsalignmacro = \chappager
+
% For single-sided printing, chapter title goes across top left of page,
% page number on top right.
\def\HEADINGSsingle{
-%\pagealignmacro
\global\pageno=1
\global\evenfootline={\hfil}
\global\oddfootline={\hfil}
\global\evenheadline={\line{\thischapter\hfil\folio}}
\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
}
\def\HEADINGSon{\HEADINGSdouble}
@@ -1400,6 +1562,7 @@ where each line of input produces a line of output.}
\global\oddfootline={\hfil}
\global\evenheadline={\line{\folio\hfil\thistitle}}
\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
}
\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
@@ -1408,6 +1571,7 @@ where each line of input produces a line of output.}
\global\oddfootline={\hfil}
\global\evenheadline={\line{\thischapter\hfil\folio}}
\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
}
% Subroutines used in generating headings
@@ -1431,6 +1595,7 @@ July\or August\or September\or October\or November\or December\fi
\def\settitle{\parsearg\settitlezzz}
\def\settitlezzz #1{\gdef\thistitle{#1}}
+
\message{tables,}
% @tabs -- simple alignment
@@ -1463,7 +1628,7 @@ July\or August\or September\or October\or November\or December\fi
\newif\ifitemxneedsnegativevskip
-\def\itemxpar{\par\ifitemxneedsnegativevskip\vskip-\parskip\nobreak\fi}
+\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi}
\def\internalBitem{\smallbreak \parsearg\itemzzz}
\def\internalBitemx{\itemxpar \parsearg\itemzzz}
@@ -1734,7 +1899,7 @@ July\or August\or September\or October\or November\or December\fi
\flushcr}
% @multitable macros
-% Amy Hendrickson, 8/18/94
+% Amy Hendrickson, 8/18/94, 3/6/96
%
% @multitable ... @end multitable will make as many columns as desired.
% Contents of each column will wrap at width given in preamble. Width
@@ -1746,25 +1911,35 @@ July\or August\or September\or October\or November\or December\fi
% To make preamble:
%
% Either define widths of columns in terms of percent of \hsize:
-% @multitable @percentofhsize .2 .3 .5
+% @multitable @columnfractions .25 .3 .45
% @item ...
%
-% Numbers following @percentofhsize are the percent of the total
+% Numbers following @columnfractions are the percent of the total
% current hsize to be used for each column. You may use as many
% columns as desired.
+
% Or use a template:
% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
% @item ...
% using the widest term desired in each column.
-
+%
+% For those who want to use more than one line's worth of words in
+% the preamble, break the line within one argument and it
+% will parse correctly, i.e.,
+%
+% @multitable {Column 1 template} {Column 2 template} {Column 3
+% template}
+% Not:
+% @multitable {Column 1 template} {Column 2 template}
+% {Column 3 template}
% Each new table line starts with @item, each subsequent new column
% starts with @tab. Empty columns may be produced by supplying @tab's
% with nothing between them for as many times as empty columns are needed,
% ie, @tab@tab@tab will produce two empty columns.
-% @item, @tab, @multicolumn or @endmulticolumn do not need to be on their
+% @item, @tab, @multitable or @end multitable do not need to be on their
% own lines, but it will not hurt if they are.
% Sample multitable:
@@ -1785,68 +1960,83 @@ July\or August\or September\or October\or November\or December\fi
% @end multitable
% Default dimensions may be reset by user.
-% @intableparskip will set vertical space between paragraphs in table.
-% @intableparindent will set paragraph indent in table.
-% @spacebetweencols will set horizontal space to be left between columns.
-% @spacebetweenlines will set vertical space to be left between lines.
+% @multitableparskip is vertical space between paragraphs in table.
+% @multitableparindent is paragraph indent in table.
+% @multitablecolmargin is horizontal space to be left between columns.
+% @multitablelinespace is space to leave between table items, baseline
+% to baseline.
+% 0pt means it depends on current normal line spacing.
%%%%
% Dimensions
-\newdimen\intableparskip
-\newdimen\intableparindent
-\newdimen\spacebetweencols
-\newdimen\spacebetweenlines
-\intableparskip=0pt
-\intableparindent=6pt
-\spacebetweencols=12pt
-\spacebetweenlines=12pt
+\newskip\multitableparskip
+\newskip\multitableparindent
+\newdimen\multitablecolspace
+\newskip\multitablelinespace
+\multitableparskip=0pt
+\multitableparindent=6pt
+\multitablecolspace=12pt
+\multitablelinespace=0pt
%%%%
% Macros used to set up halign preamble:
\let\endsetuptable\relax
\def\xendsetuptable{\endsetuptable}
-\let\percentofhsize\relax
-\def\xpercentofhsize{\percentofhsize}
+\let\columnfractions\relax
+\def\xcolumnfractions{\columnfractions}
\newif\ifsetpercent
+%% 2/1/96, to allow fractions to be given with more than one digit.
+\def\pickupwholefraction#1 {\global\advance\colcount by1 %
+\expandafter\xdef\csname col\the\colcount\endcsname{.#1\hsize}%
+\setuptable}
+
\newcount\colcount
\def\setuptable#1{\def\firstarg{#1}%
\ifx\firstarg\xendsetuptable\let\go\relax%
\else
- \ifx\firstarg\xpercentofhsize\global\setpercenttrue%
+ \ifx\firstarg\xcolumnfractions\global\setpercenttrue%
\else
\ifsetpercent
- \if#1.\else%
- \global\advance\colcount by1 %
- \expandafter\xdef\csname col\the\colcount\endcsname{.#1\hsize}%
- \fi
+ \let\go\pickupwholefraction % In this case arg of setuptable
+ % is the decimal point before the
+ % number given in percent of hsize.
+ % We don't need this so we don't use it.
\else
\global\advance\colcount by1
- \setbox0=\hbox{#1}%
+ \setbox0=\hbox{#1 }% Add a normal word space as a separator;
+ % typically that is always in the input, anyway.
\expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
\fi%
\fi%
- \let\go\setuptable%
+\ifx\go\pickupwholefraction\else\let\go\setuptable\fi%
\fi\go}
+
%%%%
% multitable syntax
-\def\tab{&}
+\def\tab{&\hskip1sp\relax} % 2/2/96
+ % tiny skip here makes sure this column space is
+ % maintained, even if it is never used.
+
%%%%
% @multitable ... @end multitable definitions:
-\def\multitable#1\item{\bgroup
+\def\multitable{\parsearg\dotable}
+
+\def\dotable#1{\bgroup
\let\item\cr
\tolerance=9500
\hbadness=9500
-\parskip=\intableparskip
-\parindent=\intableparindent
+\setmultitablespacing
+\parskip=\multitableparskip
+\parindent=\multitableparindent
\overfullrule=0pt
\global\colcount=0\relax%
\def\Emultitable{\global\setpercentfalse\global\everycr{}\cr\egroup\egroup}%
% To parse everything between @multitable and @item :
-\def\one{#1}\expandafter\setuptable\one\endsetuptable
+\setuptable#1 \endsetuptable
% Need to reset this to 0 after \setuptable.
\global\colcount=0\relax%
%
@@ -1855,11 +2045,11 @@ July\or August\or September\or October\or November\or December\fi
% \vtop will set a single line and will also let text wrap and
% continue for many paragraphs if desired.
\halign\bgroup&\global\advance\colcount by 1\relax%
-\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname
+\multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname
% In order to keep entries from bumping into each other
- % we will add a \leftskip of \spacebetweencols to all columns after
+ % we will add a \leftskip of \multitablecolspace to all columns after
% the first one.
- % If a template has been used, we will add \spacebetweencols
+ % If a template has been used, we will add \multitablecolspace
% to the width of each template entry.
% If user has set preamble in terms of percent of \hsize
% we will use that dimension as the width of the column, and
@@ -1871,20 +2061,58 @@ July\or August\or September\or October\or November\or December\fi
\ifsetpercent
\else
% If user has <not> set preamble in terms of percent of \hsize
- % we will advance \hsize by \spacebetweencols
- \advance\hsize by \spacebetweencols
+ % we will advance \hsize by \multitablecolspace
+ \advance\hsize by \multitablecolspace
\fi
- % In either case we will make \leftskip=\spacebetweencols:
-\leftskip=\spacebetweencols
+ % In either case we will make \leftskip=\multitablecolspace:
+\leftskip=\multitablecolspace
\fi
-\noindent##}\cr%
+ % Ignoring space at the beginning and end avoids an occasional spurious
+ % blank line, when TeX decides to break the line at the space before the
+ % box from the multistrut, so the strut ends up on a line by itself.
+ % For example:
+ % @multitable @columnfractions .11 .89
+ % @item @code{#}
+ % @tab Legal holiday which is valid in major parts of the whole country.
+ % Is automatically provided with highlighing sequences respectively marking
+ % characters.
+ \noindent\ignorespaces##\unskip\multistrut}\cr
% \everycr will reset column counter, \colcount, at the end of
% each line. Every column entry will cause \colcount to advance by one.
% The table preamble
% looks at the current \colcount to find the correct column width.
-\global\everycr{\noalign{\nointerlineskip\vskip\spacebetweenlines
-\filbreak%% keeps underfull box messages off when table breaks over pages.
-\global\colcount=0\relax}}}
+\global\everycr{\noalign{%
+% \filbreak%% keeps underfull box messages off when table breaks over pages.
+% Maybe so, but it also creates really weird page breaks when the table
+% breaks over pages Wouldn't \vfil be better? Wait until the problem
+% manifests itself, so it can be fixed for real --karl.
+\global\colcount=0\relax}}
+}
+
+\def\setmultitablespacing{% test to see if user has set \multitablelinespace.
+% If so, do nothing. If not, give it an appropriate dimension based on
+% current baselineskip.
+\ifdim\multitablelinespace=0pt
+%% strut to put in table in case some entry doesn't have descenders,
+%% to keep lines equally spaced
+\let\multistrut = \strut
+%% Test to see if parskip is larger than space between lines of
+%% table. If not, do nothing.
+%% If so, set to same dimension as multitablelinespace.
+\else
+\gdef\multistrut{\vrule height\multitablelinespace depth\dp0
+width0pt\relax} \fi
+\ifdim\multitableparskip>\multitablelinespace
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+ %% than skip between lines in the table.
+\fi%
+\ifdim\multitableparskip=0pt
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+ %% than skip between lines in the table.
+\fi}
+
\message{indexing,}
% Index generation facilities
@@ -1898,14 +2126,14 @@ July\or August\or September\or October\or November\or December\fi
% It automatically defines \fooindex such that
% \fooindex ...rest of line... puts an entry in the index foo.
% It also defines \fooindfile to be the number of the output channel for
-% the file that accumulates this index. The file's extension is foo.
+% the file that accumulates this index. The file's extension is foo.
% The name of an index should be no more than 2 characters long
% for the sake of vms.
\def\newindex #1{
\expandafter\newwrite \csname#1indfile\endcsname% Define number for output file
-\openout \csname#1indfile\endcsname \jobname.#1 % Open the file
-\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex
+\openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex
\noexpand\doindex {#1}}
}
@@ -1917,8 +2145,8 @@ July\or August\or September\or October\or November\or December\fi
\def\newcodeindex #1{
\expandafter\newwrite \csname#1indfile\endcsname% Define number for output file
-\openout \csname#1indfile\endcsname \jobname.#1 % Open the file
-\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex
+\openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex
\noexpand\docodeindex {#1}}
}
@@ -1929,7 +2157,7 @@ July\or August\or September\or October\or November\or December\fi
\def\synindex #1 #2 {%
\expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname
\expandafter\let\csname#1indfile\endcsname=\synindexfoo
-\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex
+\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex
\noexpand\doindex {#2}}%
}
@@ -1938,7 +2166,7 @@ July\or August\or September\or October\or November\or December\fi
\def\syncodeindex #1 #2 {%
\expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname
\expandafter\let\csname#1indfile\endcsname=\synindexfoo
-\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex
+\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex
\noexpand\docodeindex {#2}}%
}
@@ -1986,24 +2214,31 @@ July\or August\or September\or October\or November\or December\fi
\def\L{\realbackslash L}%
\def\ss{\realbackslash ss}%
% Take care of texinfo commands likely to appear in an index entry.
+% (Must be a way to avoid doing expansion at all, and thus not have to
+% laboriously list every single command here.)
+\def\@{@}% will be @@ when we switch to @ as escape char.
+%\let\{ = \lbracecmd
+%\let\} = \rbracecmd
\def\_{{\realbackslash _}}%
\def\w{\realbackslash w }%
\def\bf{\realbackslash bf }%
-\def\rm{\realbackslash rm }%
+%\def\rm{\realbackslash rm }%
\def\sl{\realbackslash sl }%
\def\sf{\realbackslash sf}%
\def\tt{\realbackslash tt}%
\def\gtr{\realbackslash gtr}%
\def\less{\realbackslash less}%
\def\hat{\realbackslash hat}%
-\def\char{\realbackslash char}%
+%\def\char{\realbackslash char}%
\def\TeX{\realbackslash TeX}%
\def\dots{\realbackslash dots }%
\def\copyright{\realbackslash copyright }%
\def\tclose##1{\realbackslash tclose {##1}}%
\def\code##1{\realbackslash code {##1}}%
+\def\dotless##1{\realbackslash dotless {##1}}%
\def\samp##1{\realbackslash samp {##1}}%
-\def\t##1{\realbackslash r {##1}}%
+\def\,##1{\realbackslash ,{##1}}%
+\def\t##1{\realbackslash t {##1}}%
\def\r##1{\realbackslash r {##1}}%
\def\i##1{\realbackslash i {##1}}%
\def\b##1{\realbackslash b {##1}}%
@@ -2031,6 +2266,7 @@ July\or August\or September\or October\or November\or December\fi
\def\indexnofonts{%
% Just ignore accents.
+\let\,=\indexdummyfont
\let\"=\indexdummyfont
\let\`=\indexdummyfont
\let\'=\indexdummyfont
@@ -2043,6 +2279,7 @@ July\or August\or September\or October\or November\or December\fi
\let\u=\indexdummyfont
\let\v=\indexdummyfont
\let\H=\indexdummyfont
+\let\dotless=\indexdummyfont
% Take care of the plain tex special European modified letters.
\def\oe{oe}%
\def\ae{ae}%
@@ -2076,6 +2313,7 @@ July\or August\or September\or October\or November\or December\fi
\let\var=\indexdummyfont
\let\TeX=\indexdummytex
\let\dots=\indexdummydots
+\def\@{@}%
}
% To define \realbackslash, we must make \ not be an escape.
@@ -2091,29 +2329,37 @@ July\or August\or September\or October\or November\or December\fi
% workhorse for all \fooindexes
% #1 is name of index, #2 is stuff to put there
\def\doind #1#2{%
-% Put the index entry in the margin if desired.
-\ifx\SETmarginindex\relax\else%
-\insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}%
-\fi%
-{\count10=\lastpenalty %
-{\indexdummies % Must do this here, since \bf, etc expand at this stage
-\escapechar=`\\%
-{\let\folio=0% Expand all macros now EXCEPT \folio
-\def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now
-% so it will be output as is; and it will print as backslash in the indx.
-%
-% Now process the index-string once, with all font commands turned off,
-% to get the string to sort the index by.
-{\indexnofonts
-\xdef\temp1{#2}%
-}%
-% Now produce the complete index entry. We process the index-string again,
-% this time with font commands expanded, to get what to print in the index.
-\edef\temp{%
-\write \csname#1indfile\endcsname{%
-\realbackslash entry {\temp1}{\folio}{#2}}}%
-\temp }%
-}\penalty\count10}}
+ % Put the index entry in the margin if desired.
+ \ifx\SETmarginindex\relax\else
+ \insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}%
+ \fi
+ {%
+ \count255=\lastpenalty
+ {%
+ \indexdummies % Must do this here, since \bf, etc expand at this stage
+ \escapechar=`\\
+ {%
+ \let\folio=0% We will expand all macros now EXCEPT \folio.
+ \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now
+ % so it will be output as is; and it will print as backslash.
+ %
+ % First process the index-string with all font commands turned off
+ % to get the string to sort by.
+ {\indexnofonts \xdef\indexsorttmp{#2}}%
+ %
+ % Now produce the complete index entry, with both the sort key and the
+ % original text, including any font commands.
+ \toks0 = {#2}%
+ \edef\temp{%
+ \write\csname#1indfile\endcsname{%
+ \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}%
+ }%
+ \temp
+ }%
+ }%
+ \penalty\count255
+ }%
+}
\def\dosubind #1#2#3{%
{\count10=\lastpenalty %
@@ -2174,26 +2420,19 @@ July\or August\or September\or October\or November\or December\fi
\def\printindex{\parsearg\doprintindex}
-\def\doprintindex#1{%
- \tex
- \dobreak \chapheadingskip {10000}
- \catcode`\%=\other\catcode`\&=\other\catcode`\#=\other
- \catcode`\$=\other
- \catcode`\~=\other
- \indexbreaks
+\def\doprintindex#1{\begingroup
+ \dobreak \chapheadingskip{10000}%
%
- % The following don't help, since the chars were translated
- % when the raw index was written, and their fonts were discarded
- % due to \indexnofonts.
- %\catcode`\"=\active
- %\catcode`\^=\active
- %\catcode`\_=\active
- %\catcode`\|=\active
- %\catcode`\<=\active
- %\catcode`\>=\active
- % %
- \def\indexbackslash{\rawbackslashxx}
- \indexfonts\rm \tolerance=9500 \advance\baselineskip -1pt
+ \indexfonts \rm
+ \tolerance = 9500
+ \indexbreaks
+ \def\indexbackslash{\rawbackslashxx}%
+ % Index files are almost Texinfo source, but we use \ as the escape
+ % character. It would be better to use @, but that's too big a change
+ % to make right now.
+ \catcode`\\ = 0
+ \catcode`\@ = 11
+ \escapechar = `\\
\begindoublecolumns
%
% See if the index file exists and is nonempty.
@@ -2204,7 +2443,7 @@ July\or August\or September\or October\or November\or December\fi
% index. The easiest way to prevent this problem is to make sure
% there is some text.
(Index is nonexistent)
- \else
+ \else
%
% If the index file exists but is empty, then \openin leaves \ifeof
% false. We have to make TeX try to read something from the file, so
@@ -2218,8 +2457,7 @@ July\or August\or September\or October\or November\or December\fi
\fi
\closein 1
\enddoublecolumns
- \Etex
-}
+\endgroup}
% These macros are used by the sorted index file itself.
% Change them to control the appearance of the index.
@@ -2310,15 +2548,15 @@ July\or August\or September\or October\or November\or December\fi
\noindent\hskip\secondaryindent\hbox{#1}\indexdotfill #2\par
}}
-%% Define two-column mode, which is used in indexes.
-%% Adapted from the TeXbook, page 416.
-\catcode `\@=11
+% Define two-column mode, which we use to typeset indexes.
+% Adapted from the TeXbook, page 416, which is to say,
+% the manmac.tex format used to print the TeXbook itself.
+\catcode`\@=11
\newbox\partialpage
-
\newdimen\doublecolumnhsize
-\def\begindoublecolumns{\begingroup
+\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns
% Grab any single-column material above us.
\output = {\global\setbox\partialpage
=\vbox{\unvbox255\kern -\topskip \kern \baselineskip}}%
@@ -2351,51 +2589,51 @@ July\or August\or September\or October\or November\or December\fi
% Double the \vsize as well. (We don't need a separate register here,
% since nobody clobbers \vsize.)
\vsize = 2\vsize
- \doublecolumnpagegoal
}
-
-\def\enddoublecolumns{\eject \endgroup \pagegoal=\vsize \unvbox\partialpage}
-
-\def\doublecolumnsplit{\splittopskip=\topskip \splitmaxdepth=\maxdepth
- \global\dimen@=\pageheight \global\advance\dimen@ by-\ht\partialpage
- \global\setbox1=\vsplit255 to\dimen@ \global\setbox0=\vbox{\unvbox1}
- \global\setbox3=\vsplit255 to\dimen@ \global\setbox2=\vbox{\unvbox3}
- \ifdim\ht0>\dimen@ \setbox255=\vbox{\unvbox0\unvbox2} \global\setbox255=\copy5 \fi
- \ifdim\ht2>\dimen@ \setbox255=\vbox{\unvbox0\unvbox2} \global\setbox255=\copy5 \fi
+\def\doublecolumnout{%
+ \splittopskip=\topskip \splitmaxdepth=\maxdepth
+ % Get the available space for the double columns -- the normal
+ % (undoubled) page height minus any material left over from the
+ % previous page.
+ \dimen@=\pageheight \advance\dimen@ by-\ht\partialpage
+ % box0 will be the left-hand column, box1 the right.
+ \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@
+ \onepageout\pagesofar
+ \unvbox255 \penalty\outputpenalty
}
-\def\doublecolumnpagegoal{%
- \dimen@=\vsize \advance\dimen@ by-2\ht\partialpage \global\pagegoal=\dimen@
+\def\pagesofar{%
+ % The contents of the output page -- any previous material,
+ % followed by the two boxes we just split.
+ \unvbox\partialpage
+ \hsize = \doublecolumnhsize
+ \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}%
}
-\def\pagesofar{\unvbox\partialpage %
- \hsize=\doublecolumnhsize % have to restore this since output routine
- \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}}
-\def\doublecolumnout{%
- \setbox5=\copy255
- {\vbadness=10000 \doublecolumnsplit}
- \ifvbox255
- \setbox0=\vtop to\dimen@{\unvbox0}
- \setbox2=\vtop to\dimen@{\unvbox2}
- \onepageout\pagesofar \unvbox255 \penalty\outputpenalty
- \else
- \setbox0=\vbox{\unvbox5}
- \ifvbox0
- \dimen@=\ht0 \advance\dimen@ by\topskip \advance\dimen@ by-\baselineskip
- \divide\dimen@ by2 \splittopskip=\topskip \splitmaxdepth=\maxdepth
- {\vbadness=10000
- \loop \global\setbox5=\copy0
- \setbox1=\vsplit5 to\dimen@
- \setbox3=\vsplit5 to\dimen@
- \ifvbox5 \global\advance\dimen@ by1pt \repeat
- \setbox0=\vbox to\dimen@{\unvbox1}
- \setbox2=\vbox to\dimen@{\unvbox3}
- \global\setbox\partialpage=\vbox{\pagesofar}
- \doublecolumnpagegoal
- }
- \fi
- \fi
+\def\enddoublecolumns{%
+ \output={\balancecolumns}\eject % split what we have
+ \endgroup
+ % Back to normal single-column typesetting, but take account of the
+ % fact that we just accumulated some stuff on the output page.
+ \pagegoal=\vsize
+}
+\def\balancecolumns{%
+ % Called on the last page of the double column material.
+ \setbox0=\vbox{\unvbox255}%
+ \dimen@ = \ht0
+ \advance\dimen@ by \topskip
+ \advance\dimen@ by-\baselineskip
+ \divide\dimen@ by 2
+ \splittopskip = \topskip
+ % Loop until we get a decent breakpoint.
+ {\vbadness=10000 \loop \global\setbox3=\copy0
+ \global\setbox1=\vsplit3 to\dimen@
+ \ifdim\ht3>\dimen@ \global\advance\dimen@ by1pt \repeat}%
+ \setbox0=\vbox to\dimen@{\unvbox1}%
+ \setbox2=\vbox to\dimen@{\unvbox3}%
+ \pagesofar
}
-
\catcode `\@=\other
+
+
\message{sectioning,}
% Define chapters, sections, etc.
@@ -2567,6 +2805,10 @@ July\or August\or September\or October\or November\or December\fi
\global\let\subsubsection = \appendixsubsubsec
}}
+% @centerchap is like @unnumbered, but the heading is centered.
+\outer\def\centerchap{\parsearg\centerchapyyy}
+\def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}}
+
\outer\def\top{\parsearg\unnumberedyyy}
\outer\def\unnumbered{\parsearg\unnumberedyyy}
\def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
@@ -2669,7 +2911,7 @@ July\or August\or September\or October\or November\or December\fi
\outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy}
\def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
\def\unnumberedsubseczzz #1{\seccheck{unnumberedsubsec}%
-\plainsecheading {#1}\gdef\thissection{#1}%
+\plainsubsecheading {#1}\gdef\thissection{#1}%
{\chapternofonts%
\edef\temp{{\realbackslash unnumbsubsecentry{#1}{\noexpand\folio}}}%
\escapechar=`\\%
@@ -2714,7 +2956,7 @@ July\or August\or September\or October\or November\or December\fi
\outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy}
\def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
\def\unnumberedsubsubseczzz #1{\seccheck{unnumberedsubsubsec}%
-\plainsecheading {#1}\gdef\thissection{#1}%
+\plainsubsubsecheading {#1}\gdef\thissection{#1}%
{\chapternofonts%
\edef\temp{{\realbackslash unnumbsubsubsecentry{#1}{\noexpand\folio}}}%
\escapechar=`\\%
@@ -2752,10 +2994,10 @@ July\or August\or September\or October\or November\or December\fi
% NOTE on use of \vbox for chapter headings, section headings, and
% such:
-% 1) We use \vbox rather than the earlier \line to permit
-% overlong headings to fold.
-% 2) \hyphenpenalty is set to 10000 because hyphenation in a
-% heading is obnoxious; this forbids it.
+% 1) We use \vbox rather than the earlier \line to permit
+% overlong headings to fold.
+% 2) \hyphenpenalty is set to 10000 because hyphenation in a
+% heading is obnoxious; this forbids it.
% 3) Likewise, headings look best if no \parindent is used, and
% if justification is not attempted. Hence \raggedright.
@@ -2773,11 +3015,10 @@ July\or August\or September\or October\or November\or December\fi
\parindent=0pt\raggedright
\rm #1\hfill}}\bigskip \par\penalty 200}
-\def\heading{\parsearg\secheadingi}
-
-\def\subheading{\parsearg\subsecheadingi}
-
-\def\subsubheading{\parsearg\subsubsecheadingi}
+% @heading, @subheading, @subsubheading.
+\def\heading{\parsearg\plainsecheading}
+\def\subheading{\parsearg\plainsubsecheading}
+\def\subsubheading{\parsearg\plainsubsubsecheading}
% These macros generate a chapter, section, etc. heading only
% (including whitespace, linebreaking, etc. around it),
@@ -2791,7 +3032,7 @@ July\or August\or September\or October\or November\or December\fi
%%% Define plain chapter starts, and page on/off switching for it
% Parameter controlling skip before chapter headings (if needed)
-\newskip \chapheadingskip \chapheadingskip = 30pt plus 8pt minus 4pt
+\newskip\chapheadingskip
\def\chapbreak{\dobreak \chapheadingskip {-4000}}
\def\chappager{\par\vfill\supereject}
@@ -2800,15 +3041,18 @@ July\or August\or September\or October\or November\or December\fi
\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
\def\CHAPPAGoff{
+\global\let\contentsalignmacro = \chappager
\global\let\pchapsepmacro=\chapbreak
\global\let\pagealignmacro=\chappager}
\def\CHAPPAGon{
+\global\let\contentsalignmacro = \chappager
\global\let\pchapsepmacro=\chappager
\global\let\pagealignmacro=\chappager
\global\def\HEADINGSon{\HEADINGSsingle}}
\def\CHAPPAGodd{
+\global\let\contentsalignmacro = \chapoddpage
\global\let\pchapsepmacro=\chapoddpage
\global\let\pagealignmacro=\chapoddpage
\global\def\HEADINGSon{\HEADINGSdouble}}
@@ -2817,25 +3061,39 @@ July\or August\or September\or October\or November\or December\fi
\def\CHAPFplain{
\global\let\chapmacro=\chfplain
-\global\let\unnumbchapmacro=\unnchfplain}
+\global\let\unnumbchapmacro=\unnchfplain
+\global\let\centerchapmacro=\centerchfplain}
-\def\chfplain #1#2{%
+% Plain chapter opening.
+% #1 is the text, #2 the chapter number or empty if unnumbered.
+\def\chfplain#1#2{%
\pchapsepmacro
{%
- \chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
- \parindent=0pt\raggedright
- \rm #2\enspace #1}%
+ \chapfonts \rm
+ \def\chapnum{#2}%
+ \setbox0 = \hbox{#2\ifx\chapnum\empty\else\enspace\fi}%
+ \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+ \hangindent = \wd0 \centerparametersmaybe
+ \unhbox0 #1\par}%
}%
- \bigskip
- \penalty5000
+ \nobreak\bigskip % no page break after a chapter title
+ \nobreak
}
-\def\unnchfplain #1{%
-\pchapsepmacro %
-{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
- \parindent=0pt\raggedright
- \rm #1\hfill}}\bigskip \par\penalty 10000 %
-}
+% Plain opening for unnumbered.
+\def\unnchfplain#1{\chfplain{#1}{}}
+
+% @centerchap -- centered and unnumbered.
+\let\centerparametersmaybe = \relax
+\def\centerchfplain#1{{%
+ \def\centerparametersmaybe{%
+ \advance\rightskip by 3\rightskip
+ \leftskip = \rightskip
+ \parfillskip = 0pt
+ }%
+ \chfplain{#1}{}%
+}}
+
\CHAPFplain % The default
\def\unnchfopen #1{%
@@ -2849,73 +3107,81 @@ July\or August\or September\or October\or November\or December\fi
\par\penalty 5000 %
}
+\def\centerchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt
+ \hfill {\rm #1}\hfill}}\bigskip \par\penalty 10000 %
+}
+
\def\CHAPFopen{
\global\let\chapmacro=\chfopen
-\global\let\unnumbchapmacro=\unnchfopen}
+\global\let\unnumbchapmacro=\unnchfopen
+\global\let\centerchapmacro=\centerchfopen}
+
-% Parameter controlling skip before section headings.
+% Section titles.
+\newskip\secheadingskip
+\def\secheadingbreak{\dobreak \secheadingskip {-1000}}
+\def\secheading#1#2#3{\sectionheading{sec}{#2.#3}{#1}}
+\def\plainsecheading#1{\sectionheading{sec}{}{#1}}
-\newskip \subsecheadingskip \subsecheadingskip = 17pt plus 8pt minus 4pt
+% Subsection titles.
+\newskip \subsecheadingskip
\def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}}
+\def\subsecheading#1#2#3#4{\sectionheading{subsec}{#2.#3.#4}{#1}}
+\def\plainsubsecheading#1{\sectionheading{subsec}{}{#1}}
-\newskip \secheadingskip \secheadingskip = 21pt plus 8pt minus 4pt
-\def\secheadingbreak{\dobreak \secheadingskip {-1000}}
+% Subsubsection titles.
+\let\subsubsecheadingskip = \subsecheadingskip
+\let\subsubsecheadingbreak = \subsecheadingbreak
+\def\subsubsecheading#1#2#3#4#5{\sectionheading{subsubsec}{#2.#3.#4.#5}{#1}}
+\def\plainsubsubsecheading#1{\sectionheading{subsubsec}{}{#1}}
-% @paragraphindent is defined for the Info formatting commands only.
-\let\paragraphindent=\comment
-% Section fonts are the base font at magstep2, which produces
-% a size a bit more than 14 points in the default situation.
-
-\def\secheading #1#2#3{\secheadingi {#2.#3\enspace #1}}
-\def\plainsecheading #1{\secheadingi {#1}}
-\def\secheadingi #1{{\advance \secheadingskip by \parskip %
-\secheadingbreak}%
-{\secfonts \vbox{\hyphenpenalty=10000\tolerance=5000
- \parindent=0pt\raggedright
- \rm #1\hfill}}%
-\ifdim \parskip<10pt \kern 10pt\kern -\parskip\fi \penalty 10000 }
-
-
-% Subsection fonts are the base font at magstep1,
-% which produces a size of 12 points.
-
-\def\subsecheading #1#2#3#4{\subsecheadingi {#2.#3.#4\enspace #1}}
-\def\subsecheadingi #1{{\advance \subsecheadingskip by \parskip %
-\subsecheadingbreak}%
-{\subsecfonts \vbox{\hyphenpenalty=10000\tolerance=5000
- \parindent=0pt\raggedright
- \rm #1\hfill}}%
-\ifdim \parskip<10pt \kern 10pt\kern -\parskip\fi \penalty 10000 }
-
-\def\subsubsecfonts{\subsecfonts} % Maybe this should change:
- % Perhaps make sssec fonts scaled
- % magstep half
-\def\subsubsecheading #1#2#3#4#5{\subsubsecheadingi {#2.#3.#4.#5\enspace #1}}
-\def\subsubsecheadingi #1{{\advance \subsecheadingskip by \parskip %
-\subsecheadingbreak}%
-{\subsubsecfonts \vbox{\hyphenpenalty=10000\tolerance=5000
- \parindent=0pt\raggedright
- \rm #1\hfill}}%
-\ifdim \parskip<10pt \kern 10pt\kern -\parskip\fi \penalty 10000}
+% Print any size section title.
+%
+% #1 is the section type (sec/subsec/subsubsec), #2 is the section
+% number (maybe empty), #3 the text.
+\def\sectionheading#1#2#3{%
+ {%
+ \expandafter\advance\csname #1headingskip\endcsname by \parskip
+ \csname #1headingbreak\endcsname
+ }%
+ {%
+ % Switch to the right set of fonts.
+ \csname #1fonts\endcsname \rm
+ %
+ % Only insert the separating space if we have a section number.
+ \def\secnum{#2}%
+ \setbox0 = \hbox{#2\ifx\secnum\empty\else\enspace\fi}%
+ %
+ \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+ \hangindent = \wd0 % zero if no section number
+ \unhbox0 #3}%
+ }%
+ \ifdim\parskip<10pt \nobreak\kern10pt\nobreak\kern-\parskip\fi \nobreak
+}
\message{toc printing,}
-
% Finish up the main text and prepare to read what we've written
% to \contentsfile.
\newskip\contentsrightmargin \contentsrightmargin=1in
\def\startcontents#1{%
- \pagealignmacro
+ % If @setchapternewpage on, and @headings double, the contents should
+ % start on an odd page, unlike chapters. Thus, we maintain
+ % \contentsalignmacro in parallel with \pagealignmacro.
+ % From: Torbjorn Granlund <tege@matematik.su.se>
+ \contentsalignmacro
\immediate\closeout \contentsfile
\ifnum \pageno>0
- \pageno = -1 % Request roman numbered pages.
+ \pageno = -1 % Request roman numbered pages.
\fi
% Don't need to put `Contents' or `Short Contents' in the headline.
% It is abundantly clear what they are.
\unnumbchapmacro{#1}\def\thischapter{}%
- \begingroup % Set up to handle contents files properly.
+ \begingroup % Set up to handle contents files properly.
\catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11
\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi
\raggedbottom % Worry more about breakpoints than the bottom.
@@ -2941,6 +3207,7 @@ July\or August\or September\or October\or November\or December\fi
\secfonts
\let\rm=\shortcontrm \let\bf=\shortcontbf \let\sl=\shortcontsl
\rm
+ \hyphenpenalty = 10000
\advance\baselineskip by 1pt % Open it up a little.
\def\secentry ##1##2##3##4{}
\def\unnumbsecentry ##1##2{}
@@ -2984,7 +3251,7 @@ July\or August\or September\or October\or November\or December\fi
% This space should be plenty, since a single number is .5em, and the
% widest letter (M) is 1em, at least in the Computer Modern fonts.
% (This space doesn't include the extra space that gets added after
- % the label; that gets put in in \shortchapentry above.)
+ % the label; that gets put in by \shortchapentry above.)
\advance\dimen0 by 1.1em
\hbox to \dimen0{#1\hfil}%
}
@@ -3005,22 +3272,21 @@ July\or August\or September\or October\or November\or December\fi
\dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}}
\def\unnumbsubsubsecentry#1#2{\dosubsubsecentry{#1}{#2}}
-
% This parameter controls the indentation of the various levels.
\newdimen\tocindent \tocindent = 3pc
% Now for the actual typesetting. In all these, #1 is the text and #2 is the
% page number.
%
-% If the toc has to be broken over pages, we would want to be at chapters
+% If the toc has to be broken over pages, we want it to be at chapters
% if at all possible; hence the \penalty.
\def\dochapentry#1#2{%
- \penalty-300 \vskip\baselineskip
+ \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip
\begingroup
\chapentryfonts
\tocentry{#1}{\dopageno{#2}}%
\endgroup
- \nobreak\vskip .25\baselineskip
+ \nobreak\vskip .25\baselineskip plus.1\baselineskip
}
\def\dosecentry#1#2{\begingroup
@@ -3045,7 +3311,7 @@ July\or August\or September\or October\or November\or December\fi
%
% \turnoffactive is for the sake of @" used for umlauts.
\def\tocentry#1#2{\begingroup
- \hyphenpenalty = 10000
+ \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks
\entry{\turnoffactive #1}{\turnoffactive #2}%
\endgroup}
@@ -3070,8 +3336,6 @@ July\or August\or September\or October\or November\or December\fi
\newbox\pushcharbox \newbox\bullbox
\newbox\equivbox \newbox\errorbox
-\let\ptexequiv = \equiv
-
%{\tentt
%\global\setbox\dblarrowbox = \hbox to 1em{\hfil$\Rightarrow$\hfil}
%\global\setbox\longdblarrowbox = \hbox to 1em{\hfil$\mapsto$\hfil}
@@ -3082,12 +3346,11 @@ July\or August\or September\or October\or November\or December\fi
% depth .1ex\hfil}
%}
+% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
\def\point{$\star$}
-
\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}}
\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
-
\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}}
% Adapted from the TeXbook's \boxit.
@@ -3119,7 +3382,7 @@ July\or August\or September\or October\or November\or December\fi
\catcode `\$=3 \catcode `\&=4 \catcode `\#=6
\catcode `\^=7 \catcode `\_=8 \catcode `\~=13 \let~=\tie
\catcode `\%=14
-\catcode 43=12
+\catcode 43=12 % plus
\catcode`\"=12
\catcode`\==12
\catcode`\|=12
@@ -3127,16 +3390,18 @@ July\or August\or September\or October\or November\or December\fi
\catcode`\>=12
\escapechar=`\\
%
+\let\,=\ptexcomma
\let\~=\ptextilde
\let\{=\ptexlbrace
\let\}=\ptexrbrace
\let\.=\ptexdot
\let\*=\ptexstar
\let\dots=\ptexdots
+\def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}
+\def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}
\def\@{@}%
\let\bullet=\ptexbullet
-\let\b=\ptexb \let\c=\ptexc \let\i=\ptexi \let\t=\ptext \let\l=\ptexl
-\let\L=\ptexL
+\let\b=\ptexb \let\c=\ptexc \let\i=\ptexi \let\t=\ptext
%
\let\Etex=\endgroup}
@@ -3195,50 +3460,50 @@ July\or August\or September\or October\or November\or December\fi
\def\cbl{{\circle\char'012\hskip -6pt}}
\def\cbr{{\hskip 6pt\circle\char'011}}
\def\carttop{\hbox to \cartouter{\hskip\lskip
- \ctl\leaders\hrule height\circthick\hfil\ctr
- \hskip\rskip}}
+ \ctl\leaders\hrule height\circthick\hfil\ctr
+ \hskip\rskip}}
\def\cartbot{\hbox to \cartouter{\hskip\lskip
- \cbl\leaders\hrule height\circthick\hfil\cbr
- \hskip\rskip}}
+ \cbl\leaders\hrule height\circthick\hfil\cbr
+ \hskip\rskip}}
%
\newskip\lskip\newskip\rskip
\long\def\cartouche{%
\begingroup
- \lskip=\leftskip \rskip=\rightskip
- \leftskip=0pt\rightskip=0pt %we want these *outside*.
- \cartinner=\hsize \advance\cartinner by-\lskip
- \advance\cartinner by-\rskip
- \cartouter=\hsize
- \advance\cartouter by 18pt % allow for 3pt kerns on either
-% side, and for 6pt waste from
-% each corner char
- \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
- % Flag to tell @lisp, etc., not to narrow margin.
- \let\nonarrowing=\comment
- \vbox\bgroup
- \baselineskip=0pt\parskip=0pt\lineskip=0pt
- \carttop
- \hbox\bgroup
- \hskip\lskip
- \vrule\kern3pt
- \vbox\bgroup
- \hsize=\cartinner
- \kern3pt
- \begingroup
- \baselineskip=\normbskip
- \lineskip=\normlskip
- \parskip=\normpskip
- \vskip -\parskip
+ \lskip=\leftskip \rskip=\rightskip
+ \leftskip=0pt\rightskip=0pt %we want these *outside*.
+ \cartinner=\hsize \advance\cartinner by-\lskip
+ \advance\cartinner by-\rskip
+ \cartouter=\hsize
+ \advance\cartouter by 18pt % allow for 3pt kerns on either
+% side, and for 6pt waste from
+% each corner char
+ \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
+ % Flag to tell @lisp, etc., not to narrow margin.
+ \let\nonarrowing=\comment
+ \vbox\bgroup
+ \baselineskip=0pt\parskip=0pt\lineskip=0pt
+ \carttop
+ \hbox\bgroup
+ \hskip\lskip
+ \vrule\kern3pt
+ \vbox\bgroup
+ \hsize=\cartinner
+ \kern3pt
+ \begingroup
+ \baselineskip=\normbskip
+ \lineskip=\normlskip
+ \parskip=\normpskip
+ \vskip -\parskip
\def\Ecartouche{%
- \endgroup
- \kern3pt
- \egroup
- \kern3pt\vrule
- \hskip\rskip
- \egroup
- \cartbot
- \egroup
+ \endgroup
+ \kern3pt
+ \egroup
+ \kern3pt\vrule
+ \hskip\rskip
+ \egroup
+ \cartbot
+ \egroup
\endgroup
}}
@@ -3301,8 +3566,7 @@ July\or August\or September\or October\or November\or December\fi
\let\Esmalllisp = \nonfillfinish
\let\Esmallexample = \nonfillfinish
%
- % Smaller interline space and fonts for small examples.
- \setleading{10pt}%
+ % Smaller fonts for small examples.
\indexfonts \tt
\rawbackslash % make \ output the \ character from the current font (tt)
\gobble
@@ -3542,17 +3806,16 @@ July\or August\or September\or October\or November\or December\fi
}
% Fine, but then we have to eventually remove the \empty *and* the
-% braces (if any). That's what this does, putting the result in \tptemp.
+% braces (if any). That's what this does.
%
-\def\removeemptybraces\empty#1\relax{\def\tptemp{#1}}%
+\def\removeemptybraces\empty#1\relax{#1}
% After \spacesplit has done its work, this is called -- #1 is the final
% thing to call, #2 the type name (which starts with \empty), and #3
% (which might be empty) the arguments.
%
\def\parsetpheaderline#1#2#3{%
- \removeemptybraces#2\relax
- #1{\tptemp}{#3}%
+ #1{\removeemptybraces#2\relax}{#3}%
}%
\def\defopvarparsebody #1#2#3#4#5 {\begingroup\inENV %
@@ -3786,19 +4049,21 @@ July\or August\or September\or October\or November\or December\fi
\def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader}
-% #1 is the data type. #2 is the name.
+% #1 is the data type. #2 is the name, perhaps followed by text that
+% is actually part of the data type, which should not be put into the index.
\def\deftypevarheader #1#2{%
-\doind {vr}{\code{#2}}% Make entry in variables index
+\dovarind#2 \relax% Make entry in variables index
\begingroup\defname {\defheaderxcond#1\relax$$$#2}{Variable}%
\interlinepenalty=10000
\endgraf\penalty 10000\vskip -\parskip\penalty 10000
\endgroup}
+\def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}}
% @deftypevr {Global Flag} int enable
\def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader}
-\def\deftypevrheader #1#2#3{\doind {vr}{\code{#3}}%
+\def\deftypevrheader #1#2#3{\dovarind#3 \relax%
\begingroup\defname {\defheaderxcond#2\relax$$$#3}{#1}
\interlinepenalty=10000
\endgraf\penalty 10000\vskip -\parskip\penalty 10000
@@ -3830,6 +4095,7 @@ July\or August\or September\or October\or November\or December\fi
\def\deftpx #1 {\errmessage{@deftpx in invalid context}}
+
\message{cross reference,}
% Define cross-reference macros
\newwrite \auxfile
@@ -3837,6 +4103,11 @@ July\or August\or September\or October\or November\or December\fi
\newif\ifhavexrefs % True if xref values are known.
\newif\ifwarnedxrefs % True if we warned once that they aren't known.
+% @inforef is simple.
+\def\inforef #1{\inforefzzz #1,,,,**}
+\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+ node \samp{\ignorespaces#1{}}}
+
% \setref{foo} defines a cross-reference point named foo.
\def\setref#1{%
@@ -3915,7 +4186,7 @@ July\or August\or September\or October\or November\or December\fi
% Use \turnoffactive so that punctuation chars such as underscore
% work in node names.
-\def\dosetq #1#2{{\let\folio=0 \turnoffactive \auxhat%
+\def\dosetq #1#2{{\let\folio=0 \turnoffactive
\edef\next{\write\auxfile{\internalsetq {#1}{#2}}}%
\next}}
@@ -3984,84 +4255,101 @@ July\or August\or September\or October\or November\or December\fi
#2% Output the suffix in any case.
}
-% Read the last existing aux file, if any. No error if none exists.
-
% This is the macro invoked by entries in the aux file.
-\def\xrdef #1#2{
-{\catcode`\'=\other\expandafter \gdef \csname X#1\endcsname {#2}}}
+\def\xrdef #1#2{{%
+ \catcode`\'=\other
+ \expandafter\gdef\csname X#1\endcsname{#2}%
+}}
-\def\readauxfile{%
-\begingroup
-\catcode `\^^@=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode `\^^C=\other
-\catcode `\^^D=\other
-\catcode `\^^E=\other
-\catcode `\^^F=\other
-\catcode `\^^G=\other
-\catcode `\^^H=\other
-\catcode `\ =\other
-\catcode `\^^L=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode `\=\other
-\catcode 26=\other
-\catcode `\^^[=\other
-\catcode `\^^\=\other
-\catcode `\^^]=\other
-\catcode `\^^^=\other
-\catcode `\^^_=\other
-\catcode `\@=\other
-\catcode `\^=\other
-\catcode `\~=\other
-\catcode `\[=\other
-\catcode `\]=\other
-\catcode`\"=\other
-\catcode`\_=\other
-\catcode`\|=\other
-\catcode`\<=\other
-\catcode`\>=\other
-\catcode `\$=\other
-\catcode `\#=\other
-\catcode `\&=\other
-% `\+ does not work, so use 43.
-\catcode 43=\other
-% Make the characters 128-255 be printing characters
-{%
- \count 1=128
- \def\loop{%
- \catcode\count 1=\other
- \advance\count 1 by 1
- \ifnum \count 1<256 \loop \fi
+% Read the last existing aux file, if any. No error if none exists.
+\def\readauxfile{\begingroup
+ \catcode`\^^@=\other
+ \catcode`\=\other
+ \catcode`\=\other
+ \catcode`\^^C=\other
+ \catcode`\^^D=\other
+ \catcode`\^^E=\other
+ \catcode`\^^F=\other
+ \catcode`\^^G=\other
+ \catcode`\^^H=\other
+ \catcode`\ =\other
+ \catcode`\^^L=\other
+ \catcode`\=\other
+ \catcode`\=\other
+ \catcode`\=\other
+ \catcode`\=\other
+ \catcode`\=\other
+ \catcode`\=\other
+ \catcode`\=\other
+ \catcode`\=\other
+ \catcode`\=\other
+ \catcode`\=\other
+ \catcode`\=\other
+ \catcode`\=\other
+ \catcode26=\other
+ \catcode`\^^[=\other
+ \catcode`\^^\=\other
+ \catcode`\^^]=\other
+ \catcode`\^^^=\other
+ \catcode`\^^_=\other
+ \catcode`\@=\other
+ \catcode`\^=\other
+ % It was suggested to define this as 7, which would allow ^^e4 etc.
+ % in xref tags, i.e., node names. But since ^^e4 notation isn't
+ % supported in the main text, it doesn't seem desirable. Furthermore,
+ % that is not enough: for node names that actually contain a ^
+ % character, we would end up writing a line like this: 'xrdef {'hat
+ % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first
+ % argument, and \hat is not an expandable control sequence. It could
+ % all be worked out, but why? Either we support ^^ or we don't.
+ %
+ % The other change necessary for this was to define \auxhat:
+ % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter
+ % and then to call \auxhat in \setq.
+ %
+ \catcode`\~=\other
+ \catcode`\[=\other
+ \catcode`\]=\other
+ \catcode`\"=\other
+ \catcode`\_=\other
+ \catcode`\|=\other
+ \catcode`\<=\other
+ \catcode`\>=\other
+ \catcode`\$=\other
+ \catcode`\#=\other
+ \catcode`\&=\other
+ % `\+ does not work, so use 43.
+ \catcode43=\other
+ % Make the characters 128-255 be printing characters
+ {%
+ \count 1=128
+ \def\loop{%
+ \catcode\count 1=\other
+ \advance\count 1 by 1
+ \ifnum \count 1<256 \loop \fi
+ }%
}%
-}%
-% the aux file uses ' as the escape.
-% Turn off \ as an escape so we do not lose on
-% entries which were dumped with control sequences in their names.
-% For example, 'xrdef {$\leq $-fun}{page ...} made by @defun ^^
-% Reference to such entries still does not work the way one would wish,
-% but at least they do not bomb out when the aux file is read in.
-\catcode `\{=1 \catcode `\}=2
-\catcode `\%=\other
-\catcode `\'=0
-\catcode`\^=7 % to make ^^e4 etc usable in xref tags
-\catcode `\\=\other
-\openin 1 \jobname.aux
-\ifeof 1 \else \closein 1 \input \jobname.aux \global\havexrefstrue
-\global\warnedobstrue
-\fi
-% Open the new aux file. Tex will close it automatically at exit.
-\openout \auxfile=\jobname.aux
+ % The aux file uses ' as the escape (for now).
+ % Turn off \ as an escape so we do not lose on
+ % entries which were dumped with control sequences in their names.
+ % For example, 'xrdef {$\leq $-fun}{page ...} made by @defun ^^
+ % Reference to such entries still does not work the way one would wish,
+ % but at least they do not bomb out when the aux file is read in.
+ \catcode`\{=1
+ \catcode`\}=2
+ \catcode`\%=\other
+ \catcode`\'=0
+ \catcode`\\=\other
+ %
+ \openin 1 \jobname.aux
+ \ifeof 1 \else
+ \closein 1
+ \input \jobname.aux
+ \global\havexrefstrue
+ \global\warnedobstrue
+ \fi
+ % Open the new aux file. TeX will close it automatically at exit.
+ \openout\auxfile=\jobname.aux
\endgroup}
@@ -4072,7 +4360,8 @@ July\or August\or September\or October\or November\or December\fi
% The trailing space in the following definition for supereject is
% vital for proper filling; pages come out unaligned when you do a
% pagealignmacro call if that space before the closing brace is
-% removed.
+% removed. (Generally, numeric constants should always be followed by a
+% space to prevent strange expansion errors.)
\def\supereject{\par\penalty -20000\footnoteno =0 }
% @footnotestyle is meaningful for info output only..
@@ -4100,8 +4389,12 @@ July\or August\or September\or October\or November\or December\fi
% Don't bother with the trickery in plain.tex to not require the
% footnote text as a parameter. Our footnotes don't need to be so general.
+%
+% Oh yes, they do; otherwise, @ifset and anything else that uses
+% \parseargline fail inside footnotes because the tokens are fixed when
+% the footnote is read. --karl, 16nov96.
%
-\long\gdef\footnotezzz#1{\insert\footins{%
+\long\gdef\footnotezzz{\insert\footins\bgroup
% We want to typeset this text as a normal paragraph, even if the
% footnote reference occurs in (for example) a display environment.
% So reset some parameters.
@@ -4123,8 +4416,13 @@ July\or August\or September\or October\or November\or December\fi
% expands into a box, it must come within the paragraph, lest it
% provide a place where TeX can split the footnote.
\footstrut
- #1\strut}%
+ \futurelet\next\fo@t
}
+\def\fo@t{\ifcat\bgroup\noexpand\next \let\next\f@@t
+ \else\let\next\f@t\fi \next}
+\def\f@@t{\bgroup\aftergroup\@foot\let\next}
+\def\f@t#1{#1\@foot}
+\def\@foot{\strut\egroup}
}%end \catcode `\@=11
@@ -4197,13 +4495,18 @@ July\or August\or September\or October\or November\or December\fi
% Set some numeric style parameters, for 8.5 x 11 format.
-%\hsize = 6.5in
+\hsize = 6in
+\hoffset = .25in
\newdimen\defaultparindent \defaultparindent = 15pt
\parindent = \defaultparindent
-\parskip 18pt plus 1pt
-\setleading{15pt}
+\parskip 3pt plus 2pt minus 1pt
+\setleading{13.2pt}
\advance\topskip by 1.2cm
+\chapheadingskip = 15pt plus 4pt minus 2pt
+\secheadingskip = 12pt plus 3pt minus 2pt
+\subsecheadingskip = 9pt plus 2pt minus 2pt
+
% Prevent underfull vbox error messages.
\vbadness=10000
@@ -4226,30 +4529,28 @@ July\or August\or September\or October\or November\or December\fi
% Use @smallbook to reset parameters for 7x9.5 format (or else 7x9.25)
\def\smallbook{
-
-% These values for secheadingskip and subsecheadingskip are
-% experiments. RJC 7 Aug 1992
-\global\secheadingskip = 17pt plus 6pt minus 3pt
-\global\subsecheadingskip = 14pt plus 6pt minus 3pt
-
-\global\lispnarrowing = 0.3in
-\setleading{12pt}
-\advance\topskip by -1cm
-\global\parskip 3pt plus 1pt
-\global\hsize = 5in
-\global\vsize=7.5in
-\global\tolerance=700
-\global\hfuzz=1pt
-\global\contentsrightmargin=0pt
-\global\deftypemargin=0pt
-\global\defbodyindent=.5cm
-
-\global\pagewidth=\hsize
-\global\pageheight=\vsize
-
-\global\let\smalllisp=\smalllispx
-\global\let\smallexample=\smalllispx
-\global\def\Esmallexample{\Esmalllisp}
+ \global\chapheadingskip = 15pt plus 4pt minus 2pt
+ \global\secheadingskip = 12pt plus 3pt minus 2pt
+ \global\subsecheadingskip = 9pt plus 2pt minus 2pt
+ %
+ \global\lispnarrowing = 0.3in
+ \setleading{12pt}
+ \advance\topskip by -1cm
+ \global\parskip 2pt plus 1pt
+ \global\hsize = 5in
+ \global\vsize=7.5in
+ \global\tolerance=700
+ \global\hfuzz=1pt
+ \global\contentsrightmargin=0pt
+ \global\deftypemargin=0pt
+ \global\defbodyindent=.5cm
+ %
+ \global\pagewidth=\hsize
+ \global\pageheight=\vsize
+ %
+ \global\let\smalllisp=\smalllispx
+ \global\let\smallexample=\smalllispx
+ \global\def\Esmallexample{\Esmalllisp}
}
% Use @afourpaper to print on European A4 paper.
@@ -4272,12 +4573,19 @@ July\or August\or September\or October\or November\or December\fi
\global\pageheight=\vsize
}
+\bindingoffset=0pt
+\normaloffset=\hoffset
+\pagewidth=\hsize
+\pageheight=\vsize
+
% Allow control of the text dimensions. Parameters in order: textheight;
-% textwidth; \voffset; \hoffset (!); binding offset. All require a dimension;
+% textwidth; voffset; hoffset; binding offset; topskip.
+% All require a dimension;
% header is additional; added length extends the bottom of the page.
-\def\changepagesizes#1#2#3#4#5{
+\def\changepagesizes#1#2#3#4#5#6{
\global\vsize= #1
+ \global\topskip= #6
\advance\vsize by \topskip
\global\voffset= #3
\global\hsize= #2
@@ -4290,13 +4598,20 @@ July\or August\or September\or October\or November\or December\fi
\global\normaloffset= #4
\global\bindingoffset= #5}
-% This layout is compatible with Latex on A4 paper.
-
-\def\afourlatex{\changepagesizes{22cm}{15cm}{7mm}{4.6mm}{5mm}}
+% A specific text layout, 24x15cm overall, intended for A4 paper. Top margin
+% 29mm, hence bottom margin 28mm, nominal side margin 3cm.
+\def\afourlatex
+ {\global\tolerance=700
+ \global\hfuzz=1pt
+ \setleading{12pt}
+ \global\parskip 15pt plus 1pt
+ \advance\baselineskip by 1.6pt
+ \changepagesizes{237mm}{150mm}{3.6mm}{3.6mm}{3mm}{7mm}
+ }
% Use @afourwide to print on European A4 paper in wide format.
\def\afourwide{\afourpaper
-\changepagesizes{9.5in}{6.5in}{\hoffset}{\normaloffset}{\bindingoffset}}
+\changepagesizes{9.5in}{6.5in}{\hoffset}{\normaloffset}{\bindingoffset}{7mm}}
% Define macros to output various characters with catcode for normal text.
\catcode`\"=\other
@@ -4339,7 +4654,6 @@ July\or August\or September\or October\or November\or December\fi
\def~{{\tt \char '176}}
\chardef\hat=`\^
\catcode`\^=\active
-\def\auxhat{\def^{'hat}}
\def^{{\tt \hat}}
\catcode`\_=\active
diff --git a/eval.c b/eval.c
index 36e4d678..b3b7139d 100644
--- a/eval.c
+++ b/eval.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-1995 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-1996 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -33,6 +33,7 @@ static int eval_condition P((NODE *tree));
static NODE *op_assign P((NODE *tree));
static NODE *func_call P((NODE *name, NODE *arg_list));
static NODE *match_op P((NODE *tree));
+static char *nodetype2str P((NODETYPE type));
#if __GNUC__ < 2
NODE *_t; /* used as a temporary in macros */
@@ -142,6 +143,112 @@ char casetable[] = {
#endif
/*
+ * This table maps node types to strings for debugging.
+ * KEEP IN SYNC WITH awk.h!!!!
+ */
+static char *nodetypes[] = {
+ "Node_illegal",
+ "Node_times",
+ "Node_quotient",
+ "Node_mod",
+ "Node_plus",
+ "Node_minus",
+ "Node_cond_pair",
+ "Node_subscript",
+ "Node_concat",
+ "Node_exp",
+ "Node_preincrement",
+ "Node_predecrement",
+ "Node_postincrement",
+ "Node_postdecrement",
+ "Node_unary_minus",
+ "Node_field_spec",
+ "Node_assign",
+ "Node_assign_times",
+ "Node_assign_quotient",
+ "Node_assign_mod",
+ "Node_assign_plus",
+ "Node_assign_minus",
+ "Node_assign_exp",
+ "Node_and",
+ "Node_or",
+ "Node_equal",
+ "Node_notequal",
+ "Node_less",
+ "Node_greater",
+ "Node_leq",
+ "Node_geq",
+ "Node_match",
+ "Node_nomatch",
+ "Node_not",
+ "Node_rule_list",
+ "Node_rule_node",
+ "Node_statement_list",
+ "Node_if_branches",
+ "Node_expression_list",
+ "Node_param_list",
+ "Node_K_if",
+ "Node_K_while",
+ "Node_K_for",
+ "Node_K_arrayfor",
+ "Node_K_break",
+ "Node_K_continue",
+ "Node_K_print",
+ "Node_K_printf",
+ "Node_K_next",
+ "Node_K_exit",
+ "Node_K_do",
+ "Node_K_return",
+ "Node_K_delete",
+ "Node_K_getline",
+ "Node_K_function",
+ "Node_K_nextfile",
+ "Node_redirect_output",
+ "Node_redirect_append",
+ "Node_redirect_pipe",
+ "Node_redirect_pipein",
+ "Node_redirect_input",
+ "Node_var",
+ "Node_var_array",
+ "Node_val",
+ "Node_builtin",
+ "Node_line_range",
+ "Node_in_array",
+ "Node_func",
+ "Node_func_call",
+ "Node_cond_exp",
+ "Node_regex",
+ "Node_hashnode",
+ "Node_ahash",
+ "Node_NF",
+ "Node_NR",
+ "Node_FNR",
+ "Node_FS",
+ "Node_RS",
+ "Node_FIELDWIDTHS",
+ "Node_IGNORECASE",
+ "Node_OFS",
+ "Node_ORS",
+ "Node_OFMT",
+ "Node_CONVFMT",
+ "Node_final",
+ NULL
+};
+
+static char *
+nodetype2str(type)
+NODETYPE type;
+{
+ static char buf[40];
+
+ if (type >= Node_illegal && type <= Node_final)
+ return nodetypes[(int) type];
+
+ sprintf(buf, "unknown nodetype %d", (int) type);
+ return buf;
+}
+
+/*
* interpret:
* Tree is a bunch of rules to run. Returns zero if it hit an exit()
* statement
@@ -728,7 +835,7 @@ int iscond;
tree->vname);
default:
- fatal("illegal type (%d) in tree_eval", tree->type);
+ fatal("illegal type (%s) in tree_eval", nodetype2str(tree->type));
}
return 0;
}
@@ -1118,6 +1225,8 @@ Func_ptr *assign;
register NODE **aptr = NULL;
register NODE *n;
+ if (assign)
+ *assign = NULL; /* for safety */
if (ptr->type == Node_param_list)
ptr = stack_ptr[ptr->param_cnt];
@@ -1238,6 +1347,9 @@ Func_ptr *assign;
n = stack_ptr[n->param_cnt];
if ((n->flags & SCALAR) != 0)
fatal("attempt to use scalar parameter %d as an array", i);
+ } else if (n->type == Node_func) {
+ fatal("attempt to use function `%s' as array",
+ n->lnode->param);
}
aptr = assoc_lookup(n, concat_exp(ptr->rnode));
break;
@@ -1245,6 +1357,9 @@ Func_ptr *assign;
case Node_func:
fatal("`%s' is a function, assignment is not allowed",
ptr->lnode->param);
+
+ case Node_builtin:
+ fatal("assignment is not allowed to result of builtin function");
default:
cant_happen();
}
@@ -1261,7 +1376,7 @@ register NODE *tree;
register Regexp *rp;
int i;
int match = TRUE;
- int kludge_need_start = FALSE; /* XXX --- see below */
+ int kludge_need_start = FALSE; /* FIXME: --- see below */
if (tree->type == Node_nomatch)
match = FALSE;
@@ -1273,7 +1388,7 @@ register NODE *tree;
}
rp = re_update(tree);
/*
- * XXX
+ * FIXME:
*
* Any place where research() is called with a last parameter of
* FALSE, we need to use the avoid_dfa test. This is the only place
@@ -1306,9 +1421,12 @@ set_IGNORECASE()
}
if (do_traditional)
IGNORECASE = FALSE;
- else if (IGNORECASE_node->var_value->flags & STRING)
- IGNORECASE = (force_string(IGNORECASE_node->var_value)->stlen > 0);
- else if (IGNORECASE_node->var_value->flags & NUMBER)
+ else if ((IGNORECASE_node->var_value->flags & (STRING|STR)) != 0) {
+ if ((IGNORECASE_node->var_value->flags & MAYBE_NUM) == 0)
+ IGNORECASE = (force_string(IGNORECASE_node->var_value)->stlen > 0);
+ else
+ IGNORECASE = (force_number(IGNORECASE_node->var_value) != 0.0);
+ } else if ((IGNORECASE_node->var_value->flags & (NUM|NUMBER)) != 0)
IGNORECASE = (force_number(IGNORECASE_node->var_value) != 0.0);
else
IGNORECASE = FALSE; /* shouldn't happen */
diff --git a/field.c b/field.c
index 4b638b2c..c5b4e10f 100644
--- a/field.c
+++ b/field.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-1995 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-1996 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -24,6 +24,7 @@
*/
#include "awk.h"
+#include <assert.h>
typedef void (* Setfunc) P((long, char *, long, NODE *));
@@ -34,6 +35,8 @@ static long re_parse_field P((long, char **, int, NODE *,
Regexp *, Setfunc, NODE *));
static long def_parse_field P((long, char **, int, NODE *,
Regexp *, Setfunc, NODE *));
+static long posix_def_parse_field P((long, char **, int, NODE *,
+ Regexp *, Setfunc, NODE *));
static long null_parse_field P((long, char **, int, NODE *,
Regexp *, Setfunc, NODE *));
static long sc_parse_field P((long, char **, int, NODE *,
@@ -52,12 +55,11 @@ static int resave_fs;
static NODE *save_FS; /* save current value of FS when line is read,
* to be used in deferred parsing
*/
-static NODE **nodes; /* permanent repository of field nodes */
static int *FIELDWIDTHS = NULL;
NODE **fields_arr; /* array of pointers to the field nodes */
int field0_valid; /* $(>0) has not been changed yet */
-int default_FS; /* 1 when FS == " " */
+int default_FS; /* TRUE when FS == " " */
Regexp *FS_regexp = NULL;
/* init_fields --- set up the fields array to start with */
@@ -68,11 +70,10 @@ init_fields()
NODE *n;
emalloc(fields_arr, NODE **, sizeof(NODE *), "init_fields");
- emalloc(nodes, NODE **, sizeof(NODE *), "init_fields");
getnode(n);
*n = *Nnull_string;
- n->flags |= SCALAR;
- fields_arr[0] = nodes[0] = n;
+ n->flags |= (SCALAR|PERM);
+ fields_arr[0] = n;
parse_extent = fields_arr[0]->stptr;
save_FS = dupnode(FS_node->var_value);
field0_valid = TRUE;
@@ -88,12 +89,11 @@ long num;
register NODE *n;
erealloc(fields_arr, NODE **, (num + 1) * sizeof(NODE *), "grow_fields_arr");
- erealloc(nodes, NODE **, (num+1) * sizeof(NODE *), "grow_fields_arr");
for (t = nf_high_water + 1; t <= num; t++) {
getnode(n);
*n = *Nnull_string;
n->flags |= SCALAR;
- fields_arr[t] = nodes[t] = n;
+ fields_arr[t] = n;
}
nf_high_water = num;
}
@@ -112,11 +112,10 @@ NODE *dummy; /* not used -- just to make interface same as set_element */
if (num > nf_high_water)
grow_fields_arr(num);
- n = nodes[num];
+ n = fields_arr[num];
n->stptr = str;
n->stlen = len;
- n->flags = (PERM|STR|STRING|MAYBE_NUM);
- fields_arr[num] = n;
+ n->flags = (PERM|STR|STRING|MAYBE_NUM|SCALAR);
}
/* rebuild_record --- Someone assigned a value to $(something).
@@ -135,13 +134,17 @@ rebuild_record()
NODE *ofs;
char *ops;
register char *cops;
- register NODE **ptr;
+ long i;
+ char *f0start, *f0end;
+
+ assert(NF != -1);
tlen = 0;
ofs = force_string(OFS_node->var_value);
ofslen = ofs->stlen;
- for (ptr = &fields_arr[NF]; ptr > &fields_arr[0]; ptr--) {
- tmp = force_string(*ptr);
+ for (i = NF; i > 0; i--) {
+ tmp = fields_arr[i];
+ tmp = force_string(tmp);
tlen += tmp->stlen;
}
tlen += (NF - 1) * ofslen;
@@ -150,15 +153,17 @@ rebuild_record()
emalloc(ops, char *, tlen + 2, "rebuild_record");
cops = ops;
ops[0] = '\0';
- for (ptr = &fields_arr[1]; ptr <= &fields_arr[NF]; ptr++) {
- tmp = *ptr;
+ for (i = 1; i <= NF; i++) {
+ tmp = fields_arr[i];
+ /* copy field */
if (tmp->stlen == 1)
*cops++ = tmp->stptr[0];
else if (tmp->stlen != 0) {
memcpy(cops, tmp->stptr, tmp->stlen);
cops += tmp->stlen;
}
- if (ptr != &fields_arr[NF]) {
+ /* copy OFS */
+ if (i != NF) {
if (ofslen == 1)
*cops++ = ofs->stptr[0];
else if (ofslen != 0) {
@@ -168,8 +173,29 @@ rebuild_record()
}
}
tmp = make_str_node(ops, tlen, ALREADY_MALLOCED);
+
+ /*
+ * Since we are about to unref fields_arr[0], we want to find
+ * any fields that still point into it, and have them point
+ * into the new field zero.
+ */
+ f0start = fields_arr[0]->stptr;
+ f0end = fields_arr[0]->stptr + fields_arr[0]->stlen;
+ for (cops = ops, i = 1; i <= NF; i++) {
+ char *field_data = fields_arr[i]->stptr;
+
+ if (fields_arr[i]->stlen > 0
+ && f0start <= field_data && field_data < f0end)
+ fields_arr[i]->stptr = cops;
+
+ cops += fields_arr[i]->stlen + ofslen;
+ }
+
+ fields_arr[0]->flags &= ~PERM;
unref(fields_arr[0]);
+
fields_arr[0] = tmp;
+ fields_arr[0]->flags |= PERM;
field0_valid = TRUE;
}
@@ -180,20 +206,26 @@ rebuild_record()
*/
void
set_record(buf, cnt, freeold)
-char *buf;
-int cnt;
+char *buf; /* ignored if ! freeold */
+int cnt; /* ignored if ! freeold */
int freeold;
{
register int i;
+ NODE *n;
NF = -1;
- for (i = 1; i <= parse_high_water; i++)
+ for (i = 1; i <= parse_high_water; i++) {
unref(fields_arr[i]);
+ getnode(n);
+ *n = *Nnull_string;
+ n->flags |= SCALAR;
+ fields_arr[i] = n;
+ }
parse_high_water = 0;
/*
* $0 = $0 should resplit using the current value of FS, thus,
- * this if is executed orthogonally to the value of freeold.
+ * this is executed orthogonally to the value of freeold.
*/
if (resave_fs) {
resave_fs = FALSE;
@@ -202,13 +234,16 @@ int freeold;
}
if (freeold) {
unref(fields_arr[0]);
- nodes[0]->stptr = buf;
- nodes[0]->stlen = cnt;
- nodes[0]->stref = 1;
- nodes[0]->flags = (STRING|STR|PERM|MAYBE_NUM);
- fields_arr[0] = nodes[0];
+ getnode(n);
+ n->stptr = buf;
+ n->stlen = cnt;
+ n->stref = 1;
+ n->type = Node_val;
+ n->stfmt = -1;
+ n->flags = (STRING|STR|PERM|MAYBE_NUM|SCALAR);
+ fields_arr[0] = n;
}
- fields_arr[0]->flags |= MAYBE_NUM;
+ fields_arr[0]->flags |= (MAYBE_NUM|PERM);
field0_valid = TRUE;
}
@@ -227,13 +262,30 @@ void
set_NF()
{
register int i;
+ NODE *n;
+
+ assert(NF != -1);
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++) {
- unref(fields_arr[i]);
- fields_arr[i] = Nnull_string;
+ if (parse_high_water < NF) {
+ for (i = parse_high_water + 1; i <= NF; i++) {
+ unref(fields_arr[i]);
+ getnode(n);
+ *n = *Nnull_string;
+ n->flags |= SCALAR;
+ fields_arr[i] = n;
+ }
+ } else if (parse_high_water > 0) {
+ for (i = NF + 1; i <= parse_high_water; i++) {
+ unref(fields_arr[i]);
+ getnode(n);
+ *n = *Nnull_string;
+ n->flags |= SCALAR;
+ fields_arr[i] = n;
+ }
+ parse_high_water = NF;
}
field0_valid = FALSE;
}
@@ -303,6 +355,7 @@ NODE *n;
* 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)
long up_to; /* parse only up to this field number */
@@ -343,6 +396,74 @@ NODE *n;
/*
* special case: fs is single space, strip leading whitespace
*/
+ while (scan < end && (*scan == ' ' || *scan == '\t' || *scan == '\n'))
+ scan++;
+ if (scan >= end)
+ break;
+ field = scan;
+ while (*scan != ' ' && *scan != '\t' && *scan != '\n')
+ scan++;
+ (*set)(++nf, field, (long)(scan - field), n);
+ if (scan == end)
+ break;
+ }
+
+ /* everything done, restore original char at *end */
+ *end = sav;
+
+ *buf = scan;
+ return nf;
+}
+
+/*
+ * posix_def_parse_field --- default field parsing.
+ *
+ * This is called both from get_field() and from do_split()
+ * via (*parse_field)(). This variation is for when FS is a single space
+ * character. The only difference between this and def_parse_field()
+ * is that this one does not allow newlines to separate fields.
+ */
+
+static long
+posix_def_parse_field(up_to, buf, len, fs, rp, set, n)
+long up_to; /* parse only up to this field number */
+char **buf; /* on input: string to parse; on output: point to start next */
+int len;
+NODE *fs;
+Regexp *rp;
+Setfunc set; /* routine to set the value of the parsed field */
+NODE *n;
+{
+ register char *scan = *buf;
+ register long nf = parse_high_water;
+ register char *field;
+ register char *end = scan + len;
+ char sav;
+
+ if (up_to == HUGE)
+ nf = 0;
+ if (len == 0)
+ return nf;
+
+ /*
+ * Nasty special case. If FS set to "", return whole record
+ * as first field. This is not worth a separate function.
+ */
+ if (fs->stlen == 0) {
+ (*set)(++nf, *buf, len, n);
+ *buf += len;
+ return nf;
+ }
+
+ /* before doing anything save the char at *end */
+ sav = *end;
+ /* because it will be destroyed now: */
+
+ *end = ' '; /* sentinel character */
+ for (; nf < up_to; scan++) {
+ /*
+ * special case: fs is single space, strip leading whitespace
+ */
while (scan < end && (*scan == ' ' || *scan == '\t'))
scan++;
if (scan >= end)
@@ -431,7 +552,7 @@ NODE *n;
onecase = (IGNORECASE && isalpha(fschar));
if (onecase)
- fschar = casetable[fschar];
+ fschar = casetable[(int) fschar];
/* before doing anything save the char at *end */
sav = *end;
@@ -441,7 +562,7 @@ NODE *n;
for (; nf < up_to;) {
field = scan;
if (onecase) {
- while (casetable[*scan] != fschar)
+ while (casetable[(int) *scan] != fschar)
scan++;
} else {
while (*scan != fschar)
@@ -524,7 +645,6 @@ Func_ptr *assign; /* this field is on the LHS of an assign */
parse_high_water = NF;
}
rebuild_record();
- reset_record(); /* clear out fields array */
}
if (assign != NULL)
*assign = reset_record;
@@ -565,15 +685,9 @@ Func_ptr *assign; /* this field is on the LHS of an assign */
}
if (parse_high_water < requested) { /* requested beyond end of record */
if (assign != NULL) { /* expand record */
- register int i;
-
if (requested > nf_high_water)
grow_fields_arr(requested);
- /* fill in fields that don't exist */
- for (i = parse_high_water + 1; i <= requested; i++)
- fields_arr[i] = Nnull_string;
-
NF = requested;
parse_high_water = requested;
} else
@@ -605,14 +719,13 @@ NODE *
do_split(tree)
NODE *tree;
{
- NODE *t1, *t2, *t3, *tmp;
+ NODE *src, *arr, *sep, *tmp;
NODE *fs;
char *s;
long (*parseit) P((long, char **, int, NODE *,
Regexp *, Setfunc, NODE *));
Regexp *rp = NULL;
-
/*
* do dupnode(), to avoid problems like
* x = split(a[1], a, "blah")
@@ -620,45 +733,52 @@ NODE *tree;
* this also gives us complete call by value semantics.
*/
tmp = tree_eval(tree->lnode);
- t1 = dupnode(tmp);
+ src = dupnode(tmp);
free_temp(tmp);
- t2 = tree->rnode->lnode;
- t3 = tree->rnode->rnode->lnode;
+ arr = tree->rnode->lnode;
+ if (tree->rnode->rnode != NULL)
+ sep = tree->rnode->rnode->lnode; /* 3rd arg */
+ else
+ sep = NULL;
- (void) force_string(t1);
+ (void) force_string(src);
- if (t2->type == Node_param_list)
- t2 = stack_ptr[t2->param_cnt];
- if (t2->type != Node_var && t2->type != Node_var_array)
+ if (arr->type == Node_param_list)
+ arr = stack_ptr[arr->param_cnt];
+ if (arr->type != Node_var && arr->type != Node_var_array)
fatal("second argument of split is not an array");
- assoc_clear(t2);
+ arr->type = Node_var_array;
+ assoc_clear(arr);
- if (t3->re_flags & FS_DFLT) {
+ if (sep->re_flags & FS_DFLT) {
parseit = parse_field;
fs = force_string(FS_node->var_value);
rp = FS_regexp;
} else {
- tmp = force_string(tree_eval(t3->re_exp));
+ tmp = force_string(tree_eval(sep->re_exp));
if (tmp->stlen == 0)
parseit = null_parse_field;
- else if (tmp->stlen == 1) {
- if (tmp->stptr[0] == ' ')
- parseit = def_parse_field;
- else
+ else if (tmp->stlen == 1 && (sep->re_flags & CONST) == 0) {
+ if (tmp->stptr[0] == ' ') {
+ if (do_posix)
+ parseit = posix_def_parse_field;
+ else
+ parseit = def_parse_field;
+ } else
parseit = sc_parse_field;
} else {
parseit = re_parse_field;
- rp = re_update(t3);
+ rp = re_update(sep);
}
fs = tmp;
}
- s = t1->stptr;
- tmp = tmp_number((AWKNUM) (*parseit)(HUGE, &s, (int) t1->stlen,
- fs, rp, set_element, t2));
- unref(t1);
- free_temp(t3);
+ s = src->stptr;
+ tmp = tmp_number((AWKNUM) (*parseit)(HUGE, &s, (int) src->stlen,
+ fs, rp, set_element, arr));
+ unref(src);
+ free_temp(sep);
return tmp;
}
@@ -760,7 +880,10 @@ set_FS()
sprintf(buf, "[%c\n]", fs->stptr[0]);
}
} else {
- parse_field = def_parse_field;
+ if (do_posix)
+ parse_field = posix_def_parse_field;
+ else
+ parse_field = def_parse_field;
if (fs->stptr[0] == ' ' && fs->stlen == 1)
default_FS = TRUE;
else if (fs->stptr[0] != ' ' && fs->stlen == 1) {
@@ -789,3 +912,4 @@ using_fieldwidths()
{
return parse_field == fw_parse_field;
}
+
diff --git a/gawkmisc.c b/gawkmisc.c
index 0660587e..f7c0f3ce 100644
--- a/gawkmisc.c
+++ b/gawkmisc.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991 - 95 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991 - 96 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -53,6 +53,8 @@ typedef void *pointer;
typedef char *pointer;
#endif
+extern pointer xmalloc P((size_t bytes)); /* get rid of gcc warning */
+
pointer
xmalloc(bytes)
size_t bytes;
diff --git a/getopt.c b/getopt.c
index 023281cd..7306888b 100644
--- a/getopt.c
+++ b/getopt.c
@@ -3,7 +3,7 @@
"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, 94, 95
+ Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
@@ -19,6 +19,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+*/
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
Ditto for AIX 3.2 and <stdlib.h>. */
@@ -483,7 +484,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
const struct option *pfound = NULL;
int exact = 0;
int ambig = 0;
- int indfound;
+ int indfound = 0;
int option_index;
for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
@@ -625,6 +626,130 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
optopt = c;
return '?';
}
+ /* Convenience. Treat POSIX -W foo same as long option --foo */
+ if (temp[0] == 'W' && temp[1] == ';')
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = 0;
+ int option_index;
+
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (opterr)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr,
+ gettext ("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+
+ /* optarg is now the argument, see if it's in the
+ table of longopts. */
+
+ for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if (nameend - nextchar == strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+ if (ambig && !exact)
+ {
+ if (opterr)
+ fprintf (stderr, gettext ("%s: option `-W %s' is ambiguous\n"),
+ argv[0], argv[optind]);
+ nextchar += strlen (nextchar);
+ optind++;
+ return '?';
+ }
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (opterr)
+ fprintf (stderr,
+ gettext ("%s: option `-W %s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+
+ nextchar += strlen (nextchar);
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (opterr)
+ fprintf (stderr,
+ gettext ("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+ nextchar += strlen (nextchar);
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+ nextchar = NULL;
+ return 'W'; /* Let the application handle it. */
+ }
if (temp[1] == ':')
{
if (temp[2] == ':')
diff --git a/io.c b/io.c
index 5253af88..225ae86f 100644
--- a/io.c
+++ b/io.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-1995 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-1996 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -33,9 +33,19 @@
#include <sys/wait.h>
#endif /* HAVE_SYS_WAIT_H */
+#ifdef HAVE_MMAP
+#include <sys/mman.h>
+#ifndef MAP_FAILED
+#define MAP_FAILED ((caddr_t) -1)
+#endif /* ! defined (MAP_FAILED) */
+#endif /* HAVE_MMAP */
+
#ifndef O_RDONLY
#include <fcntl.h>
#endif
+#ifndef O_ACCMODE
+#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
+#endif
#include <assert.h>
@@ -73,6 +83,9 @@ static IOBUF *iop_open P((const char *file, const char *how));
static int gawk_pclose P((struct redirect *rp));
static int do_pathopen P((const char *file));
static int get_a_record P((char **out, IOBUF *iop, int rs, Regexp *RSre, int *errcode));
+#ifdef HAVE_MMAP
+static int mmap_get_record P((char **out, IOBUF *iop, int rs, Regexp *RSre, int *errcode));
+#endif /* HAVE_MMAP */
static int str2mode P((const char *mode));
static void spec_setup P((IOBUF *iop, int len, int allocate));
static int specfdopen P((IOBUF *iop, const char *name, const char *mode));
@@ -202,7 +215,9 @@ IOBUF *iop;
register int cnt;
int retval = 0;
- cnt = get_a_record(&begin, iop, RS->stptr[0], RS_regexp, NULL);
+ if ((cnt = iop->cnt) != EOF)
+ cnt = (*(iop->getrec))
+ (&begin, iop, RS->stptr[0], RS_regexp, NULL);
if (cnt == EOF) {
cnt = 0;
retval = 1;
@@ -249,18 +264,19 @@ IOBUF *iop;
ret = 0;
else
ret = close(iop->fd);
+
if (ret == -1)
warning("close of fd %d (`%s') failed (%s)", iop->fd,
iop->name, strerror(errno));
if ((iop->flag & IOP_NO_FREE) == 0) {
/*
- * be careful -- $0 may still reference the buffer even though
+ * Be careful -- $0 may still reference the buffer even though
* an explicit close is being done; in the future, maybe we
- * can do this a bit better
+ * can do this a bit better.
*/
if (iop->buf) {
if ((fields_arr[0]->stptr >= iop->buf)
- && (fields_arr[0]->stptr < iop->end)) {
+ && (fields_arr[0]->stptr < (iop->buf + iop->secsiz + iop->size))) {
NODE *t;
t = make_string(fields_arr[0]->stptr,
@@ -269,7 +285,12 @@ IOBUF *iop;
fields_arr [0] = t;
reset_record();
}
- free(iop->buf);
+ if ((iop->flag & IOP_MMAPPED) == 0)
+ free(iop->buf);
+#ifdef HAVE_MMAP
+ else
+ (void) munmap(iop->buf, iop->size);
+#endif
}
free((char *) iop);
}
@@ -350,9 +371,11 @@ int *errflg;
what);
tmp = force_string(tmp);
str = tmp->stptr;
+
if (str == NULL || *str == '\0')
fatal("expression for `%s' redirection has null string value",
what);
+
if (do_lint
&& (STREQN(str, "0", tmp->stlen) || STREQN(str, "1", tmp->stlen)))
warning("filename `%s' for `%s' redirection may be result of logical expression", str, what);
@@ -381,7 +404,8 @@ int *errflg;
rp->prev = NULL;
rp->next = red_head;
red_head = rp;
- }
+ } else
+ str = rp->value; /* get \0 terminated string */
while (rp->fp == NULL && rp->iop == NULL) {
if (rp->flag & RED_EOF)
/*
@@ -401,6 +425,9 @@ int *errflg;
mode = "a";
break;
case Node_redirect_pipe:
+ /* synchronize output before new pipe */
+ (void) flush_io();
+
if ((rp->fp = popen(str, "w")) == NULL)
fatal("can't open pipe (\"%s\") for output (%s)",
str, strerror(errno));
@@ -522,6 +549,16 @@ NODE *tree;
register struct redirect *rp;
tmp = force_string(tree_eval(tree->subnode));
+
+ /* icky special case: close(FILENAME) called. */
+ if (tree->subnode == FILENAME_node
+ || (tmp->stlen == FILENAME_node->var_value->stlen
+ && STREQN(tmp->stptr, FILENAME_node->var_value->stptr, tmp->stlen))) {
+ (void) nextfile(TRUE);
+ free_temp(tmp);
+ return tmp_number((AWKNUM) 0.0);
+ }
+
for (rp = red_head; rp != NULL; rp = rp->next) {
if (strlen(rp->value) == tmp->stlen
&& STREQN(rp->value, tmp->stptr, tmp->stlen))
@@ -571,7 +608,7 @@ int exitwarn;
what, rp->value);
/* SVR4 awk checks and warns about status of close */
- if (do_lint && status != 0) {
+ if (status != 0) {
char *s = strerror(errno);
/*
@@ -733,11 +770,11 @@ const char *name, *mode;
if (STREQN(name, "/dev/", 5) && stat((char *) name, &buf) == -1) {
cp = name + 5;
- if (STREQ(cp, "stdin") && (flag & O_RDONLY) == O_RDONLY)
+ if (STREQ(cp, "stdin") && (flag & O_ACCMODE) == O_RDONLY)
openfd = fileno(stdin);
- else if (STREQ(cp, "stdout") && (flag & O_WRONLY) == O_WRONLY)
+ else if (STREQ(cp, "stdout") && (flag & O_ACCMODE) == O_WRONLY)
openfd = fileno(stdout);
- else if (STREQ(cp, "stderr") && (flag & O_WRONLY) == O_WRONLY)
+ else if (STREQ(cp, "stderr") && (flag & O_ACCMODE) == O_WRONLY)
openfd = fileno(stderr);
else if (STREQN(cp, "fd/", 3)) {
cp += 3;
@@ -913,6 +950,10 @@ const char *name, *mode;
flag = str2mode(mode);
+ /*
+ * FIXME: remove the stat call, and always process these files
+ * internally.
+ */
if (STREQ(name, "-"))
openfd = fileno(stdin);
else if (do_traditional)
@@ -1195,7 +1236,7 @@ NODE *tree;
return tmp_number((AWKNUM) 0.0);
}
errcode = 0;
- cnt = get_a_record(&s, iop, RS->stptr[0], RS_regexp, &errcode);
+ cnt = (*(iop->getrec))(&s, iop, RS->stptr[0], RS_regexp, &errcode);
if (errcode != 0) {
if (! do_traditional) {
s = strerror(errcode);
@@ -1233,7 +1274,7 @@ NODE *tree;
lhs = get_lhs(tree->lnode, &after_assign);
unref(*lhs);
- *lhs = make_string(s, strlen(s));
+ *lhs = make_string(s, cnt);
(*lhs)->flags |= MAYBE_NUM;
/* we may have to regenerate $0 here! */
if (after_assign != NULL)
@@ -1374,9 +1415,42 @@ const char *name;
iop->off = iop->buf = NULL;
iop->cnt = 0;
iop->name = name;
+ iop->getrec = get_a_record;
+#ifdef HAVE_MMAP
+ if (S_ISREG(sbuf.st_mode) && sbuf.st_size > 0) {
+ iop->buf = iop->off = mmap((caddr_t) 0, sbuf.st_size,
+ PROT_READ|PROT_WRITE, MAP_PRIVATE,
+ fd, 0L);
+ /* cast is for buggy compilers (e.g. DEC OSF/1) */
+ if (iop->buf == (caddr_t)MAP_FAILED) {
+ iop->buf = iop->off = NULL;
+ goto out;
+ }
+
+ iop->flag |= IOP_MMAPPED;
+ iop->size = sbuf.st_size;
+ iop->end = iop->buf + iop->size;
+ iop->cnt = sbuf.st_size;
+ iop->getrec = mmap_get_record;
+
+#if defined(HAVE_MADVISE) && defined(MADV_SEQUENTIAL)
+ madvise(iop->buf, iop->size, MADV_SEQUENTIAL);
+#endif
+ }
+out:
+#endif /* HAVE_MMAP */
return iop;
}
+/* These macros used by both record reading routines */
+#define set_RT_to_null() \
+ (void)(! do_traditional && (unref(RT_node->var_value), \
+ RT_node->var_value = Nnull_string))
+
+#define set_RT(str, len) \
+ (void)(! do_traditional && (unref(RT_node->var_value), \
+ RT_node->var_value = make_string(str, len)))
+
/*
* get_a_record:
* Get the next record. Uses a "split buffer" where the latter part is
@@ -1407,20 +1481,12 @@ int *errcode; /* pointer to error variable */
register char *bp = iop->off;
char *bufend;
char *start = iop->off; /* beginning of record */
- char rs;
+ int rs;
static Regexp *RS_null_re = NULL;
Regexp *rsre = NULL;
- int continuing = FALSE; /* used for re matching */
+ int continuing = FALSE, continued = FALSE; /* used for re matching */
int onecase;
-#define set_RT_to_null() \
- (void)(! do_traditional && (unref(RT_node->var_value), \
- RT_node->var_value = Nnull_string))
-
-#define set_RT(str, len) \
- (void)(! do_traditional && (unref(RT_node->var_value), \
- RT_node->var_value = make_string(str, len)))
-
/* first time through */
if (RS_null_re == NULL) {
RS_null_re = make_regexp("\n\n+", 3, TRUE, TRUE);
@@ -1582,7 +1648,7 @@ int *errcode; /* pointer to error variable */
if (start + REEND(rsre, start) >= iop->end) {
if (iop->cnt != EOF) {
bp = iop->end;
- continuing = TRUE;
+ continuing = continued = TRUE;
continue;
}
}
@@ -1620,7 +1686,8 @@ int *errcode; /* pointer to error variable */
iop->cnt = bp - start;
}
if (iop->cnt == EOF
- && (((iop->flag & IOP_IS_INTERNAL) != 0) || start == bp)) {
+ && (((iop->flag & IOP_IS_INTERNAL) != 0)
+ || (start == bp && ! continued))) {
*out = NULL;
set_RT_to_null();
return EOF;
@@ -1675,6 +1742,141 @@ char *argv[];
}
#endif
+#ifdef HAVE_MMAP
+/* mmap_get_record --- pull a record out of a memory-mapped file */
+
+static int
+mmap_get_record(out, iop, grRS, RSre, errcode)
+char **out; /* pointer to pointer to data */
+IOBUF *iop; /* input IOP */
+register int grRS; /* first char in RS->stptr */
+Regexp *RSre; /* regexp for RS */
+int *errcode; /* pointer to error variable */
+{
+ register char *bp = iop->off;
+ char *start = iop->off; /* beginning of record */
+ int rs;
+ static Regexp *RS_null_re = NULL;
+ Regexp *rsre = NULL;
+ int onecase;
+ register char *end = iop->end;
+
+ /* first time through */
+ if (RS_null_re == NULL) {
+ RS_null_re = make_regexp("\n\n+", 3, TRUE, TRUE);
+ if (RS_null_re == NULL)
+ fatal("internal error: file `%s', line %d\n",
+ __FILE__, __LINE__);
+ }
+
+ if (iop->off >= iop->end) { /* previous record was last */
+ *out = NULL;
+ set_RT_to_null();
+ iop->cnt = EOF; /* tested by higher level code */
+ return EOF;
+ }
+
+ if (grRS == FALSE) /* special case: RS == "" */
+ rs = '\n';
+ else
+ rs = (char) grRS;
+
+ onecase = (IGNORECASE && isalpha(rs));
+ if (onecase)
+ rs = casetable[rs];
+
+ /* if RS = "", skip leading newlines at the front of the file */
+ if (grRS == FALSE && iop->off == iop->buf) {
+ for (bp = iop->off; *bp == '\n'; bp++)
+ continue;
+
+ if (bp != iop->off)
+ iop->off = start = bp;
+ }
+
+ /*
+ * Regexp based searching. Either RS = "" or RS = <regex>
+ * See comments in get_a_record.
+ */
+ if (! do_traditional && RSre != NULL) /* regexp */
+ rsre = RSre;
+ else if (grRS == FALSE) /* RS = "" */
+ rsre = RS_null_re;
+ else
+ rsre = NULL;
+
+ /*
+ * Look for regexp match of RS. Non-match conditions are:
+ * 1. No match at all
+ * 2. Match of a null string
+ * 3. Match ends at exact end of buffer
+ *
+ * #1 means that the record ends the file
+ * and there is no text that actually matched RS.
+ *
+ * #2: is probably like #1.
+ *
+ * #3 is simple; since we have the whole file mapped, it's
+ * the last record in the file.
+ */
+ if (rsre != NULL) {
+ if (research(rsre, start, 0, iop->end - start, TRUE) == -1
+ || RESTART(rsre, start) == REEND(rsre, start)) {
+ /* no matching text, we have the record */
+ *out = start;
+ iop->off = iop->end; /* all done with the record */
+ set_RT_to_null();
+ /* special case, don't allow trailing newlines */
+ if (grRS == FALSE && *(iop->end - 1) == '\n')
+ return iop->end - start - 1;
+ else
+ return iop->end - start;
+
+ }
+ /* have a match */
+ *out = start;
+ bp = start + RESTART(rsre, start);
+ set_RT(bp, REEND(rsre, start) - RESTART(rsre, start));
+ *bp = '\0';
+ iop->off = start + REEND(rsre, start);
+ return bp - start;
+ }
+
+ /*
+ * RS = "?", i.e., one character based searching.
+ *
+ * Alas, we can't just plug the sentinel character in at
+ * the end of the mmapp'ed file ( *(iop->end) = rs; ). This
+ * works if we're lucky enough to have a file that does not
+ * take up all of its last disk block. But if we end up with
+ * file whose size is an even multiple of the disk block size,
+ * assigning past the end of it delivers a SIGBUS. So, we have to
+ * add the extra test in the while loop at the front that looks
+ * for going past the end of the mapped object. Sigh.
+ */
+ /* search for RS, #2, RS = <single char> */
+ if (onecase) {
+ while (bp < end && casetable[*bp++] != rs)
+ continue;
+ } else {
+ while (bp < end && *bp++ != rs)
+ continue;
+ }
+ if (bp >= iop->end) {
+ /* at end, may have actually seen rs, or may not */
+ if (*(bp-1) == rs)
+ set_RT(bp - 1, 1); /* real RS seen */
+ else
+ set_RT_to_null();
+ } else
+ set_RT(bp - 1, 1);
+
+ iop->off = bp;
+ *out = start;
+ return bp - 1 - start;
+}
+#endif /* HAVE_MMAP */
+
/* set_RS --- update things as appropriate when RS is set */
void
diff --git a/main.c b/main.c
index 273b13b0..719e006d 100644
--- a/main.c
+++ b/main.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-1995 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-1996 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -27,14 +27,13 @@
#include "getopt.h"
#include "patchlevel.h"
-static void usage P((int exitval));
+static void usage P((int exitval, FILE *fp));
static void copyleft P((void));
static void cmdline_fs P((char *str));
static void init_args P((int argc0, int argc, char *argv0, char **argv));
static void init_vars P((void));
static void pre_assign P((char *v));
RETSIGTYPE catchsig P((int sig, int code));
-static void gawk_option P((char *optstr));
static void nostalgia P((void));
static void version P((void));
@@ -133,13 +132,16 @@ char **argv;
int c;
char *scan;
/* the + on the front tells GNU getopt not to rearrange argv */
- const char *optlist = "+F:f:v:W:m:";
+ const char *optlist = "+F:f:v:W;m:";
int stopped_early = FALSE;
int old_optind;
extern int optind;
extern int opterr;
extern char *optarg;
+ setlocale(LC_CTYPE, "");
+ setlocale(LC_COLLATE, "");
+
(void) signal(SIGFPE, (RETSIGTYPE (*) P((int))) catchsig);
(void) signal(SIGSEGV, (RETSIGTYPE (*) P((int))) catchsig);
#ifdef SIGBUS
@@ -155,7 +157,7 @@ char **argv;
version_string += 4;
if (argc < 2)
- usage(1);
+ usage(1, stderr);
/* initialize the null string */
Nnull_string = make_string("", 0);
@@ -206,7 +208,7 @@ char **argv;
* of a #! /bin/gawk line in an executable file
*/
scan = optarg;
- while (isspace(*scan))
+ while (ISSPACE(*scan))
scan++;
++numfiles;
@@ -224,18 +226,20 @@ char **argv;
case 'm':
/*
* Research awk extension.
- * -mf=nnn set # fields, gawk ignores
- * -mr=nnn set record length, ditto
+ * -mf nnn set # fields, gawk ignores
+ * -mr nnn set record length, ditto
*/
if (do_lint)
warning("-m[fr] option irrelevant in gawk");
- if ((optarg[0] != 'r' && optarg[0] != 'f')
- || optarg[1] != '=')
- warning("-m option usage: -m[fr]=nnn");
+ if (optarg[0] != 'r' && optarg[0] != 'f')
+ warning("-m option usage: `-m[fr] nnn'");
+ if (optarg[1] == '\0')
+ optind++;
break;
- case 'W': /* gawk specific options */
- gawk_option(optarg);
+ case 'W': /* gawk specific options - now in getopt_long */
+ fprintf(stderr, "%s: option `-W %s' unrecognized, ignored\n",
+ argv[0], optarg);
break;
/* These can only come from long form options */
@@ -253,7 +257,7 @@ char **argv;
break;
case 'u':
- usage(0);
+ usage(0, stdout); /* per coding stds */
break;
case 'V':
@@ -356,7 +360,7 @@ out:
/* No -f or --source options, use next arg */
if (numfiles == -1) {
if (optind > argc - 1 || stopped_early) /* no args left or no program */
- usage(1);
+ usage(1, stderr);
srcfiles[++numfiles].stype = CMDLINE;
srcfiles[numfiles].val = argv[optind];
optind++;
@@ -401,39 +405,42 @@ out:
/* usage --- print usage information and exit */
static void
-usage(exitval)
+usage(exitval, fp)
int exitval;
+FILE *fp;
{
char *opt1 = " -f progfile [--]";
char *regops = " [POSIX or GNU style options]";
- fprintf(stderr, "Usage: %s%s%s file ...\n\t%s%s [--] %cprogram%c file ...\n",
+ fprintf(fp, "Usage: %s%s%s file ...\n\t%s%s [--] %cprogram%c file ...\n",
myname, regops, opt1, myname, regops, quote, quote);
/* GNU long options info. Gack. */
- fputs("POSIX options:\t\tGNU long options:\n", stderr);
- fputs("\t-f progfile\t\t--file=progfile\n", stderr);
- fputs("\t-F fs\t\t\t--field-separator=fs\n", stderr);
- fputs("\t-v var=val\t\t--assign=var=val\n", stderr);
- fputs("\t-m[fr]=val\n", stderr);
- fputs("\t-W compat\t\t--compat\n", stderr);
- fputs("\t-W copyleft\t\t--copyleft\n", stderr);
- fputs("\t-W copyright\t\t--copyright\n", stderr);
- fputs("\t-W help\t\t\t--help\n", stderr);
- fputs("\t-W lint\t\t\t--lint\n", stderr);
- fputs("\t-W lint-old\t\t--lint-old\n", stderr);
+ fputs("POSIX options:\t\tGNU long options:\n", fp);
+ fputs("\t-f progfile\t\t--file=progfile\n", fp);
+ fputs("\t-F fs\t\t\t--field-separator=fs\n", fp);
+ fputs("\t-v var=val\t\t--assign=var=val\n", fp);
+ fputs("\t-m[fr] val\n", fp);
+ fputs("\t-W compat\t\t--compat\n", fp);
+ fputs("\t-W copyleft\t\t--copyleft\n", fp);
+ fputs("\t-W copyright\t\t--copyright\n", fp);
+ fputs("\t-W help\t\t\t--help\n", fp);
+ fputs("\t-W lint\t\t\t--lint\n", fp);
+ fputs("\t-W lint-old\t\t--lint-old\n", fp);
#ifdef NOSTALGIA
- fputs("\t-W nostalgia\t\t--nostalgia\n", stderr);
+ fputs("\t-W nostalgia\t\t--nostalgia\n", fp);
#endif
#ifdef DEBUG
- fputs("\t-W parsedebug\t\t--parsedebug\n", stderr);
+ fputs("\t-W parsedebug\t\t--parsedebug\n", fp);
#endif
- fputs("\t-W posix\t\t--posix\n", stderr);
- fputs("\t-W re-interval\t\t--re-interval\n", stderr);
- fputs("\t-W source=program-text\t--source=program-text\n", stderr);
- fputs("\t-W traditional\t\t--traditional\n", stderr);
- fputs("\t-W usage\t\t--usage\n", stderr);
- fputs("\t-W version\t\t--version\n", stderr);
+ fputs("\t-W posix\t\t--posix\n", fp);
+ fputs("\t-W re-interval\t\t--re-interval\n", fp);
+ fputs("\t-W source=program-text\t--source=program-text\n", fp);
+ fputs("\t-W traditional\t\t--traditional\n", fp);
+ fputs("\t-W usage\t\t--usage\n", fp);
+ fputs("\t-W version\t\t--version\n", fp);
+ fputs("\nReport bugs to bug-gnu-utils@prep.ai.mit.edu,\n", fp);
+ fputs("with a Cc: to arnold@gnu.ai.mit.edu\n", fp);
exit(exitval);
}
@@ -443,7 +450,7 @@ static void
copyleft()
{
static char blurb_part1[] =
-"Copyright (C) 1989, 1991-1995 Free Software Foundation.\n\
+"Copyright (C) 1989, 1991-1996 Free Software Foundation.\n\
\n\
This program is free software; you can redistribute it and/or modify\n\
it under the terms of the GNU General Public License as published by\n\
@@ -462,10 +469,11 @@ along with this program; if not, write to the Free Software\n\
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n";
/* multiple blurbs are needed for some brain dead compilers. */
- fputs(blurb_part1, stderr);
- fputs(blurb_part2, stderr);
- fputs(blurb_part3, stderr);
- fflush(stderr);
+ fputs(blurb_part1, stdout);
+ fputs(blurb_part2, stdout);
+ fputs(blurb_part3, stdout);
+ fflush(stdout);
+ exit(0);
}
/* cmdline_fs --- set FS from the command line */
@@ -674,7 +682,7 @@ char *v;
fprintf(stderr,
"%s: `%s' argument to `-v' not in `var=value' form\n",
myname, v);
- usage(1);
+ usage(1, stderr);
}
}
@@ -702,128 +710,6 @@ int sig, code;
/* NOTREACHED */
}
-/* gawk_option --- do gawk specific things */
-
-static void
-gawk_option(optstr)
-char *optstr;
-{
- char *cp;
-
- for (cp = optstr; *cp != '\0'; cp++) {
- /* keep this switch sorted as optioins are added */
- switch (*cp) {
- case ' ':
- case '\t':
- case ',':
- break;
- case 'c':
- case 'C':
- if (strncasecmp(cp, "copyright", 9) == 0) {
- cp += 8;
- copyleft();
- } else if (strncasecmp(cp, "copyleft", 8) == 0) {
- cp += 7;
- copyleft();
- } else if (strncasecmp(cp, "compat", 6) == 0) {
- cp += 5;
- do_traditional = TRUE;
- } else
- goto unknown;
- break;
- case 'H':
- case 'h':
- if (strncasecmp(cp, "help", 4) != 0)
- goto unknown;
- cp += 3;
- usage(0);
- break;
- case 'l':
- case 'L':
- if (strncasecmp(cp, "lint-old", 8) == 0) {
- cp += 7;
- do_lint_old = TRUE;
- } else if (strncasecmp(cp, "lint", 4) == 0) {
- cp += 3;
- do_lint = TRUE;
- } else
- goto unknown;
- break;
- case 'n':
- case 'N':
- /*
- * Undocumented feature,
- * inspired by nostalgia, and a T-shirt
- */
- if (strncasecmp(cp, "nostalgia", 9) != 0)
- goto unknown;
- nostalgia();
- break;
- case 'p':
- case 'P':
-#ifdef DEBUG
- if (strncasecmp(cp, "parsedebug", 10) == 0) {
- cp += 9;
- yydebug = 2;
- break;
- }
-#endif
- if (strncasecmp(cp, "posix", 5) != 0)
- goto unknown;
- cp += 4;
- do_posix = do_traditional = TRUE;
- break;
- case 'r':
- case 'R':
- if (strncasecmp(cp, "re-interval", 11) != 0)
- goto unknown;
- do_intervals = TRUE;
- break;
- case 's':
- case 'S':
- 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;
- srcfiles[numfiles].val = cp;
- return;
- }
- break;
- case 't':
- case 'T':
- if (strncasecmp(cp, "traditional", 11) != 0)
- goto unknown;
- do_traditional = TRUE;
- cp += 11;
- break;
- case 'U':
- case 'u':
- if (strncasecmp(cp, "usage", 5) != 0)
- goto unknown;
- cp += 4;
- usage(0);
- break;
- case 'v':
- case 'V':
- /* print version */
- if (strncasecmp(cp, "version", 7) != 0)
- goto unknown;
- else
- cp += 6;
- version();
- break;
- default:
- unknown:
- fprintf(stderr, "'%c' -- unknown option, ignored\n",
- *cp);
- break;
- }
- }
-}
-
/* nostalgia --- print the famous error message and die */
static void
@@ -838,7 +724,11 @@ nostalgia()
static void
version()
{
- fprintf(stderr, "%s, patchlevel %d\n", version_string, PATCHLEVEL);
- /* per GNU coding standards, exit successfully, do nothing else */
+ printf("%s.%d\n", version_string, PATCHLEVEL);
+ /*
+ * Per GNU coding standards, print copyright info,
+ * then exit successfully, do nothing else.
+ */
+ copyleft();
exit(0);
}
diff --git a/missing.c b/missing.c
index aa0d03cb..7494d766 100644
--- a/missing.c
+++ b/missing.c
@@ -34,10 +34,6 @@
#include "missing/memset.c"
#endif /* HAVE_MEMSET */
-#ifndef HAVE_RANDOM
-#include "missing/random.c"
-#endif /* HAVE_RANDOM */
-
#ifndef HAVE_STRNCASECMP
#include "missing/strncasecmp.c"
#endif /* HAVE_STRCASE */
diff --git a/missing/strftime.3 b/missing/strftime.3
index 76fc02a0..92d25b2c 100644
--- a/missing/strftime.3
+++ b/missing/strftime.3
@@ -89,7 +89,7 @@ with a 12-hour clock.
.TP
.B %S
is replaced by the second as a decimal number
-.RB ( 00 - 61 ).
+.RB ( 00 - 60 ).
.TP
.B %U
is replaced by the week number of the year (the first Sunday as the first
diff --git a/missing/strftime.c b/missing/strftime.c
index 478471c3..1e16868c 100644
--- a/missing/strftime.c
+++ b/missing/strftime.c
@@ -348,8 +348,8 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
strcpy(tbuf, ampm[1]);
break;
- case 'S': /* second, 00 - 61 */
- i = range(0, timeptr->tm_sec, 61);
+ case 'S': /* second, 00 - 60 */
+ i = range(0, timeptr->tm_sec, 60);
sprintf(tbuf, "%02d", i);
break;
@@ -562,7 +562,7 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
else
sprintf(tbuf, "%02d", y % 100);
break;
-#endif ISO_DATE_EXT
+#endif /* ISO_DATE_EXT */
default:
tbuf[0] = '%';
tbuf[1] = *format;
@@ -826,7 +826,7 @@ static char *array[] =
"(%%M) minute (00..59) %M",
"(%%O) Locale extensions (ignored) %O",
"(%%R) time, 24-hour (%%H:%%M) %R",
- "(%%S) second (00..61) %S",
+ "(%%S) second (00..60) %S",
"(%%T) time, 24-hour (%%H:%%M:%%S) %T",
"(%%U) week of year, Sunday as first day of week (00..53) %U",
"(%%V) week of year according to ISO 8601 %V",
diff --git a/msg.c b/msg.c
index a9fe66db..5bf3c2bc 100644
--- a/msg.c
+++ b/msg.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-1995 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-1996 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
diff --git a/node.c b/node.c
index cba10dfc..66c9ecb7 100644
--- a/node.c
+++ b/node.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-1995 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-1996 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -57,7 +57,7 @@ register NODE *n;
return 0.0;
cp = n->stptr;
- if (isalpha(*cp))
+ if (ISALPHA(*cp))
return 0.0;
cpend = cp + n->stlen;
@@ -72,7 +72,7 @@ register NODE *n;
} else
newflags = 0;
if (cpend - cp == 1) {
- if (isdigit(*cp)) {
+ if (ISDIGIT(*cp)) {
n->numbr = (AWKNUM)(*cp - '0');
n->flags |= newflags;
}
@@ -85,7 +85,7 @@ register NODE *n;
n->numbr = (AWKNUM) strtod((const char *) cp, &ptr);
/* POSIX says trailing space is OK for NUMBER */
- while (isspace(*ptr))
+ while (ISSPACE(*ptr))
ptr++;
*cpend = save;
/* the >= should be ==, but for SunOS 3.5 strtod() */
@@ -116,30 +116,18 @@ static const char *values[] = {
};
#define NVAL (sizeof(values)/sizeof(values[0]))
-/* r_force_string --- force a value to be a string */
+/* format_val --- format a numeric value based on format */
NODE *
-r_force_string(s)
+format_val(format, index, s)
+char *format;
+int index;
register NODE *s;
{
char buf[128];
register char *sp = buf;
double val;
-#ifdef DEBUG
- if (s == NULL)
- cant_happen();
- if (s->type != Node_val)
- cant_happen();
- if ((s->flags & STR) != 0
- && (s->stfmt == -1 || s->stfmt == CONVFMTidx))
- return s;
- if ((s->flags & NUM) == 0)
- cant_happen();
- 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) {
@@ -155,9 +143,9 @@ register NODE *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);
+ r = format_tree(format, fmt_list[index]->stlen, dummy);
s->flags = oflags;
- s->stfmt = (char) CONVFMTidx;
+ s->stfmt = (char) index;
s->stlen = r->stlen;
s->stptr = r->stptr;
freenode(r); /* Do not free_temp(r)! We want */
@@ -169,9 +157,9 @@ register NODE *s;
* no need for a "replacement" formatting by gawk,
* just use sprintf
*/
- sprintf(sp, CONVFMT, s->numbr);
+ sprintf(sp, format, s->numbr);
s->stlen = strlen(sp);
- s->stfmt = (char) CONVFMTidx;
+ s->stfmt = (char) index;
#endif /* GFMT_WORKAROUND */
} else {
/* integral value */
@@ -196,6 +184,29 @@ no_malloc:
return s;
}
+/* r_force_string --- force a value to be a string */
+
+NODE *
+r_force_string(s)
+register NODE *s;
+{
+#ifdef DEBUG
+ if (s == NULL)
+ cant_happen();
+ if (s->type != Node_val)
+ cant_happen();
+ if ((s->flags & NUM) == 0)
+ cant_happen();
+ if (s->stref <= 0)
+ cant_happen();
+ if ((s->flags & STR) != 0
+ && (s->stfmt == -1 || s->stfmt == CONVFMTidx))
+ return s;
+#endif
+
+ return format_val(CONVFMT, CONVFMTidx, s);
+}
+
/*
* dupnode:
* Duplicate a node. (For strings, "duplicate" means crank up the
@@ -463,17 +474,17 @@ char **string_ptr;
}
if (do_posix)
return ('x');
- if (! isxdigit((*string_ptr)[1])) {
+ if (! isxdigit((*string_ptr)[0])) {
warning("no hex digits in \\x escape sequence");
return ('x');
}
i = 0;
for (;;) {
- if (isxdigit((c = *(*string_ptr)++))) {
+ if (ISXDIGIT((c = *(*string_ptr)++))) {
i *= 16;
- if (isdigit(c))
+ if (ISDIGIT(c))
i += c - '0';
- else if (isupper(c))
+ else if (ISUPPER(c))
i += c - 'A' + 10;
else
i += c - 'a' + 10;
diff --git a/patchlevel.h b/patchlevel.h
index 2867bba9..131713a8 100644
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -1 +1 @@
-#define PATCHLEVEL 0
+#define PATCHLEVEL 1
diff --git a/pc/ChangeLog b/pc/ChangeLog
index 570c031b..04e5b419 100644
--- a/pc/ChangeLog
+++ b/pc/ChangeLog
@@ -1,3 +1,7 @@
+Thu Aug 1 19:46:00 1996 Scott Deifik <scottd@amgen.com>
+
+ * Makefile: Changes for MSC 8.
+
Wed Jan 10 22:58:55 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
* ChangeLog created.
diff --git a/pc/Makefile b/pc/Makefile
index cefd9c3d..a1329eb6 100644
--- a/pc/Makefile
+++ b/pc/Makefile
@@ -1,4 +1,4 @@
-# Makefile for gawk (GNU awk) 1 Sep 1995
+# Makefile for gawk (GNU awk) 7 Oct 1996
#
# - for GNU C (djgpp) [executable for DOS (32-bit)]
# - for GNU C (emx) [executable for OS/2 2.x or DOS (32-bit)]
@@ -6,9 +6,9 @@
# - for Microsoft C 6.00A [executable for OS/2 or DOS (16-bit)]
# - for Microsoft C 5.1 [executable for OS/2 or DOS (16-bit)]
-# Tested with ndmake and dmake-3.8 under DOS and dmake and
-# GNU make under OS/2. Compiling with dmake under DOS may require
-# the DOS-only version of dmake (so that swapping works).
+# Tested with GNU make and dmake-3.8 under OS/2 and DOS, and ndmake
+# under DOS. Compiling with dmake under DOS may require the DOS-only
+# version of dmake (so that swapping works).
default:
@echo "Enter $(MAK) target "
@@ -16,10 +16,11 @@ default:
@echo " djgpp ... DOS 32-bit exe [GNU C, Delorie, v1 or v2] "
@echo " emx ..... OS/2 32-bit exe [emx/gcc; uses emxlibc.dll] "
@echo " emxbnd .. OS/2 and DOS 32-bit exe [emx/gcc] "
- @echo " msc ..... DOS exe [Microsoft C 7] "
+ @echo " msc ..... DOS exe [Microsoft C 7 & 8 (AKA 1.52)] "
@echo " msc6 .... DOS exe [Microsoft C 6.00a] "
@echo " msc6os2 . OS/2 exe [Microsoft C 6.00a] "
@echo " msc6bnd . OS/2 and DOS exe [Microsoft C 6.00a] "
+ @echo " msvc32 .. DOS exe [Microsoft Visual C] "
@echo " ----------------------------------------------------- "
@echo " test .... Perform tests (see README_d/README.pc) "
@echo " install . Install gawk under $(prefix)/ "
@@ -35,7 +36,7 @@ RSPFILE = gawk.rsp
#
# If compiling under OS/2 or if make can pass long lines
#LDRSP = $(GAWKOBJS)
-#LINKRSP = $(LDRSP)
+#LNKRSP = $(LDRSP)
#
# else if make == dmake
# Response files for linker: dmake allows the macro expansion
@@ -43,17 +44,18 @@ RSPFILE = gawk.rsp
# The macro mktmp creates a temporary file for the linker.
# The 't' modifier is for tokenization.
#LDRSP = @$(mktmp $(<:t"\n"))
-#LINKRSP = @$(mktmp $(<:t"+\n") ) # Space before final paren req
+#LNKRSP = @$(mktmp $(<:t"+\n") ) # Space before final paren req
#
# else use brain-dead approach (emxbnd will need 'tr').
RSP = $(RSPFILE)
LDRSP = @$(RSP)
-LINKRSP = $(LDRSP)
+LNKRSP = $(LDRSP)
#------------------------------------------------------------------------
# Some makes do not define MAKE (and ndmake does not allow a define).
# Define MAK to be your make command.
-#MAK = $(MAKE) $(MAKEFILE)
-MAK = $(MAKE)
+#MAKE = dmake
+MAK = $(MAKE) $(MAKEFILE)
+#MAK = $(MAKE)
#MAKEFILE = -f Makefile
#MAK = make45 $(MAKEFILE)
#------------------------------------------------------------------------
@@ -82,13 +84,13 @@ BDJG = coff2exe gawk
djgpp:
$(MAK) all \
CC=gcc O=.o CF=-O \
- LINK=LDJG LF=-s LF2=-lm \
+ LNK=LDJG LF=-s LF2=-lm \
BIND=BDJG
djgpp-debug:
$(MAK) all \
CC=gcc O=.o CF=-g \
- LINK=LDJG LF2=-lm \
+ LNK=LDJG LF2=-lm \
BIND=BDJG
#========================================================================
@@ -101,25 +103,26 @@ LEMX = $(CC) $(LF) -o $@ $(GAWKOBJS) gawk.def -lbsd $(LF2)
# Link and bind for DOS and OS/2 versions.
# emx-09 needs '-p' emx option here or in EMXOPT environ var.
LEMXBND = $(CC) $(LF) -o a.out $(LDRSP) gawk.def -lbsd $(LF2)
-BEMX = emxbind -b /emx/bin/emxl.exe a.out $@ -p
-#BEMX = emxbind -b /emx/bin/emx.exe a.out $@ -p
+BEMX = emxbind -bs -o $@ a.out -p
+#BEMX = emxbind -bs /emx/bin/emx.exe a.out $@ -p
+BEMXD = emxbind -b -o $@ a.out -p
emx:
$(MAK) all \
"CC=gcc -Zomf" O=.obj "CF=-O -DOS2" \
- LINK=LEMX "LF=-s -Zcrtdll -Zstack 512" RSP=
+ LNK=LEMX "LF=-s -Zcrtdll -Zstack 512" RSP=
emxbnd:
$(MAK) all \
CC=gcc O=.o "CF=-O -DOS2 -DMSDOS" OBJ=popen.o \
- LINK=LEMXBND LF=-s \
+ LNK=LEMXBND \
BIND=BEMX "P=|tr \" \" \"\n\""
emxbnd-debug:
$(MAK) all \
CC=gcc O=.o CF="-g -DOS2 -DMSDOS" OBJ=popen.o \
- LINK=LEMXBND \
- BIND=BEMX "P=|tr \" \" \"\n\""
+ LNK=LEMXBND \
+ BIND=BEMXD "P=|tr \" \" \"\n\""
#========================================================================
#========================== MSC =========================================
@@ -143,7 +146,7 @@ MSCLIB = llibce
MSCCL = -FPi
#MSCCL = -FPc
-LMSC = link $(LF) $(LINKRSP) $(STDARGV)/NOE,$@,,/NOD:llibce $(MSCLIB)$(LF2)/STACK:0x6f00;
+LMSC = link $(LF) $(LNKRSP) $(STDARGV)/NOE,$@,,/NOD:llibce $(MSCLIB)$(LF2)/STACK:0x5900,nul
# CLMSC-linking works when building under OS/2
CLMSC = $(CC) -o $@ $(LF) $(GAWKOBJS) $(STDARGV) $(LF2) -link /NOE/NOI/STACK:0x6f00
@@ -164,30 +167,36 @@ msc:
$(MAK) all \
"CC=cl -nologo $(MSCCL)" O=.obj "CF=-AL -Ze -Ipc/include $(MSCOPT)" \
OBJ=popen.obj \
- LINK=LMSC P=+
+ LNK=LMSC P=+
msc-debug:
$(MAK) all \
"CC=cl $(MSCCL)" O=.obj "CF=-AL -Ze -Ipc/include -W2 -Zi -Od" \
OBJ=popen.obj \
- LINK=LMSC LF2=/CO P=+
+ LNK=LMSC LF2=/CO P=+
msc6:
+ $(MAK) builtin.obj \
+ "CC=cl -nologo $(MSCCL)" O=.obj "CF=-AL -Za $(MSCOPT) -Od"
$(MAK) all \
"CC=cl -nologo $(MSCCL)" O=.obj "CF=-AL -Za $(MSCOPT)" \
OBJ=popen.obj \
- LINK=LMSC P=+
+ LNK=LMSC P=+
msc6os2:
+ $(MAK) builtin.obj \
+ "CC=cl -nologo $(MSCCL)" O=.obj "CF=-AL -DOS2 -UMSDOS $(MSCOPT) -Od"
$(MAK) all \
"CC=cl $(MSCCL)" O=.obj "CF=-AL -DOS2 -UMSDOS $(MSCOPT)" \
- LINK=LMSC "LF2=p,gawk.def" P=+
+ LNK=LMSC "LF2=p,gawk.def" P=+
msc6bnd:
+ $(MAK) builtin.obj \
+ "CC=cl -nologo $(MSCCL)" O=.obj "CF=-AL -DOS2 $(MSCOPT) -Od"
$(MAK) all \
"CC=cl $(MSCCL)" O=.obj "CF=-AL -DOS2 $(MSCOPT)" \
OBJ=popen.obj \
- LINK=LMSC "LF2=p,gawk.def" P=+ \
+ LNK=LMSC "LF2=p,gawk.def" P=+ \
BIND=BMSC
# Support dropped in 3.0
@@ -195,13 +204,25 @@ msc6bnd:
# $(MAK) all \
# "CC=cl $(MSCCL)" O=.obj "CF=-AL -Za -D_MSC_VER=510 $(MSCOPT)" \
# OBJ=popen.obj \
-# LINK=LMSC P=+
+# LNK=LMSC P=+
#
#msc51bnd:
# $(MAK) all \
# "CC=cl -AL ($MSCCL)" O=.obj "CF=-DOS2 -D_MSC_VER=510 $(MSCOPT)" \
# OBJ=popen.obj \
-# LINK=CLMSC "LF=-Lp -Fb" "LF2=gawk.def"
+# LNK=CLMSC "LF=-Lp -Fb" "LF2=gawk.def"
+
+
+# The msvc32 target was supplied by a user, and is untested by the
+# OS/2 and DOS maintainers. Bug reports welcomed.
+
+LNKMSVC32="link -out:gawk.exe $(LNKRSP)"
+
+msvc32:
+ $(MAK) all \
+ "CC=cl -nologo" O=.obj "CF=-DMSDOS -D__STDC__=0" \
+ OBJ=popen.obj \
+ LNK=LNKMSVC32
#========================================================================
@@ -212,17 +233,17 @@ EMPTY=
CFLAGS = $(CF) -DGAWK -I. -DHAVE_CONFIG_H
# object files
-AWKOBJS1 = array$O builtin$O eval$O field$O gawkmisc$O io$O main$O
+AWKOBJS1 = array$O builtin$O eval$O field$O gawkmisc$O io$O main$O
AWKOBJS2 = missing$O msg$O node$O re$O version$O
AWKOBJS = $(AWKOBJS1) $(AWKOBJS2)
ALLOBJS = $(AWKOBJS) awktab$O getid$O $(OBJ)
-# GNUOBJS
-# GNU stuff that gawk uses as library routines.
-GNUOBJS= getopt$O getopt1$O regex$O dfa$O
+# LIBOBJS
+# GNU and other stuff that gawk uses as library routines.
+LIBOBJS= getopt$O getopt1$O regex$O dfa$O random$O
-GAWKOBJS = $(ALLOBJS) $(GNUOBJS)
+GAWKOBJS = $(ALLOBJS) $(LIBOBJS)
# clear out suffixes list
# .SUFFIXES:
@@ -234,14 +255,14 @@ GAWKOBJS = $(ALLOBJS) $(GNUOBJS)
# rules to build gawk
all : gawk.exe
-gawk.exe:: $(ALLOBJS) $(GNUOBJS) $(RSP)
- $($(LINK))
+gawk.exe:: $(GAWKOBJS) $(RSP)
+ $($(LNK))
$($(BIND))
$(RSPFILE) : $(GAWKOBJS)
echo $(AWKOBJS1)$P > $@
echo $(AWKOBJS2)$P >> $@
- echo awktab$O getid$O $(OBJ) $(GNUOBJS)$P >> $@
+ echo awktab$O getid$O $(OBJ) $(LIBOBJS)$P >> $@
$(ALLOBJS): awk.h dfa.h regex.h config.h
@@ -262,8 +283,6 @@ awktab.c: awk.y
alloca$O: alloca.c
-#.PRECIOUS: install
-#.PHONY: install
install: install$(install)
@@ -294,6 +313,11 @@ awklib/eg: doc/gawk.texi
sh -c "cd awklib && ../gawk -f extract.awk ../doc/gawk.texi"
check:
- cd test && $(MAK) -k AWK=../gawk.exe
+ @echo "Running the tests requires several unix-like utilities. The"
+ @echo "recommendation is to copy pc/Makefile.tst to test/Makefile. Under"
+ @echo "DOS, it may be necessary to run make from the test directory."
+# The `-k' option to make should be unnecessary if using pc/Makefile.tst.
+# sh -c "cd test && $(MAK) -k AWK=../gawk.exe"
+ sh -c "cd test && $(MAK) AWK=../gawk.exe bigtest extra"
test: check
diff --git a/pc/Makefile.tst b/pc/Makefile.tst
index 749d83ab..ebc171f3 100644
--- a/pc/Makefile.tst
+++ b/pc/Makefile.tst
@@ -1,6 +1,6 @@
# Makefile for GNU Awk test suite.
#
-# Copyright (C) 1988-1995 the Free Software Foundation, Inc.
+# Copyright (C) 1988-1996 the Free Software Foundation, Inc.
#
# This file is part of GAWK, the GNU implementation of the
# AWK Programming Language.
@@ -28,29 +28,38 @@
# to run this makefile:
#
# 1. The first thing that you will need to do is to convert all of the
-# files ending in ".ok" in the test directory and all of the files ending
-# in ".good" (or ".goo") in the test/reg directory from having a linefeed
-# to having carriage return/linefeed at the end of each line. There are
-# various public domain UNIX to DOS converters and any should work.
+# files ending in ".ok" in the test directory, all of the files ending
+# in ".good" (or ".goo") in the test/reg directory, and mmap8k.in from
+# having a linefeed to having carriage return/linefeed at the end of each
+# line. There are various public domain UNIX to DOS converters and any
+# should work. Alternatively, you can use diff instead of cmp--most
+# versions of diff don't care about how the lines end.
#
# 2. You will need an sh-compatible shell. Please refer to the "README.pc"
# file in the README_d directory for information about obtaining a copy.
# You will also need various UNIX utilities. At a minimum, you will
-# need: rm, tr, cmp, cat, wc, and sh.
+# need: rm, tr, cmp (or diff, see above), cat, wc, and sh.
# You should also have a UNIX-compatible date program.
#
# 3. You will need a \tmp directory on the same drive as the test directory
# for the poundba (called poundbang in the UNIX makefile) test.
#
-# The makefile has only been tested with dmake 3.8. After making all of these
-# changes, typing "dmake bigtest extra" should run successfully.
+# The makefile has only been tested with dmake 3.8 and DJGPP Make 3.74 or
+# later. After making all of these changes, typing "dmake bigtest extra"
+# or "make bigtest extra" (with DJGPP Make) should run successfully.
-# So far, the only MS-DOS & OS/2 shell that this has been found to work with
-# is Stewartson's sh 2.3. That version of sh will sometimes send long
+# So far, most of the testing has been with Stewartson's sh 2.3 under
+# MS-DOS & OS/2. That version of sh will sometimes send long
# command-line arguments to programs using the @ notation. You may need
# to disable this feature of sh for programs that you have which don't support
-# that feature. For more information about the @ notation please refer to
-# the sh documentation.
+# that feature. The DJGPP response file facility is incompatible with the
+# one used by Stewartson's sh, so you will certainly need to disable it if you
+# use DJGPP tools to run the tests. For more information about the @ notation
+# please refer to the sh documentation.
+#
+# A beta of the Bash shell (compiled with djgpp) was tested for gawk-3.0.1,
+# and worked very well with the djgpp-compiled gawk. See README.pc for
+# more information on OS/2 and DOS shells.
# You will almost certainly need to change some of the values (MACROS)
# defined on the next few lines.
@@ -59,49 +68,60 @@
.USESHELL = yes
# Using EMXSHELL=/bin/sh with emx versions can exhaust lower mem.
+# Lower mem can also be exhausted on some of the tests even with MSC gawk.
# The .SWAP setting forces (DOS-only) dmake to swap itself out.
-#.SWAP: childin fflush
+.SWAP: childin fflush getlnhd tweakfld
-# This won't work unless you have "sh" and set SHELL equal to it.
+# This won't work unless you have "sh" and set SHELL equal to it (Make 3.74
+# or later which comes with DJGPP will work with SHELL=/bin/sh if you have
+# sh.exe anywhere on your PATH).
#SHELL = e:\bin\sh.exe
SHELL = /bin/sh
# Point to gawk
AWK = ../gawk.exe
-# Set your cmp command here
-CMP = cmp
+# Set your cmp command here (you can use most versions of diff instead of cmp
+# if you don't want to convert the .ok files to the DOS CR/LF format).
+#CMP = cmp
+CMP = diff
+#CMP = diff -c
#CMP = gcmp
-# Set your "cp" command here. Note: It must take forward slashes.
-# 'command -c copy' will work for MS-DOS if "command=noexpand switch export" is
-# set in extend.lst.
-#CP = cp
-#CP = gcp
-CP = command -c copy
+# Set your "cp" and "mkdir" commands here. Note: cp must take forward
+# slashes. Using "command -c" may work for MS-DOS with Stewartson's shell
+# (but not bash) if "command=noexpand switch export" is set in extend.lst.
+# `true &&' is needed to force DJGPP Make to call the shell, or else the
+# conversion of `command -c' won't work.
+CP = cp
+#CP = true && command -c copy
+
+MKDIR = mkdir
+#MKDIR = true && command -c mkdir
# Set your unix-style date function here
#DATE = date
DATE = gdate
-# Set your mkdir command here.
-#MKDIR = /bin/mkdir
-MKDIR = command -c mkdir
-
# ============================================================================
# You shouldn't need to modify anything below this line.
# ============================================================================
srcdir = .
-bigtest: basic poundba gawk.extensions
+bigtest: basic unix-tests gawk.extensions
basic: msg swaplns messages argarray longwrds \
getline fstabplus compare arrayref rs fsrs rand \
fsbs negexp asgext anchgsub splitargv awkpath nfset reparse \
convfmt arrayparm paramdup nonl defref nofmtch litoct resplit \
rswhite prmarscl sclforin sclifin intprec childin noeffect \
- numsubstr pcntplus prmreuse math fflush fldchg
+ numsubstr pcntplus prmreuse math fldchg fldchgnf reindops \
+ sprintfc backgsub tweakfld clsflnam mmap8k fnarray \
+ dynlj substr eofsplit prt1eval gsubasgn prtoeval gsubtest splitwht \
+ back89 tradanch nlfldsep splitvar
+
+unix-tests: poundba fflush getlnhd
gawk.extensions: fieldwdth ignrcase posix manyfiles igncfs argtest \
badargs strftime gensub gnureops
@@ -176,7 +196,7 @@ regtes::
posix::
@echo 'posix test may fail due to 1.500000e+000 not being equal to'
- @echo '1.500000e+00 for MSC 7.0 gawk.'
+ @echo '1.500000e+00 for MSC gawk.'
@echo '1:2,3 4' | $(AWK) -f $(srcdir)/posix.awk >_$@
# $(CMP) $(srcdir)/posix.ok _$@ && rm -f _$@
-$(CMP) $(srcdir)/posix.ok _$@ && rm -f _$@
@@ -225,8 +245,8 @@ getline::
$(CMP) $(srcdir)/getline.ok _$@ && rm -f _$@
rand::
- @echo The following line should just be 19 random numbers between 1 and 100
- @$(AWK) -f $(srcdir)/rand.awk
+ @$(AWK) -f $(srcdir)/rand.awk >_$@
+ $(CMP) $(srcdir)/rand.ok _$@ && rm -f _$@
negexp::
@$(AWK) 'BEGIN { a = -2; print 10^a }' >_$@
@@ -275,11 +295,11 @@ convfmt::
$(CMP) $(srcdir)/convfmt.ok _$@ && rm -f _$@
arrayparm::
- @-AWKPATH=$(srcdir) $(AWK) -f arrayparm.awk >_$@ 2>&1
+ @-AWKPATH=$(srcdir) $(AWK) -f arrayparm.awk >_$@ 2>&1 || exit 0
$(CMP) $(srcdir)/arrayparm.ok _$@ && rm -f _$@
paramdup::
- @-AWKPATH=$(srcdir) $(AWK) -f paramdup.awk >_$@ 2>&1
+ @-AWKPATH=$(srcdir) $(AWK) -f paramdup.awk >_$@ 2>&1 || exit 0
$(CMP) $(srcdir)/paramdup.ok _$@ && rm -f _$@
nonl::
@@ -288,7 +308,7 @@ nonl::
$(CMP) $(srcdir)/nonl.ok _$@ && rm -f _$@
defref::
- @-AWKPATH=$(srcdir) $(AWK) --lint -f defref.awk >_$@ 2>&1
+ @-AWKPATH=$(srcdir) $(AWK) --lint -f defref.awk >_$@ 2>&1 || exit 0
$(CMP) $(srcdir)/defref.ok _$@ && rm -f _$@
nofmtch::
@@ -298,10 +318,11 @@ nofmtch::
strftime::
: this test could fail on slow machines or on a second boundary,
: so if it does, double check the actual results
-# @date | $(AWK) '{ $$3 = sprintf("%02d", $$3 + 0) ; print }' > strftime.ok
- @$(DATE) | $(AWK) '{ $$3 = sprintf("%02d", $$3 + 0) ; print }' > strftime.ok
- @$(AWK) 'BEGIN { print strftime() }' >_$@
- -$(CMP) strftime.ok _$@ && rm -f _$@ strftime.ok
+# @date | $(AWK) '{ $$3 = sprintf("%02d", $$3 + 0) ;
+ @$(DATE) | $(AWK) '{ $$3 = sprintf("%02d", $$3 + 0) ; \
+ print > "strftime.ok" ; \
+ print strftime() > "'_$@'" }'
+ $(CMP) strftime.ok _$@ && rm -f _$@ strftime.ok || exit 0
litoct::
@echo ab | $(AWK) --traditional -f $(srcdir)/litoct.awk >_$@
@@ -321,15 +342,15 @@ rswhite::
$(CMP) $(srcdir)/rswhite.ok _$@ && rm -f _$@
prmarscl::
- @-AWKPATH=$(srcdir) $(AWK) -f prmarscl.awk > _$@ 2>&1
+ @-AWKPATH=$(srcdir) $(AWK) -f prmarscl.awk > _$@ 2>&1 || exit 0
$(CMP) $(srcdir)/prmarscl.ok _$@ && rm -f _$@
sclforin::
- @-AWKPATH=$(srcdir) $(AWK) -f sclforin.awk > _$@ 2>&1
+ @-AWKPATH=$(srcdir) $(AWK) -f sclforin.awk > _$@ 2>&1 || exit 0
$(CMP) $(srcdir)/sclforin.ok _$@ && rm -f _$@
sclifin::
- @-AWKPATH=$(srcdir) $(AWK) -f sclifin.awk > _$@ 2>&1
+ @-AWKPATH=$(srcdir) $(AWK) -f sclifin.awk > _$@ 2>&1 || exit 0
$(CMP) $(srcdir)/sclifin.ok _$@ && rm -f _$@
intprec::
@@ -372,5 +393,105 @@ fldchg::
@$(AWK) -f $(srcdir)/fldchg.awk $(srcdir)/fldchg.in >_$@
$(CMP) $(srcdir)/fldchg.ok _$@ && rm -f _$@
+fldchgnf::
+ @$(AWK) -f $(srcdir)/fldchgnf.awk $(srcdir)/fldchgnf.in >_$@
+ $(CMP) $(srcdir)/fldchgnf.ok _$@ && rm -f _$@
+
+reindops::
+ @$(AWK) -f $(srcdir)/reindops.awk $(srcdir)/reindops.in >_$@
+ $(CMP) $(srcdir)/reindops.ok _$@ && rm -f _$@
+
+sprintfc::
+ @$(AWK) -f $(srcdir)/sprintfc.awk $(srcdir)/sprintfc.in >_$@
+ $(CMP) $(srcdir)/sprintfc.ok _$@ && rm -f _$@
+
+getlnhd::
+# We need to set COMSPEC to a UNIX-like shell for the here doc in getlnhd.awk
+# to work.
+# @$(AWK) -f $(srcdir)/getlnhd.awk >_$@
+ @echo 'Getlnhd is set to ignore errors. However, there should not be any.'
+ @echo 'If getlnhd fails, set sh to swap to disk only (in sh.rc).'
+ @echo 'If it still hangs with EMX gawk type ^C, then try the test when'
+ @echo 'not using DPMI and RSX (in particular, run outside MS-Windows).'
+ @echo 'If it fails with MSC, run make from the test directory.'
+ COMSPEC=$(SHELL) $(AWK) -f $(srcdir)/getlnhd.awk >_$@
+ -$(CMP) $(srcdir)/getlnhd.ok _$@ && rm -f _$@
+
+backgsub::
+ @$(AWK) -f $(srcdir)/backgsub.awk $(srcdir)/backgsub.in >_$@
+ $(CMP) $(srcdir)/backgsub.ok _$@ && rm -f _$@
+
+tweakfld::
+ @$(AWK) -f $(srcdir)/tweakfld.awk $(srcdir)/tweakfld.in >_$@
+ @rm -f errors.cleanup
+ $(CMP) $(srcdir)/tweakfld.ok _$@ && rm -f _$@
+
+clsflnam::
+ @$(AWK) -f $(srcdir)/clsflnam.awk $(srcdir)/clsflnam.in >_$@
+ $(CMP) $(srcdir)/clsflnam.ok _$@ && rm -f _$@
+
+mmap8k::
+ @echo 'If mmap8k fails make sure that mmap8k.in has CR/LFs.'
+ @$(AWK) '{ print }' $(srcdir)/mmap8k.in >_$@
+ $(CMP) $(srcdir)/mmap8k.in _$@ && rm -f _$@
+
+fnarray::
+ @-AWKPATH=$(srcdir) $(AWK) -f fnarray.awk >_$@ 2>&1 || exit 0
+ $(CMP) $(srcdir)/fnarray.ok _$@ && rm -f _$@
+
+dynlj::
+ @$(AWK) -f $(srcdir)/dynlj.awk >_$@
+ $(CMP) $(srcdir)/dynlj.ok _$@ && rm -f _$@
+
+substr::
+ @$(AWK) -f $(srcdir)/substr.awk >_$@
+ $(CMP) $(srcdir)/substr.ok _$@ && rm -f _$@
+
+eofsplit::
+ @$(AWK) -f $(srcdir)/eofsplit.awk >_$@
+ $(CMP) $(srcdir)/eofsplit.ok _$@ && rm -f _$@
+
+prt1eval::
+ @$(AWK) -f $(srcdir)/prt1eval.awk >_$@
+ $(CMP) $(srcdir)/prt1eval.ok _$@ && rm -f _$@
+
+gsubasgn::
+ @-AWKPATH=$(srcdir) $(AWK) -f gsubasgn.awk >_$@ 2>&1 || exit 0
+ $(CMP) $(srcdir)/gsubasgn.ok _$@ && rm -f _$@
+
+prtoeval::
+ @$(AWK) -f $(srcdir)/prtoeval.awk >_$@
+ $(CMP) $(srcdir)/prtoeval.ok _$@ && rm -f _$@
+
+gsubtest::
+ @$(AWK) -f $(srcdir)/gsubtest.awk >_$@
+ $(CMP) $(srcdir)/gsubtest.ok _$@ && rm -f _$@
+
+splitwht::
+ @$(AWK) -f $(srcdir)/splitwht.awk >_$@
+ $(CMP) $(srcdir)/splitwht.ok _$@ && rm -f _$@
+
+back89::
+ @$(AWK) '/a\8b/' $(srcdir)/back89.in >_$@
+ $(CMP) $(srcdir)/back89.ok _$@ && rm -f _$@
+
+tradanch::
+ @$(AWK) --traditional -f $(srcdir)/tradanch.awk $(srcdir)/tradanch.in >_$@
+ $(CMP) $(srcdir)/tradanch.ok _$@ && rm -f _$@
+
+nlfldsep::
+ AWK=$(AWK); export AWK; $(srcdir)/nlfldsep.sh > _$@
+ $(CMP) $(srcdir)/nlfldsep.ok _$@ && rm -f _$@
+
+splitvar::
+ @$(AWK) -f $(srcdir)/splitvar.awk $(srcdir)/splitvar.in >_$@
+ $(CMP) $(srcdir)/splitvar.ok _$@ && rm -f _$@
+
clean:
- rm -fr _* core junk
+ rm -fr _* core junk out1 out2 out3 strftime.ok *~
+
+distclean: clean
+ rm -f Makefile
+
+maintainer-clean: distclean
+
diff --git a/pc/config.h b/pc/config.h
index 00255c42..ff6ed616 100644
--- a/pc/config.h
+++ b/pc/config.h
@@ -129,7 +129,7 @@
#define SPRINTF_RET int /* return type of sprintf */
/* Define if you have the fmod function. */
-/* #undef HAVE_FMOD */
+#define HAVE_FMOD 1
/* Define if you have the memcmp function. */
#define HAVE_MEMCMP 1
diff --git a/pc/gawkmisc.pc b/pc/gawkmisc.pc
index 05db6c36..9912dcf3 100644
--- a/pc/gawkmisc.pc
+++ b/pc/gawkmisc.pc
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991 - 95 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991 - 96 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Progamming Language.
diff --git a/posix/gawkmisc.c b/posix/gawkmisc.c
index dce9e70a..2c5f09d3 100644
--- a/posix/gawkmisc.c
+++ b/posix/gawkmisc.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991 - 95 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991 - 96 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
diff --git a/protos.h b/protos.h
index 3429b21f..13b1f077 100644
--- a/protos.h
+++ b/protos.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1991 -95 the Free Software Foundation, Inc.
+ * Copyright (C) 1991 - 96 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
diff --git a/missing/random.c b/random.c
index 16e598ae..002b2265 100644
--- a/missing/random.c
+++ b/random.c
@@ -19,9 +19,8 @@
static char sccsid[] = "@(#)random.c 5.5 (Berkeley) 7/6/88";
#endif /* LIBC_SCCS and not lint */
-#if 0
#include <stdio.h>
-#endif
+#include "random.h" /* GAWK ADDITION */
/*
* random.c:
diff --git a/random.h b/random.h
new file mode 100644
index 00000000..7fd0ff9b
--- /dev/null
+++ b/random.h
@@ -0,0 +1,29 @@
+/*
+ * random.h - redefine name of random lib routines to avoid conflicts
+ */
+
+/*
+ * Copyright (C) 1996 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#define initstate gawk_initstate
+#define setstate gawk_setstate
+#define random gawk_random
+#define srandom gawk_srandom
diff --git a/re.c b/re.c
index 497f7214..995fbb99 100644
--- a/re.c
+++ b/re.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1991-1995 the Free Software Foundation, Inc.
+ * Copyright (C) 1991-1996 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -87,6 +87,11 @@ int dfa;
*dest++ = '\\';
*dest++ = (char) c2;
break;
+ case '8':
+ case '9': /* a\9b not valid */
+ *dest++ = c;
+ src++;
+ break;
case 'y': /* normally \b */
/* gnu regex op */
if (! do_traditional) {
@@ -267,7 +272,7 @@ resetup()
dfasyntax(syn, FALSE);
}
-/* avoid_dfa --- temporary kludge function until we have a new dfa.c */
+/* avoid_dfa --- FIXME: temporary kludge function until we have a new dfa.c */
int
avoid_dfa(re, str, len)
diff --git a/regex.c b/regex.c
index 5d1e16fb..d378c036 100644
--- a/regex.c
+++ b/regex.c
@@ -3,7 +3,7 @@
(Implements POSIX draft P10003.2/D11.2, except for
internationalization features.)
- Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,7 +17,8 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA. */
/* AIX requires this to be the first thing in the file. */
#if defined (_AIX) && !defined (REGEX_MALLOC)
@@ -937,6 +938,12 @@ re_set_syntax (syntax)
reg_syntax_t ret = re_syntax_options;
re_syntax_options = syntax;
+#ifdef DEBUG
+ if (syntax & RE_DEBUG)
+ debug = 1;
+ else if (debug) /* was on but now is not */
+ debug = 0;
+#endif /* DEBUG */
return ret;
}
@@ -1017,7 +1024,7 @@ static const char *re_error_msgid[] =
#endif
/* Roughly the maximum number of failure points on the stack. Would be
- exactly that if always used MAX_FAILURE_SPACE each time we failed.
+ exactly that if always used MAX_FAILURE_ITEMS items each time we failed.
This is a variable only so users of regex can assign to it; we never
change it ourselves. */
@@ -1047,6 +1054,8 @@ typedef struct
#else /* not INT_IS_16BIT */
#if defined (MATCH_MAY_ALLOCATE)
+/* 4400 was enough to cause a crash on Alpha OSF/1,
+ whose default stack limit is 2mb. */
int re_max_failures = 20000;
#else
int re_max_failures = 2000;
@@ -1265,7 +1274,10 @@ typedef struct
#endif
/* We push at most this many items on the stack. */
-#define MAX_FAILURE_ITEMS ((num_regs - 1) * NUM_REG_ITEMS + NUM_NONREG_ITEMS)
+/* We used to use (num_regs - 1), which is the number of registers
+ this regexp will save; but that was changed to 5
+ to avoid stack overflow for a regexp with lots of parens. */
+#define MAX_FAILURE_ITEMS (5 * NUM_REG_ITEMS + NUM_NONREG_ITEMS)
/* We actually push this many items. */
#define NUM_FAILURE_ITEMS \
@@ -3537,12 +3549,14 @@ re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop)
: (d) == string2 - 1 ? *(end1 - 1) : *(d)) \
== Sword)
+/* Disabled due to a compiler bug -- see comment at case wordbound */
+#if 0
/* Test if the character before D and the one at D differ with respect
to being word-constituent. */
#define AT_WORD_BOUNDARY(d) \
(AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \
|| WORDCHAR_P (d - 1) != WORDCHAR_P (d))
-
+#endif
/* Free everything we malloc. */
#ifdef MATCH_MAY_ALLOCATE
@@ -4613,9 +4627,9 @@ re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop)
#endif
if ((re_opcode_t) p1[3] == exactn
- && ! ((int) p2[1] * BYTEWIDTH > (int) p1[4]
- && (p2[1 + p1[4] / BYTEWIDTH]
- & (1 << (p1[4] % BYTEWIDTH)))))
+ && ! ((int) p2[1] * BYTEWIDTH > (int) p1[5]
+ && (p2[2 + p1[5] / BYTEWIDTH]
+ & (1 << (p1[5] % BYTEWIDTH)))))
{
p[-3] = (unsigned char) pop_failure_jump;
DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n",
@@ -4787,17 +4801,54 @@ re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop)
break;
}
- case wordbound:
- DEBUG_PRINT1 ("EXECUTING wordbound.\n");
- if (AT_WORD_BOUNDARY (d))
+#if 0
+ /* The DEC Alpha C compiler 3.x generates incorrect code for the
+ test WORDCHAR_P (d - 1) != WORDCHAR_P (d) in the expansion of
+ AT_WORD_BOUNDARY, so this code is disabled. Expanding the
+ macro and introducing temporary variables works around the bug. */
+
+ case wordbound:
+ DEBUG_PRINT1 ("EXECUTING wordbound.\n");
+ if (AT_WORD_BOUNDARY (d))
break;
- goto fail;
+ goto fail;
case notwordbound:
- DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
+ DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
if (AT_WORD_BOUNDARY (d))
goto fail;
- break;
+ break;
+#else
+ case wordbound:
+ {
+ boolean prevchar, thischar;
+
+ DEBUG_PRINT1 ("EXECUTING wordbound.\n");
+ if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d))
+ break;
+
+ prevchar = WORDCHAR_P (d - 1);
+ thischar = WORDCHAR_P (d);
+ if (prevchar != thischar)
+ break;
+ goto fail;
+ }
+
+ case notwordbound:
+ {
+ boolean prevchar, thischar;
+
+ DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
+ if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d))
+ goto fail;
+
+ prevchar = WORDCHAR_P (d - 1);
+ thischar = WORDCHAR_P (d);
+ if (prevchar != thischar)
+ goto fail;
+ break;
+ }
+#endif
case wordbeg:
DEBUG_PRINT1 ("EXECUTING wordbeg.\n");
@@ -5252,12 +5303,18 @@ re_compile_pattern (pattern, length, bufp)
/* Entry points compatible with 4.2 BSD regex library. We don't define
them unless specifically requested. */
-#ifdef _REGEX_RE_COMP
+#if defined (_REGEX_RE_COMP) || defined (_LIBC)
/* BSD has one and only one pattern buffer. */
static struct re_pattern_buffer re_comp_buf;
char *
+#ifdef _LIBC
+/* Make these definitions weak in libc, so POSIX programs can redefine
+ these names if they don't use our functions, and still use
+ regcomp/regexec below without link errors. */
+weak_function
+#endif
re_comp (s)
const char *s;
{
@@ -5299,6 +5356,9 @@ re_comp (s)
int
+#ifdef _LIBC
+weak_function
+#endif
re_exec (s)
const char *s;
{
@@ -5550,11 +5610,3 @@ regfree (preg)
}
#endif /* not emacs */
-
-/*
-Local variables:
-make-backup-files: t
-version-control: t
-trim-versions-without-asking: nil
-End:
-*/
diff --git a/regex.h b/regex.h
index 21cd9902..666c7b3a 100644
--- a/regex.h
+++ b/regex.h
@@ -1,7 +1,7 @@
/* Definitions for data structures and routines for the regular
expression library, version 0.12.
- Copyright (C) 1985, 89, 90, 91, 92, 93, 95 Free Software Foundation, Inc.
+ Copyright (C) 1985, 89, 90, 91, 92, 93, 95, 96 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -12,10 +12,11 @@
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA. */
#ifndef __REGEXP_LIBRARY_H__
#define __REGEXP_LIBRARY_H__
@@ -145,6 +146,14 @@ typedef unsigned long reg_syntax_t;
without further backtracking. */
#define RE_NO_POSIX_BACKTRACKING (RE_NO_GNU_OPS << 1)
+/* If this bit is set, turn on internal regex debugging.
+ If not set, and debugging was on, turn it off.
+ This only works if regex.c is compiled -DDEBUG.
+ We define this bit always, so that all that's needed to turn on
+ debugging is to recompile regex.c; the calling code can always have
+ this bit set, and it won't affect anything in the normal case. */
+#define RE_DEBUG (RE_NO_POSIX_BACKTRACKING << 1)
+
/* This global variable defines the particular regexp syntax to use (for
some interfaces). When a regexp is compiled, the syntax used is
stored in the pattern buffer, so changing this does not affect
@@ -160,16 +169,17 @@ extern reg_syntax_t re_syntax_options;
#define RE_SYNTAX_AWK \
(RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \
| RE_NO_BK_PARENS | RE_NO_BK_REFS \
- | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \
- | RE_DOT_NEWLINE \
+ | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \
+ | RE_DOT_NEWLINE | RE_CONTEXT_INDEP_ANCHORS \
| RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS)
#define RE_SYNTAX_GNU_AWK \
- ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS) \
- & ~(RE_DOT_NOT_NULL|RE_INTERVALS))
+ ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG) \
+ & ~(RE_DOT_NOT_NULL|RE_INTERVALS|RE_CONTEXT_INDEP_OPS))
#define RE_SYNTAX_POSIX_AWK \
- (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS| RE_NO_GNU_OPS)
+ (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \
+ | RE_INTERVALS | RE_NO_GNU_OPS)
#define RE_SYNTAX_GREP \
(RE_BK_PLUS_QM | RE_CHAR_CLASSES \
diff --git a/stamp-h.in b/stamp-h.in
index eaec84aa..6d7105ef 100644
--- a/stamp-h.in
+++ b/stamp-h.in
@@ -1 +1 @@
-Wed Dec 20 16:39:26 EST 1995
+Tue Dec 10 22:48:08 EST 1996
diff --git a/test/ChangeLog b/test/ChangeLog
index 570c031b..53a1b541 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,140 @@
+Thu Nov 7 09:12:20 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (splitvar): new test case.
+ * splitvar.awk, splitvar.in, splitvar.ok: new files.
+
+Sun Nov 3 10:55:50 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (nlfldsep): new test case.
+ * nlfldsep.sh, nlfldsep.ok: new files.
+
+Fri Oct 25 10:29:56 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * rand.awk: call srand with fixed seed.
+ * rand.ok: new file.
+ * Makefile.in (rand): changed to compare output with rand.ok.
+
+Sat Oct 19 21:52:04 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (tradanch): new test case.
+ * tradanch.awk, tradanch.in, tradanch.ok: new files.
+
+Thu Oct 17 21:22:05 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * tweakfld.awk: move `rm' out into Makefile.in.
+ * eofsplit.awk: fixed buggy code so won't loop forever.
+ * Makefile.in (all): add unix-tests.
+ (unix-tests): new target, has pound-bang, fflush, getlnhd.
+ (basic): removed fflush, getlnhd.
+ (tweakfld): added rm from tweakfld.awk.
+
+Sun Oct 6 22:00:35 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (back89): new test case.
+ * back89.in, back89.ok: new files.
+
+Sun Oct 6 20:45:54 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (splitwht): new test case.
+ * splitwht.awk, splitwht.ok: new files.
+
+Sun Sep 29 23:14:20 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (gsubtest): new test case.
+ * gsubtest.awk, gsubtest.ok: new files.
+
+Fri Sep 20 11:58:40 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (prtoeval): new test case.
+ * prtoeval.awk, prtoeval.ok: new files.
+
+Tue Sep 10 06:26:44 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (gsubasgn): new test case.
+ * gsubasgn.awk, gsubasgn.ok: new files.
+
+Wed Aug 28 22:06:33 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * badargs.ok: updated output corresponding to change made to
+ main.c (see main ChangeLog).
+
+Thu Aug 1 07:20:28 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (clean): remove out[123] files from `messages' test.
+ Thanks to Pat Rankin (rankin@eql.caltech.edu).
+
+Sat Jul 27 23:56:57 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (prt1eval): new test case.
+ * prt1eval.awk, prt1eval.ok: new files.
+
+Mon Jul 22 22:06:10 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (eofsplit): new test case.
+ * eofsplit.awk, eofsplit.ok: new files.
+
+Sun Jul 14 07:07:45 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (fldchgnf): new test case.
+ * fldchgnf.awk, fldchgnf.ok: new files.
+
+Tue May 21 23:23:22 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (substr): new test case.
+ * substr.awk, substr.ok: new files.
+
+Tue May 14 15:05:23 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (dynlj): new test case.
+ * dynlj.awk, dynlj.ok: new files.
+
+Sun May 12 20:45:34 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (fnarray): new test case.
+ * fnarray.awk, fnarray.ok: new files.
+
+Fri Mar 15 06:46:48 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (clean): added `*~' to list of files to be removed.
+ * tweakfld.awk (END): added to do clean up action.
+
+Thu Mar 14 16:41:32 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (mmap8k): new test case.
+ * mmap8k.in, mmap8k.ok: new files.
+
+Sun Mar 10 22:58:35 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (clsflnam): new test case.
+ * clsflnam.in, clsflnam.awk, clsflnam.ok: new files.
+ * tweakfld.awk: changed to have a fixed date.
+
+Thu Mar 7 09:56:09 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (tweakfld): new test case.
+ * tweakfld.in, tweakfld.awk, tweakfld.ok: new files.
+
+Sun Mar 3 06:51:26 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (getlnhd, backgsub) : new test cases.
+ * getlnhd.awk, getlnhd.ok: new files.
+ * backgsub.in, backgsub.awk, backgsub.ok: new files.
+
+Mon Feb 26 22:30:02 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (sprintfc): new test case.
+ * sprintfc.in, sprintfc.awk, sprintfc.ok: new files.
+ * gensub.awk: updated for case of no match of regex.
+
+Wed Jan 24 10:06:16 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
+
+ * Makefile.in (distclean, maintainer-clean): new targets.
+ (reindops): added test from Rick Adams (rick@uunet.uu.net).
+ (arrayparm, paramdup, defref, strftime, prmarscl, sclforin,
+ sclifin): Fix from Larry Schwimmer (schwim@cyclone.stanford.edu)
+ so that tests that are supposed to fail use `... || exit 0' to
+ cause a clean `make clean'.
+
Wed Jan 10 22:58:55 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
* ChangeLog created.
diff --git a/test/Makefile b/test/Makefile
deleted file mode 100644
index 1ec91c45..00000000
--- a/test/Makefile
+++ /dev/null
@@ -1,279 +0,0 @@
-# Generated automatically from Makefile.in by configure.
-# Makefile for GNU Awk test suite.
-#
-# Copyright (C) 1988-1995 the Free Software Foundation, Inc.
-#
-# This file is part of GAWK, the GNU implementation of the
-# AWK Programming Language.
-#
-# GAWK is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# GAWK is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-SHELL = /bin/sh
-AWK = ../gawk
-CMP = cmp
-
-srcdir = .
-
-bigtest: basic poundbang gawk.extensions
-
-basic: msg swaplns messages argarray longwrds \
- getline fstabplus compare arrayref rs fsrs rand \
- fsbs negexp asgext anchgsub splitargv awkpath nfset reparse \
- convfmt arrayparm paramdup nonl defref nofmtch litoct resplit \
- rswhite prmarscl sclforin sclifin intprec childin noeffect \
- numsubstr pcntplus prmreuse math fflush fldchg
-
-gawk.extensions: fieldwdth ignrcase posix manyfiles igncfs argtest \
- badargs strftime gensub gnureops
-
-extra: regtest inftest
-
-poundbang::
- cp $(AWK) /tmp/gawk && $(srcdir)/poundbang $(srcdir)/poundbang >_`basename $@`
- rm -f /tmp/gawk
- $(CMP) $(srcdir)/poundbang.ok _`basename $@` && rm -f _`basename $@`
-
-msg::
- @echo 'Any output from "cmp" is bad news, although some differences'
- @echo 'in floating point values are probably benign -- in particular,'
- @echo 'some systems may omit a leading zero and the floating point'
- @echo 'precision may lead to slightly different output in a few cases.'
-
-swaplns::
- @$(AWK) -f $(srcdir)/swaplns.awk $(srcdir)/swaplns.in >_$@
- $(CMP) $(srcdir)/swaplns.ok _$@ && rm -f _$@
-
-messages::
- @$(AWK) -f $(srcdir)/messages.awk >out2 2>out3
- { $(CMP) $(srcdir)/out1.ok out1 && $(CMP) $(srcdir)/out2.ok out2 && $(CMP) $(srcdir)/out3.ok out3 && rm -f out1 out2 out3; } || { test -d /dev/fd && echo IT IS OK THAT THIS TEST FAILED; }
-
-argarray::
- @case $(srcdir) in \
- .) : ;; \
- *) cp $(srcdir)/argarray.in . ;; \
- esac
- @TEST=test echo just a test | $(AWK) -f $(srcdir)/argarray.awk ./argarray.in - >_$@
- $(CMP) $(srcdir)/argarray.ok _$@ && rm -f _$@
-
-fstabplus::
- @echo '1 2' | $(AWK) -f $(srcdir)/fstabplus.awk >_$@
- $(CMP) $(srcdir)/fstabplus.ok _$@ && rm -f _$@
-
-fsrs::
- @$(AWK) -f $(srcdir)/fsrs.awk $(srcdir)/fsrs.in >_$@
- $(CMP) $(srcdir)/fsrs.ok _$@ && rm -f _$@
-
-igncfs::
- @$(AWK) -f $(srcdir)/igncfs.awk $(srcdir)/igncfs.in >_$@
- $(CMP) $(srcdir)/igncfs.ok _$@ && rm -f _$@
-
-longwrds::
- @$(AWK) -f $(srcdir)/longwrds.awk $(srcdir)/manpage | sort >_$@
- $(CMP) $(srcdir)/longwrds.ok _$@ && rm -f _$@
-
-fieldwdth::
- @echo '123456789' | $(AWK) -v FIELDWIDTHS="2 3 4" '{ print $$2}' >_$@
- $(CMP) $(srcdir)/fieldwdth.ok _$@ && rm -f _$@
-
-ignrcase::
- @echo xYz | $(AWK) -v IGNORECASE=1 '{ sub(/y/, ""); print}' >_$@
- $(CMP) $(srcdir)/ignrcase.ok _$@ && rm -f _$@
-
-regtest::
- @echo 'Some of the output from regtest is very system specific, do not'
- @echo 'be distressed if your output differs from that distributed.'
- @echo 'Manual inspection is called for.'
- AWK=`pwd`/$(AWK) $(srcdir)/regtest
-
-posix::
- @echo '1:2,3 4' | $(AWK) -f $(srcdir)/posix.awk >_$@
- $(CMP) $(srcdir)/posix.ok _$@ && rm -f _$@
-
-manyfiles::
- @rm -rf junk
- @mkdir junk
- @$(AWK) 'BEGIN { for (i = 1; i <= 300; i++) print i, i}' >_$@
- @$(AWK) -f $(srcdir)/manyfiles.awk _$@ _$@
- @echo "This number better be 1 ->" | tr -d '\012'
- @wc -l junk/* | $(AWK) '$$1 != 2' | wc -l
- @rm -rf junk _$@
-
-compare::
- @$(AWK) -f $(srcdir)/compare.awk 0 1 $(srcdir)/compare.in >_$@
- $(CMP) $(srcdir)/compare.ok _$@ && rm -f _$@
-
-arrayref::
- @$(AWK) -f $(srcdir)/arrayref.awk >_$@
- $(CMP) $(srcdir)/arrayref.ok _$@ && rm -f _$@
-
-rs::
- @$(AWK) -v RS="" '{ print $$1, $$2}' $(srcdir)/rs.in >_$@
- $(CMP) $(srcdir)/rs.ok _$@ && rm -f _$@
-
-fsbs::
- @$(AWK) -v FS='\' '{ print $$1, $$2 }' $(srcdir)/fsbs.in >_$@
- $(CMP) $(srcdir)/fsbs.ok _$@ && rm -f _$@
-
-inftest::
- @echo This test is very machine specific...
- @$(AWK) -f $(srcdir)/inftest.awk >_$@
- $(CMP) $(srcdir)/inftest.ok _$@ && rm -f _$@
-
-getline::
- @$(AWK) -f $(srcdir)/getline.awk $(srcdir)/getline.awk $(srcdir)/getline.awk >_$@
- $(CMP) $(srcdir)/getline.ok _$@ && rm -f _$@
-
-rand::
- @echo The following line should just be 19 random numbers between 1 and 100
- @$(AWK) -f $(srcdir)/rand.awk
-
-negexp::
- @$(AWK) 'BEGIN { a = -2; print 10^a }' >_$@
- $(CMP) $(srcdir)/negexp.ok _$@ && rm -f _$@
-
-asgext::
- @$(AWK) -f $(srcdir)/asgext.awk $(srcdir)/asgext.in >_$@
- $(CMP) $(srcdir)/asgext.ok _$@ && rm -f _$@
-
-anchgsub::
- @$(AWK) -f $(srcdir)/anchgsub.awk $(srcdir)/anchgsub.in >_$@
- $(CMP) $(srcdir)/anchgsub.ok _$@ && rm -f _$@
-
-splitargv::
- @$(AWK) -f $(srcdir)/splitargv.awk $(srcdir)/splitargv.in >_$@
- $(CMP) $(srcdir)/splitargv.ok _$@ && rm -f _$@
-
-awkpath::
- @AWKPATH="$(srcdir):$(srcdir)/lib" $(AWK) -f awkpath.awk >_$@
- $(CMP) $(srcdir)/awkpath.ok _$@ && rm -f _$@
-
-nfset::
- @$(AWK) -f $(srcdir)/nfset.awk $(srcdir)/nfset.in >_$@
- $(CMP) $(srcdir)/nfset.ok _$@ && rm -f _$@
-
-reparse::
- @$(AWK) -f $(srcdir)/reparse.awk $(srcdir)/reparse.in >_$@
- $(CMP) $(srcdir)/reparse.ok _$@ && rm -f _$@
-
-argtest::
- @$(AWK) -f $(srcdir)/argtest.awk -x -y abc >_$@
- $(CMP) $(srcdir)/argtest.ok _$@ && rm -f _$@
-
-badargs::
- @-$(AWK) -f 2>&1 | grep -v patchlevel >_$@
- $(CMP) $(srcdir)/badargs.ok _$@ && rm -f _$@
-
-convfmt::
- @$(AWK) -f $(srcdir)/convfmt.awk >_$@
- $(CMP) $(srcdir)/convfmt.ok _$@ && rm -f _$@
-
-arrayparm::
- @-AWKPATH=$(srcdir) $(AWK) -f arrayparm.awk >_$@ 2>&1
- $(CMP) $(srcdir)/arrayparm.ok _$@ && rm -f _$@
-
-paramdup::
- @-AWKPATH=$(srcdir) $(AWK) -f paramdup.awk >_$@ 2>&1
- $(CMP) $(srcdir)/paramdup.ok _$@ && rm -f _$@
-
-nonl::
- @-AWKPATH=$(srcdir) $(AWK) --lint -f nonl.awk /dev/null >_$@ 2>&1
- $(CMP) $(srcdir)/nonl.ok _$@ && rm -f _$@
-
-defref::
- @-AWKPATH=$(srcdir) $(AWK) --lint -f defref.awk >_$@ 2>&1
- $(CMP) $(srcdir)/defref.ok _$@ && rm -f _$@
-
-nofmtch::
- @-AWKPATH=$(srcdir) $(AWK) --lint -f nofmtch.awk >_$@ 2>&1
- $(CMP) $(srcdir)/nofmtch.ok _$@ && rm -f _$@
-
-strftime::
- : this test could fail on slow machines or on a second boundary,
- : so if it does, double check the actual results
- @date | $(AWK) '{ $$3 = sprintf("%02d", $$3 + 0) ; \
- print > "strftime.ok" ; \
- print strftime() > "'_$@'" }'
- -$(CMP) strftime.ok _$@ && rm -f _$@ strftime.ok
-
-litoct::
- @echo ab | $(AWK) --traditional -f $(srcdir)/litoct.awk >_$@
- $(CMP) $(srcdir)/litoct.ok _$@ && rm -f _$@
-
-gensub::
- @$(AWK) -f $(srcdir)/gensub.awk $(srcdir)/gensub.in >_$@
- $(CMP) $(srcdir)/gensub.ok _$@ && rm -f _$@
-
-resplit::
- @echo a:b:c d:e:f | $(AWK) '{ FS = ":"; $$0 = $$0; print $$2 }' > _$@
- $(CMP) $(srcdir)/resplit.ok _$@ && rm -f _$@
-
-rswhite::
- @$(AWK) -f $(srcdir)/rswhite.awk $(srcdir)/rswhite.in > _$@
- $(CMP) $(srcdir)/rswhite.ok _$@ && rm -f _$@
-
-prmarscl::
- @-AWKPATH=$(srcdir) $(AWK) -f prmarscl.awk > _$@ 2>&1
- $(CMP) $(srcdir)/prmarscl.ok _$@ && rm -f _$@
-
-sclforin::
- @-AWKPATH=$(srcdir) $(AWK) -f sclforin.awk > _$@ 2>&1
- $(CMP) $(srcdir)/sclforin.ok _$@ && rm -f _$@
-
-sclifin::
- @-AWKPATH=$(srcdir) $(AWK) -f sclifin.awk > _$@ 2>&1
- $(CMP) $(srcdir)/sclifin.ok _$@ && rm -f _$@
-
-intprec::
- @-$(AWK) -f $(srcdir)/intprec.awk > _$@ 2>&1
- $(CMP) $(srcdir)/intprec.ok _$@ && rm -f _$@
-
-childin::
- @echo hi | $(AWK) 'BEGIN { "cat" | getline; print; close("cat") }' > _$@
- $(CMP) $(srcdir)/childin.ok _$@ && rm -f _$@
-
-noeffect::
- @-AWKPATH=$(srcdir) $(AWK) --lint -f noeffect.awk > _$@ 2>&1
- $(CMP) $(srcdir)/noeffect.ok _$@ && rm -f _$@
-
-numsubstr::
- @-AWKPATH=$(srcdir) $(AWK) -f numsubstr.awk $(srcdir)/numsubstr.in >_$@
- $(CMP) $(srcdir)/numsubstr.ok _$@ && rm -f _$@
-
-gnureops::
- @$(AWK) -f $(srcdir)/gnureops.awk >_$@
- $(CMP) $(srcdir)/gnureops.ok _$@ && rm -f _$@
-
-pcntplus::
- @$(AWK) -f $(srcdir)/pcntplus.awk >_$@
- $(CMP) $(srcdir)/pcntplus.ok _$@ && rm -f _$@
-
-prmreuse::
- @$(AWK) -f $(srcdir)/prmreuse.awk >_$@
- $(CMP) $(srcdir)/prmreuse.ok _$@ && rm -f _$@
-
-math::
- @$(AWK) -f $(srcdir)/math.awk >_$@
- $(CMP) $(srcdir)/math.ok _$@ && rm -f _$@
-
-fflush::
- @$(srcdir)/fflush.sh >_$@
- $(CMP) $(srcdir)/fflush.ok _$@ && rm -f _$@
-
-fldchg::
- @$(AWK) -f $(srcdir)/fldchg.awk $(srcdir)/fldchg.in >_$@
- $(CMP) $(srcdir)/fldchg.ok _$@ && rm -f _$@
-
-clean:
- rm -fr _* core junk
diff --git a/test/Makefile.in b/test/Makefile.in
index 52036d75..c8299e51 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -1,6 +1,6 @@
# Makefile for GNU Awk test suite.
#
-# Copyright (C) 1988-1995 the Free Software Foundation, Inc.
+# Copyright (C) 1988-1996 the Free Software Foundation, Inc.
#
# This file is part of GAWK, the GNU implementation of the
# AWK Programming Language.
@@ -26,14 +26,19 @@ CMP = cmp
srcdir = @srcdir@
VPATH = @srcdir@
-bigtest: basic poundbang gawk.extensions
+bigtest: basic unix-tests gawk.extensions
basic: msg swaplns messages argarray longwrds \
getline fstabplus compare arrayref rs fsrs rand \
fsbs negexp asgext anchgsub splitargv awkpath nfset reparse \
convfmt arrayparm paramdup nonl defref nofmtch litoct resplit \
rswhite prmarscl sclforin sclifin intprec childin noeffect \
- numsubstr pcntplus prmreuse math fflush fldchg
+ numsubstr pcntplus prmreuse math fldchg fldchgnf reindops \
+ sprintfc backgsub tweakfld clsflnam mmap8k fnarray \
+ dynlj substr eofsplit prt1eval gsubasgn prtoeval gsubtest splitwht \
+ back89 tradanch nlfldsep splitvar
+
+unix-tests: poundbang fflush getlnhd
gawk.extensions: fieldwdth ignrcase posix manyfiles igncfs argtest \
badargs strftime gensub gnureops
@@ -136,8 +141,8 @@ getline::
$(CMP) $(srcdir)/getline.ok _$@ && rm -f _$@
rand::
- @echo The following line should just be 19 random numbers between 1 and 100
- @$(AWK) -f $(srcdir)/rand.awk
+ @$(AWK) -f $(srcdir)/rand.awk >_$@
+ $(CMP) $(srcdir)/rand.ok _$@ && rm -f _$@
negexp::
@$(AWK) 'BEGIN { a = -2; print 10^a }' >_$@
@@ -180,11 +185,11 @@ convfmt::
$(CMP) $(srcdir)/convfmt.ok _$@ && rm -f _$@
arrayparm::
- @-AWKPATH=$(srcdir) $(AWK) -f arrayparm.awk >_$@ 2>&1
+ @-AWKPATH=$(srcdir) $(AWK) -f arrayparm.awk >_$@ 2>&1 || exit 0
$(CMP) $(srcdir)/arrayparm.ok _$@ && rm -f _$@
paramdup::
- @-AWKPATH=$(srcdir) $(AWK) -f paramdup.awk >_$@ 2>&1
+ @-AWKPATH=$(srcdir) $(AWK) -f paramdup.awk >_$@ 2>&1 || exit 0
$(CMP) $(srcdir)/paramdup.ok _$@ && rm -f _$@
nonl::
@@ -192,7 +197,7 @@ nonl::
$(CMP) $(srcdir)/nonl.ok _$@ && rm -f _$@
defref::
- @-AWKPATH=$(srcdir) $(AWK) --lint -f defref.awk >_$@ 2>&1
+ @-AWKPATH=$(srcdir) $(AWK) --lint -f defref.awk >_$@ 2>&1 || exit 0
$(CMP) $(srcdir)/defref.ok _$@ && rm -f _$@
nofmtch::
@@ -205,7 +210,7 @@ strftime::
@date | $(AWK) '{ $$3 = sprintf("%02d", $$3 + 0) ; \
print > "strftime.ok" ; \
print strftime() > "'_$@'" }'
- -$(CMP) strftime.ok _$@ && rm -f _$@ strftime.ok
+ $(CMP) strftime.ok _$@ && rm -f _$@ strftime.ok || exit 0
litoct::
@echo ab | $(AWK) --traditional -f $(srcdir)/litoct.awk >_$@
@@ -224,15 +229,15 @@ rswhite::
$(CMP) $(srcdir)/rswhite.ok _$@ && rm -f _$@
prmarscl::
- @-AWKPATH=$(srcdir) $(AWK) -f prmarscl.awk > _$@ 2>&1
+ @-AWKPATH=$(srcdir) $(AWK) -f prmarscl.awk > _$@ 2>&1 || exit 0
$(CMP) $(srcdir)/prmarscl.ok _$@ && rm -f _$@
sclforin::
- @-AWKPATH=$(srcdir) $(AWK) -f sclforin.awk > _$@ 2>&1
+ @-AWKPATH=$(srcdir) $(AWK) -f sclforin.awk > _$@ 2>&1 || exit 0
$(CMP) $(srcdir)/sclforin.ok _$@ && rm -f _$@
sclifin::
- @-AWKPATH=$(srcdir) $(AWK) -f sclifin.awk > _$@ 2>&1
+ @-AWKPATH=$(srcdir) $(AWK) -f sclifin.awk > _$@ 2>&1 || exit 0
$(CMP) $(srcdir)/sclifin.ok _$@ && rm -f _$@
intprec::
@@ -275,5 +280,95 @@ fldchg::
@$(AWK) -f $(srcdir)/fldchg.awk $(srcdir)/fldchg.in >_$@
$(CMP) $(srcdir)/fldchg.ok _$@ && rm -f _$@
+fldchgnf::
+ @$(AWK) -f $(srcdir)/fldchgnf.awk $(srcdir)/fldchgnf.in >_$@
+ $(CMP) $(srcdir)/fldchgnf.ok _$@ && rm -f _$@
+
+reindops::
+ @$(AWK) -f $(srcdir)/reindops.awk $(srcdir)/reindops.in >_$@
+ $(CMP) $(srcdir)/reindops.ok _$@ && rm -f _$@
+
+sprintfc::
+ @$(AWK) -f $(srcdir)/sprintfc.awk $(srcdir)/sprintfc.in >_$@
+ $(CMP) $(srcdir)/sprintfc.ok _$@ && rm -f _$@
+
+getlnhd::
+ @$(AWK) -f $(srcdir)/getlnhd.awk >_$@
+ $(CMP) $(srcdir)/getlnhd.ok _$@ && rm -f _$@
+
+backgsub::
+ @$(AWK) -f $(srcdir)/backgsub.awk $(srcdir)/backgsub.in >_$@
+ $(CMP) $(srcdir)/backgsub.ok _$@ && rm -f _$@
+
+tweakfld::
+ @$(AWK) -f $(srcdir)/tweakfld.awk $(srcdir)/tweakfld.in >_$@
+ @rm -f errors.cleanup
+ $(CMP) $(srcdir)/tweakfld.ok _$@ && rm -f _$@
+
+clsflnam::
+ @$(AWK) -f $(srcdir)/clsflnam.awk $(srcdir)/clsflnam.in >_$@
+ $(CMP) $(srcdir)/clsflnam.ok _$@ && rm -f _$@
+
+mmap8k::
+ @$(AWK) '{ print }' $(srcdir)/mmap8k.in >_$@
+ $(CMP) $(srcdir)/mmap8k.in _$@ && rm -f _$@
+
+fnarray::
+ @-AWKPATH=$(srcdir) $(AWK) -f fnarray.awk >_$@ 2>&1 || exit 0
+ $(CMP) $(srcdir)/fnarray.ok _$@ && rm -f _$@
+
+dynlj::
+ @$(AWK) -f $(srcdir)/dynlj.awk >_$@
+ $(CMP) $(srcdir)/dynlj.ok _$@ && rm -f _$@
+
+substr::
+ @$(AWK) -f $(srcdir)/substr.awk >_$@
+ $(CMP) $(srcdir)/substr.ok _$@ && rm -f _$@
+
+eofsplit::
+ @$(AWK) -f $(srcdir)/eofsplit.awk >_$@
+ $(CMP) $(srcdir)/eofsplit.ok _$@ && rm -f _$@
+
+prt1eval::
+ @$(AWK) -f $(srcdir)/prt1eval.awk >_$@
+ $(CMP) $(srcdir)/prt1eval.ok _$@ && rm -f _$@
+
+gsubasgn::
+ @-AWKPATH=$(srcdir) $(AWK) -f gsubasgn.awk >_$@ 2>&1 || exit 0
+ $(CMP) $(srcdir)/gsubasgn.ok _$@ && rm -f _$@
+
+prtoeval::
+ @$(AWK) -f $(srcdir)/prtoeval.awk >_$@
+ $(CMP) $(srcdir)/prtoeval.ok _$@ && rm -f _$@
+
+gsubtest::
+ @$(AWK) -f $(srcdir)/gsubtest.awk >_$@
+ $(CMP) $(srcdir)/gsubtest.ok _$@ && rm -f _$@
+
+splitwht::
+ @$(AWK) -f $(srcdir)/splitwht.awk >_$@
+ $(CMP) $(srcdir)/splitwht.ok _$@ && rm -f _$@
+
+back89::
+ @$(AWK) '/a\8b/' $(srcdir)/back89.in >_$@
+ $(CMP) $(srcdir)/back89.ok _$@ && rm -f _$@
+
+tradanch::
+ @$(AWK) --traditional -f $(srcdir)/tradanch.awk $(srcdir)/tradanch.in >_$@
+ $(CMP) $(srcdir)/tradanch.ok _$@ && rm -f _$@
+
+nlfldsep::
+ AWK=$(AWK); export AWK; $(srcdir)/nlfldsep.sh > _$@
+ $(CMP) $(srcdir)/nlfldsep.ok _$@ && rm -f _$@
+
+splitvar::
+ @$(AWK) -f $(srcdir)/splitvar.awk $(srcdir)/splitvar.in >_$@
+ $(CMP) $(srcdir)/splitvar.ok _$@ && rm -f _$@
+
clean:
- rm -fr _* core junk
+ rm -fr _* core junk out1 out2 out3 strftime.ok *~
+
+distclean: clean
+ rm -f Makefile
+
+maintainer-clean: distclean
diff --git a/test/README b/test/README
index 725d7d98..2343be2f 100644
--- a/test/README
+++ b/test/README
@@ -1,4 +1,4 @@
-Wed Aug 16 12:22:45 PDT 1995
+Mon Jan 22 13:08:58 EST 1996
This directory contains the tests for gawk. The tests use the
following conventions.
@@ -13,3 +13,6 @@ _foo --- the actual results; generated at run time
The _foo file will be left around if a test fails, allowing you to
compare actual and expected results, in case they differ.
+
+If they do differ (other than strftime.ok and _strftime!), send in a
+bug report. See the manual for the bug report procedure.
diff --git a/test/back89.in b/test/back89.in
new file mode 100644
index 00000000..b0a88f24
--- /dev/null
+++ b/test/back89.in
@@ -0,0 +1,2 @@
+a8b
+a\8b
diff --git a/test/back89.ok b/test/back89.ok
new file mode 100644
index 00000000..e9ea4d5f
--- /dev/null
+++ b/test/back89.ok
@@ -0,0 +1 @@
+a8b
diff --git a/test/backgsub.awk b/test/backgsub.awk
new file mode 100644
index 00000000..bec73549
--- /dev/null
+++ b/test/backgsub.awk
@@ -0,0 +1,4 @@
+{
+ gsub( "\\\\", "\\\\")
+ print
+}
diff --git a/test/backgsub.in b/test/backgsub.in
new file mode 100644
index 00000000..2d3f17f0
--- /dev/null
+++ b/test/backgsub.in
@@ -0,0 +1 @@
+\x\y\z
diff --git a/test/backgsub.ok b/test/backgsub.ok
new file mode 100644
index 00000000..e2e265fa
--- /dev/null
+++ b/test/backgsub.ok
@@ -0,0 +1 @@
+\\x\\y\\z
diff --git a/test/badargs.ok b/test/badargs.ok
index a4652933..c89e520f 100644
--- a/test/badargs.ok
+++ b/test/badargs.ok
@@ -5,7 +5,7 @@ POSIX options: GNU long options:
-f progfile --file=progfile
-F fs --field-separator=fs
-v var=val --assign=var=val
- -m[fr]=val
+ -m[fr] val
-W compat --compat
-W copyleft --copyleft
-W copyright --copyright
@@ -18,3 +18,6 @@ POSIX options: GNU long options:
-W traditional --traditional
-W usage --usage
-W version --version
+
+Report bugs to bug-gnu-utils@prep.ai.mit.edu,
+with a Cc: to arnold@gnu.ai.mit.edu
diff --git a/test/clsflnam.awk b/test/clsflnam.awk
new file mode 100644
index 00000000..53928912
--- /dev/null
+++ b/test/clsflnam.awk
@@ -0,0 +1,12 @@
+#! /usr/bin/awk -f
+BEGIN {
+ getline
+# print ("FILENAME =", FILENAME) > "/dev/stderr"
+ #Rewind the file
+ if (close(FILENAME)) {
+ print "Error " ERRNO " closing input file" > "/dev/stderr";
+ exit;
+ }
+}
+{ print "Analysing ", $0 }
+
diff --git a/test/clsflnam.in b/test/clsflnam.in
new file mode 100644
index 00000000..a92d664b
--- /dev/null
+++ b/test/clsflnam.in
@@ -0,0 +1,3 @@
+line 1
+line 2
+line 3
diff --git a/test/clsflnam.ok b/test/clsflnam.ok
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/clsflnam.ok
diff --git a/test/dynlj.awk b/test/dynlj.awk
new file mode 100644
index 00000000..ec6851bb
--- /dev/null
+++ b/test/dynlj.awk
@@ -0,0 +1 @@
+BEGIN { printf "%*sworld\n", -20, "hello" }
diff --git a/test/dynlj.ok b/test/dynlj.ok
new file mode 100644
index 00000000..c8f3fe9d
--- /dev/null
+++ b/test/dynlj.ok
@@ -0,0 +1 @@
+hello world
diff --git a/test/eofsplit.awk b/test/eofsplit.awk
new file mode 100644
index 00000000..22042b44
--- /dev/null
+++ b/test/eofsplit.awk
@@ -0,0 +1,68 @@
+# Date: Sat, 30 Mar 1996 12:47:17 -0800 (PST)
+# From: Charles Howes <chowes@grid.direct.ca>
+# To: bug-gnu-utils@prep.ai.mit.edu, arnold@gnu.ai.mit.edu
+# Subject: Bug in Gawk 3.0.0, sample code:
+#
+#!/usr/local/bin/gawk -f
+#
+# Hello! This is a bug report from chowes@direct.ca
+#
+# uname -a
+# SunOS hostname 5.5 Generic sun4m
+#
+# Gnu Awk (gawk) 3.0, patchlevel 0:
+BEGIN{
+FS=":"
+while ((getline < "/etc/passwd") > 0) {
+ r=$3
+ z=0
+ n[0]=1
+ }
+FS=" "
+}
+#gawk: fp.new:16: fatal error: internal error
+#Abort
+
+# #!/usr/local/bin/gawk -f
+# # Gnu Awk (gawk) 2.15, patchlevel 6
+#
+# BEGIN{
+# f="/etc/passwd"
+# while (getline < f) n[0]=1
+# FS=" "
+# }
+# #gawk: /staff/chowes/bin/fp:7: fatal error: internal error
+# #Abort
+
+# These examples are not perfect coding style because I took a real
+# piece of code and tried to strip away anything that didn't make the error
+# message go away.
+#
+# The interesting part of the 'truss' is:
+#
+# fstat(3, 0xEFFFF278) = 0
+# lseek(3, 0, SEEK_SET) = 0
+# read(3, " r o o t : x : 0 : 1 : S".., 2291) = 2291
+# brk(0x00050020) = 0
+# brk(0x00052020) = 0
+# read(3, 0x0004F4B8, 2291) = 0
+# close(3) = 0
+# Incurred fault #6, FLTBOUNDS %pc = 0x0001B810
+# siginfo: SIGSEGV SEGV_MAPERR addr=0x00053000
+# Received signal #11, SIGSEGV [caught]
+# siginfo: SIGSEGV SEGV_MAPERR addr=0x00053000
+# write(2, " g a w k", 4) = 4
+# write(2, " : ", 2) = 2
+#
+# --
+# Charles Howes -- chowes@direct.ca Voice: (604) 691-1607
+# System Administrator Fax: (604) 691-1605
+# Internet Direct - 1050 - 555 West Hastings St - Vancouver, BC V6B 4N6
+#
+# A sysadmin's life is a sorry one. The only advantage he has over Emergency
+# Room doctors is that malpractice suits are rare. On the other hand, ER
+# doctors never have to deal with patients installing new versions of their
+# own innards! -Michael O'Brien
+#
+# "I think I know what may have gone wrong in the original s/w.
+# It's a bug in the way it was written." - Vagueness**n
diff --git a/test/eofsplit.ok b/test/eofsplit.ok
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/eofsplit.ok
diff --git a/test/fldchgnf.awk b/test/fldchgnf.awk
new file mode 100644
index 00000000..fbb8f118
--- /dev/null
+++ b/test/fldchgnf.awk
@@ -0,0 +1 @@
+{ OFS = ":"; $2 = ""; print $0; print NF }
diff --git a/test/fldchgnf.in b/test/fldchgnf.in
new file mode 100644
index 00000000..8e13e468
--- /dev/null
+++ b/test/fldchgnf.in
@@ -0,0 +1 @@
+a b c d
diff --git a/test/fldchgnf.ok b/test/fldchgnf.ok
new file mode 100644
index 00000000..10b38edd
--- /dev/null
+++ b/test/fldchgnf.ok
@@ -0,0 +1,2 @@
+a::c:d
+4
diff --git a/test/fnarray.awk b/test/fnarray.awk
new file mode 100644
index 00000000..92a18b98
--- /dev/null
+++ b/test/fnarray.awk
@@ -0,0 +1,7 @@
+function foo(N) {
+ return 0
+}
+BEGIN {
+ Num = foo[c]
+}
+
diff --git a/test/fnarray.ok b/test/fnarray.ok
new file mode 100644
index 00000000..94beacdd
--- /dev/null
+++ b/test/fnarray.ok
@@ -0,0 +1 @@
+gawk: fnarray.awk:5: fatal: attempt to use function `foo' as array
diff --git a/test/gensub.awk b/test/gensub.awk
index 33a2a5e4..f91d84dc 100644
--- a/test/gensub.awk
+++ b/test/gensub.awk
@@ -4,3 +4,4 @@ BEGIN { a = "this is a test of gawk"
}
NR == 1 { print gensub(/b/, "BB", 2) }
NR == 2 { print gensub(/c/, "CC", "global") }
+END { print gensub(/foo/, "bar", 1, "DON'T PANIC") }
diff --git a/test/gensub.ok b/test/gensub.ok
index c909cd0d..b9ea3dec 100644
--- a/test/gensub.ok
+++ b/test/gensub.ok
@@ -1,3 +1,4 @@
3 = <gawk>, 2 = <test>, 1 = <this>
a b c a BB c a b c
a b CC a b CC a b CC
+DON'T PANIC
diff --git a/test/getlnhd.awk b/test/getlnhd.awk
new file mode 100644
index 00000000..f0f801b2
--- /dev/null
+++ b/test/getlnhd.awk
@@ -0,0 +1,10 @@
+BEGIN { pipe = "cat <<EOF\n"
+ pipe = pipe "select * from user\n"
+ pipe = pipe " where Name = 'O\\'Donell'\n"
+ pipe = pipe "EOF\n"
+
+ while ((pipe | getline) > 0)
+ print
+
+ exit 0
+}
diff --git a/test/getlnhd.ok b/test/getlnhd.ok
new file mode 100644
index 00000000..d8cb4530
--- /dev/null
+++ b/test/getlnhd.ok
@@ -0,0 +1,2 @@
+select * from user
+ where Name = 'O\'Donell'
diff --git a/test/gsubasgn.awk b/test/gsubasgn.awk
new file mode 100644
index 00000000..f0b77012
--- /dev/null
+++ b/test/gsubasgn.awk
@@ -0,0 +1,13 @@
+# tests for assigning to a function within that function
+
+#1 - should be bad
+function test1 (r) { gsub(r, "x", test1) }
+BEGIN { test1("") }
+
+#2 - should be bad
+function test2 () { gsub(/a/, "x", test2) }
+BEGIN { test2() }
+
+#3 - should be ok
+function test3 (r) { gsub(/a/, "x", r) }
+BEGIN { test3("") }
diff --git a/test/gsubasgn.ok b/test/gsubasgn.ok
new file mode 100644
index 00000000..dfa6fbc7
--- /dev/null
+++ b/test/gsubasgn.ok
@@ -0,0 +1,4 @@
+gawk: gsubasgn.awk:4: function test1 (r) { gsub(r, "x", test1) }
+gawk: gsubasgn.awk:4: ^ gsub third parameter is not a changeable object
+gawk: gsubasgn.awk:8: function test2 () { gsub(/a/, "x", test2) }
+gawk: gsubasgn.awk:8: ^ gsub third parameter is not a changeable object
diff --git a/test/gsubtest.awk b/test/gsubtest.awk
new file mode 100644
index 00000000..31374795
--- /dev/null
+++ b/test/gsubtest.awk
@@ -0,0 +1,8 @@
+BEGIN {
+ str = "abc"; gsub("b+", "FOO", str); print str
+ str = "abc"; gsub("x*", "X", str); print str
+ str = "abc"; gsub("b*", "X", str); print str
+ str = "abc"; gsub("c", "X", str); print str
+ str = "abc"; gsub("c+", "X", str); print str
+ str = "abc"; gsub("x*$", "X", str); print str
+}
diff --git a/test/gsubtest.ok b/test/gsubtest.ok
new file mode 100644
index 00000000..191bebda
--- /dev/null
+++ b/test/gsubtest.ok
@@ -0,0 +1,6 @@
+aFOOc
+XaXbXcX
+XaXcX
+abX
+abX
+abcX
diff --git a/test/mmap8k.in b/test/mmap8k.in
new file mode 100644
index 00000000..0500ddf2
--- /dev/null
+++ b/test/mmap8k.in
@@ -0,0 +1,143 @@
+XXXXXXXX.com ALTERNET 9305 930528 1500.00 startup
+XXXXXXXX.com ALTERNET 9305 930624 94.38 Line-9305
+XXXXXXXX.com ALTERNET 9306 930624 104.49 Line-9306
+XXXXXXXX.com ALTERNET 9306 930624 649.16 Line-install
+XXXXXXXX.com ALTERNET 9306 930624 166.67 TCP-slip
+XXXXXXXX.com ALTERNET 9307 930624 104.49 Line-9307
+XXXXXXXX.com ALTERNET 9307 930624 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9308 930701 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9308 930701 104.49 line-9308
+XXXXXXXX.com PAYMENT 9307 930731 1500.00 1870
+XXXXXXXX.com ALTERNET 9309 930801 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9309 930801 104.49 line-9309
+XXXXXXXX.com INTEREST 9307 930801 22.50
+XXXXXXXX.com CREDADJ 9308 930805 22.50 waive interest
+XXXXXXXX.com PAYMENT 9308 930820 1723.68 1982
+XXXXXXXX.com ALTERNET 9310 930901 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9310 930901 104.49 line-9310
+XXXXXXXX.com PAYMENT 9310 931001 708.98 2313
+XXXXXXXX.com ALTERNET 9311 931001 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9311 931001 104.49 line-9311
+XXXXXXXX.com INTEREST 9309 931001 5.32
+XXXXXXXX.com CREDADJ 9310 931007 5.32 waive int-9309
+XXXXXXXX.com ALTERNET 9312 931101 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9312 931101 104.49 line-9312
+XXXXXXXX.com PAYMENT 9311 931120 354.49 002701
+XXXXXXXX.com ALTERNET 9401 931201 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9401 931201 104.49 line-9401
+XXXXXXXX.com PAYMENT 9312 931218 354.49 2884
+XXXXXXXX.com ALTERNET 9402 940101 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9402 940101 104.49 line-9402
+XXXXXXXX.com INTEREST 9312 940101 5.32
+XXXXXXXX.com PAYMENT 9401 940122 354.49 3084
+XXXXXXXX.com ALTERNET 9403 940201 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9403 940201 104.49 line-9403
+XXXXXXXX.com INTEREST 9401 940201 5.40
+XXXXXXXX.com PAYMENT 9402 940207 354.49 3140
+XXXXXXXX.com CREDADJ 9402 940211 5.32 interest-9402
+XXXXXXXX.com CREDADJ 9402 940211 5.40 interest-9403
+XXXXXXXX.com ALTERNET 9404 940301 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9404 940301 104.49 line-9404
+XXXXXXXX.com INTEREST 9402 940301 5.32
+XXXXXXXX.com PAYMENT 9403 940310 354.49 003307
+XXXXXXXX.com PAYMENT 9403 940324 354.49 3446
+XXXXXXXX.com ALTERNET 9405 940401 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9405 940401 104.49 line-9405
+XXXXXXXX.com ALTERNET 9406 940501 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9406 940501 104.49 line-9406
+XXXXXXXX.com INTEREST 9404 940501 5.40
+XXXXXXXX.com PAYMENT 9405 940509 359.81 003819
+XXXXXXXX.com ALTERNET 9407 940601 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9407 940601 104.49 line-9407
+XXXXXXXX.com INTEREST 9405 940601 5.40
+XXXXXXXX.com PAYMENT 9406 940603 354.49 004025
+XXXXXXXX.com ALTERNET 9408 940701 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9408 940701 104.49 line-9408
+XXXXXXXX.com INTEREST 9406 940701 5.48
+XXXXXXXX.com PAYMENT 9407 940725 354.49 004350
+XXXXXXXX.com ALTERNET 9409 940801 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9409 940801 104.49 line-9409
+XXXXXXXX.com INTEREST 9407 940801 5.56
+XXXXXXXX.com PAYMENT 9408 940808 354.49 004454
+XXXXXXXX.com ALTERNET 9409 940811 0.00 startup
+XXXXXXXX.com EQUIPMENT 9408 940831 399.00 ATL6402-1
+XXXXXXXX.com EQUIPMENT 9408 940831 2295.00 NBClassicPac-1
+XXXXXXXX.com EQUIPMENT 9408 940831 1060.00 Syn35-1+ship
+XXXXXXXX.com ALTERNET 9410 940901 250.00 TCP-slip
+XXXXXXXX.com ALTERNET 9410 940901 104.49 line-9410
+XXXXXXXX.com INTEREST 9408 940901 5.64
+XXXXXXXX.com PAYMENT 9409 940906 354.49 004677
+XXXXXXXX.com CREDADJ 9409 940921 124.95 TCP-slip-9409
+XXXXXXXX.com CREDADJ 9409 940921 52.20 line-9409
+XXXXXXXX.com CREDADJ 9410 940921 250.00 TCP-slip-9410
+XXXXXXXX.com CREDADJ 9410 940921 104.49 line-9410
+XXXXXXXX.com ALTERNET 9409 940921 397.50 TCP-56k-local recon
+XXXXXXXX.com ALTERNET 9409 940921 87.45 line-9409 recon
+XXXXXXXX.com ALTERNET 9410 940921 795.00 TCP-56k-local recon
+XXXXXXXX.com ALTERNET 9410 940921 174.90 line-9410 recon
+XXXXXXXX.com ALTERNET 9411 941001 795.00 TCP-56k-local
+XXXXXXXX.com ALTERNET 9411 941001 174.90 line-9411
+XXXXXXXX.com INTEREST 9409 941001 54.06
+XXXXXXXX.com PAYMENT 9410 941017 354.49 5026
+XXXXXXXX.com ALTERNET 9412 941101 795.00 TCP-56k-local
+XXXXXXXX.com ALTERNET 9412 941101 174.90 line-9412
+XXXXXXXX.com INTEREST 9410 941101 85.93
+XXXXXXXX.com PAYMENT 9411 941114 969.90 005274
+XXXXXXXX.com ALTERNET 9501 941201 795.00 TCP-56k-local
+XXXXXXXX.com ALTERNET 9501 941201 174.90 line-9501
+XXXXXXXX.com INTEREST 9411 941201 87.22
+XXXXXXXX.com PAYMENT 9412 941219 4723.90 5590
+XXXXXXXX.com ALTERNET 9502 950101 795.00 TCP-56k-local
+XXXXXXXX.com ALTERNET 9502 950101 174.90 line-9502
+XXXXXXXX.com INTEREST 9412 950101 32.22
+XXXXXXXX.com PAYMENT 9501 950103 1893.11 5766
+XXXXXXXX.com ALTERNET 9503 950201 795.00 TCP-56k-local-old
+XXXXXXXX.com ALTERNET 9503 950201 174.90 line-9503
+XXXXXXXX.com INTEREST 9501 950201 18.85
+XXXXXXXX.com PAYMENT 9502 950207 969.90 6044
+XXXXXXXX.com ALTERNET 9504 950301 795.00 TCP-56k-local-old
+XXXXXXXX.com ALTERNET 9504 950301 174.90 line-9504
+XXXXXXXX.com INTEREST 9502 950301 19.13
+XXXXXXXX.com PAYMENT 9503 950307 969.90 6408
+XXXXXXXX.com ALTERNET 9504 950316 3000.00 startup TCP-bt1-128k%5
+XXXXXXXX.com PAYMENT 9503 950327 969.90 6594
+XXXXXXXX.com ALTERNET 9505 950401 1187.50 TCP-bt1-128k%5.00
+XXXXXXXX.com ALTERNET 9505 950401 556.60 line-9505
+XXXXXXXX.com EQUIPMENT 9504 950410 1595.00 cisco2501-1
+XXXXXXXX.com CREDADJ 9504 950417 503.50 TCP-56k-local
+XXXXXXXX.com CREDADJ 9504 950417 116.60 line-9504
+XXXXXXXX.com ALTERNET 9504 950417 448.80 line-install
+XXXXXXXX.com ALTERNET 9504 950417 752.02 TCP-bt1-128k%5 recon
+XXXXXXXX.com ALTERNET 9504 950417 371.00 line-9504 recon
+XXXXXXXX.com PAYMENT 9504 950424 3000.00 6841
+XXXXXXXX.com ALTERNET 9506 950501 1187.50 TCP-bt1-128k%5.00
+XXXXXXXX.com ALTERNET 9506 950501 556.60 line-9506
+XXXXXXXX.com PAYMENT 9505 950505 2049.86 6985
+XXXXXXXX.com PAYMENT 9505 950531 3924.22 7179
+XXXXXXXX.com ALTERNET 9507 950601 1187.50 TCP-bt1-128k%5.00
+XXXXXXXX.com ALTERNET 9507 950601 556.60 line-9507
+XXXXXXXX.com PAYMENT 9506 950607 1744.10 7232
+XXXXXXXX.com ALTERNET 9508 950701 1187.50 TCP-bt1-128k%5.00
+XXXXXXXX.com ALTERNET 9508 950701 556.60 line-9508
+XXXXXXXX.com PAYMENT 9507 950705 1744.10 7641
+XXXXXXXX.com ALTERNET 9509 950801 1187.50 TCP-bt1-128k%5.00
+XXXXXXXX.com ALTERNET 9509 950801 556.60 line-9509
+XXXXXXXX.com PAYMENT 9508 950803 1744.10 7914
+XXXXXXXX.com ALTERNET 9510 950901 1187.50 TCP-bt1-128k%5.00
+XXXXXXXX.com ALTERNET 9510 950901 556.60 line-9510
+XXXXXXXX.com PAYMENT 9509 950905 1744.10 8203
+XXXXXXXX.com ALTERNET 9511 951001 1187.50 TCP-bt1-128k%5.00
+XXXXXXXX.com ALTERNET 9511 951001 556.60 line-9511
+XXXXXXXX.com PAYMENT 9510 951003 1744.10 8508
+XXXXXXXX.com ALTERNET 9512 951101 1187.50 TCP-bt1-128k%5.00
+XXXXXXXX.com ALTERNET 9512 951101 556.60 line-9512
+XXXXXXXX.com PAYMENT 9511 951103 2129.83 8837
+XXXXXXXX.com ALTERNET 9601 951201 1187.50 TCP-bt1-128k%5.00
+XXXXXXXX.com ALTERNET 9601 951201 556.60 line-9601
+XXXXXXXX.com PAYMENT 9512 951204 2129.83 9131
+XXXXXXXX.com ALTERNET 9602 960101 1187.50 TCP-bt1-128k%5.00
+XXXXXXXX.com ALTERNET 9602 960101 556.60 line-9602
+XXXXXXXX.com PAYMENT 9601 960103 1744.10 9456
+XXXXXXXX.com ALTERNET 9603 960201 1187.50 TCP-bt1-128k%5.00
+XXXXXXXX.com ALTERNET 9603 960201 556.60 line-9603
+XXXXXXXX.com PAYMENT 9602 960205 1358.37 9834
diff --git a/test/nlfldsep.ok b/test/nlfldsep.ok
new file mode 100644
index 00000000..66849161
--- /dev/null
+++ b/test/nlfldsep.ok
@@ -0,0 +1,13 @@
+4
+some
+stuff
+more
+stuff
+
+2
+junk
+stuff
+
+1
+final
+
diff --git a/test/nlfldsep.sh b/test/nlfldsep.sh
new file mode 100755
index 00000000..0a0a5f53
--- /dev/null
+++ b/test/nlfldsep.sh
@@ -0,0 +1,10 @@
+#! /bin/sh
+AWK=${AWK-../gawk}
+
+echo 'some stuff
+more stuffA
+junk
+stuffA
+final' | $AWK 'BEGIN { RS = "A" }
+{print NF; for (i = 1; i <= NF; i++) print $i ; print ""}'
+
diff --git a/test/prt1eval.awk b/test/prt1eval.awk
new file mode 100644
index 00000000..4ecd3680
--- /dev/null
+++ b/test/prt1eval.awk
@@ -0,0 +1,6 @@
+function tst () {
+ sum += 1
+ return sum
+}
+
+BEGIN { OFMT = "%.0f" ; print tst() }
diff --git a/test/prt1eval.ok b/test/prt1eval.ok
new file mode 100644
index 00000000..d00491fd
--- /dev/null
+++ b/test/prt1eval.ok
@@ -0,0 +1 @@
+1
diff --git a/test/prtoeval.awk b/test/prtoeval.awk
new file mode 100644
index 00000000..77880d87
--- /dev/null
+++ b/test/prtoeval.awk
@@ -0,0 +1,4 @@
+function returns_a_str() { print "<in function>" ; return "'A STRING'" }
+BEGIN {
+ print "partial line:", returns_a_str()
+}
diff --git a/test/prtoeval.ok b/test/prtoeval.ok
new file mode 100644
index 00000000..13e122b8
--- /dev/null
+++ b/test/prtoeval.ok
@@ -0,0 +1,2 @@
+<in function>
+partial line: 'A STRING'
diff --git a/test/rand.awk b/test/rand.awk
index 08f9894e..6378f3d3 100644
--- a/test/rand.awk
+++ b/test/rand.awk
@@ -1,5 +1,5 @@
BEGIN {
- srand()
+ srand(2)
for (i = 0; i < 19; i++)
printf "%3d ", (1 + int(100 * rand()))
print ""
diff --git a/test/rand.ok b/test/rand.ok
new file mode 100644
index 00000000..b6d75545
--- /dev/null
+++ b/test/rand.ok
@@ -0,0 +1 @@
+ 27 17 86 27 22 53 61 11 33 48 51 97 99 35 20 27 62 100 32
diff --git a/test/reindops.awk b/test/reindops.awk
new file mode 100644
index 00000000..13ae6576
--- /dev/null
+++ b/test/reindops.awk
@@ -0,0 +1,6 @@
+{
+ if ($1 !~ /^+[2-9]/)
+ print "gawk is broken"
+ else
+ print "gawk is ok"
+}
diff --git a/test/reindops.in b/test/reindops.in
new file mode 100644
index 00000000..b1e54353
--- /dev/null
+++ b/test/reindops.in
@@ -0,0 +1 @@
++44 123 456
diff --git a/test/reindops.ok b/test/reindops.ok
new file mode 100644
index 00000000..f9605fd3
--- /dev/null
+++ b/test/reindops.ok
@@ -0,0 +1 @@
+gawk is ok
diff --git a/test/splitvar.awk b/test/splitvar.awk
new file mode 100644
index 00000000..9e1ac790
--- /dev/null
+++ b/test/splitvar.awk
@@ -0,0 +1,5 @@
+{
+ sep = "=+"
+ n = split($0, a, sep)
+ print n
+}
diff --git a/test/splitvar.in b/test/splitvar.in
new file mode 100644
index 00000000..85be8ee5
--- /dev/null
+++ b/test/splitvar.in
@@ -0,0 +1 @@
+Here===Is=Some=====Data
diff --git a/test/splitvar.ok b/test/splitvar.ok
new file mode 100644
index 00000000..b8626c4c
--- /dev/null
+++ b/test/splitvar.ok
@@ -0,0 +1 @@
+4
diff --git a/test/splitwht.awk b/test/splitwht.awk
new file mode 100644
index 00000000..6163d72e
--- /dev/null
+++ b/test/splitwht.awk
@@ -0,0 +1,7 @@
+BEGIN {
+ str = "a b\t\tc d"
+ n = split(str, a, " ")
+ print n
+ m = split(str, b, / /)
+ print m
+}
diff --git a/test/splitwht.ok b/test/splitwht.ok
new file mode 100644
index 00000000..61c83cba
--- /dev/null
+++ b/test/splitwht.ok
@@ -0,0 +1,2 @@
+4
+5
diff --git a/test/sprintfc.awk b/test/sprintfc.awk
new file mode 100644
index 00000000..ee1e5a7c
--- /dev/null
+++ b/test/sprintfc.awk
@@ -0,0 +1 @@
+{ print sprintf("%c", $1), $1 }
diff --git a/test/sprintfc.in b/test/sprintfc.in
new file mode 100644
index 00000000..4602d28d
--- /dev/null
+++ b/test/sprintfc.in
@@ -0,0 +1,3 @@
+65
+66
+foo
diff --git a/test/sprintfc.ok b/test/sprintfc.ok
new file mode 100644
index 00000000..33769a82
--- /dev/null
+++ b/test/sprintfc.ok
@@ -0,0 +1,3 @@
+A 65
+B 66
+f foo
diff --git a/test/strftime.ok b/test/strftime.ok
deleted file mode 100644
index 52715bb9..00000000
--- a/test/strftime.ok
+++ /dev/null
@@ -1 +0,0 @@
-Thu Jan 11 09:35:20 EST 1996
diff --git a/test/substr.awk b/test/substr.awk
new file mode 100644
index 00000000..f330402c
--- /dev/null
+++ b/test/substr.awk
@@ -0,0 +1,5 @@
+BEGIN {
+ x = "A"
+ printf("%-39s\n", substr(x,1,39))
+ exit (0)
+}
diff --git a/test/substr.ok b/test/substr.ok
new file mode 100644
index 00000000..5f9debb1
--- /dev/null
+++ b/test/substr.ok
@@ -0,0 +1 @@
+A
diff --git a/test/tradanch.awk b/test/tradanch.awk
new file mode 100644
index 00000000..0cd45d17
--- /dev/null
+++ b/test/tradanch.awk
@@ -0,0 +1,2 @@
+/foo^bar/
+/foo$bar/
diff --git a/test/tradanch.in b/test/tradanch.in
new file mode 100644
index 00000000..e5c8a094
--- /dev/null
+++ b/test/tradanch.in
@@ -0,0 +1,2 @@
+foo^bar
+foo$bar
diff --git a/test/tradanch.ok b/test/tradanch.ok
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/tradanch.ok
diff --git a/test/tweakfld.awk b/test/tweakfld.awk
new file mode 100644
index 00000000..e7b538f6
--- /dev/null
+++ b/test/tweakfld.awk
@@ -0,0 +1,296 @@
+# To: bug-gnu-utils@prep.ai.mit.edu
+# Cc: arnold@gnu.ai.mit.edu
+# Date: Mon, 20 Nov 1995 11:39:29 -0500
+# From: "R. Hank Donnelly" <emory!head-cfa.harvard.edu!donnelly>
+#
+# Operating system: Linux1.2.13 (Slackware distrib)
+# GAWK version: 2.15 (?)
+# compiler: GCC (?)
+#
+# The following enclosed script does not want to fully process the input data
+# file. It correctly executes the operations on the first record, and then dies
+# on the second one. My true data file is much longer but this is
+# representative and it does fail on a file even as short as this one.
+# The failure appears to occur in the declared function add2output. Between the
+# steps of incrementing NF by one and setting $NF to the passed variable
+# the passed variable appears to vanish (i.e. NF does go from 68 to 69
+# and before incrementing it "variable" equals what it should but after
+# "variable" has no value at all.)
+#
+# The scripts have been developed using nawk on a Sun (where they run fine)
+# I have tried gawk there but get a different crash which I have not yet traced
+# down. Ideally I would like to keep the script the same so that it would run
+# on either gawk or nawk (that way I can step back and forth between laptop and
+# workstation.
+#
+# Any ideas why the laptop installation is having problems?
+# Hank
+#
+#
+# #!/usr/bin/gawk -f
+
+BEGIN {
+ # set a few values
+ FS = "\t"
+ OFS = "\t"
+ pi = atan2(0, -1)
+# distance from HRMA to focal plane in mm
+ fullradius = 10260.54
+
+ # set locations of parameters on input line
+ nf_nrg = 1
+ nf_order = 3
+ nf_item = 4
+ nf_suite = 5
+ nf_grating = 8
+ nf_shutter = 9
+ nf_type = 13
+ nf_src = 14
+ nf_target = 15
+ nf_voltage = 16
+ nf_flux = 17
+ nf_filt1 = 20
+ nf_filt1_th = 21
+ nf_filt2 = 22
+ nf_filt2_th = 23
+ nf_bnd = 24
+ nf_hrma_polar = 27
+ nf_hrma_az = 28
+ nf_detector = 30
+ nf_acis_read = 32
+ nf_acis_proc = 33
+ nf_acis_frame = 34
+ nf_hxda_aplist = 36
+ nf_hxda_y_range = 37
+ nf_hxda_z_range = 38
+ nf_hxda_y_step = 39
+ nf_hxda_z_step = 40
+ nf_sim_z = 41
+ nf_fam_polar = 43
+ nf_fam_az = 44
+ nf_fam_dither_type = 45
+ nf_mono_init = 51
+ nf_mono_range = 52
+ nf_mono_step = 53
+ nf_defocus = 54
+ nf_acis_temp = 55
+ nf_tight = 59
+ nf_offset_y = 64
+ nf_offset_z = 65
+
+ while( getline < "xrcf_mnemonics.dat" > 0 ) {
+ mnemonic[$1] = $2
+ }
+
+# "date" | getline date_line
+# ADR: use a fixed date so that testing will work
+ date_line = "Sun Mar 10 23:00:27 EST 1996"
+ split(date_line, in_date, " ")
+ out_date = in_date[2] " " in_date[3] ", " in_date[6]
+}
+
+function add2output( variable ) {
+#print("hi1") >> "debug"
+ NF++
+#print("hi2") >> "debug"
+ $NF = variable
+#print("hi3") >> "debug"
+}
+
+function error( ekey, message ) {
+ print "Error at input line " NR ", anode " ekey >> "errors.cleanup"
+ print " " message "." >> "errors.cleanup"
+}
+
+function hxda_na() {
+ $nf_hxda_aplist = $nf_hxda_y_range = $nf_hxda_z_range = "N/A"
+ $nf_hxda_y_step = $nf_hxda_z_step = "N/A"
+}
+
+function acis_na() {
+ $nf_acis_read = $nf_acis_proc = $nf_acis_frame = $nf_acis_temp = "N/A"
+}
+
+function hrc_na() {
+# print ("hi") >> "debug"
+}
+
+function fpsi_na() {
+ acis_na()
+ hrc_na()
+ $nf_sim_z = $nf_fam_polar = $nf_fam_az = $nf_fam_dither_type = "N/A"
+}
+
+function mono_na() {
+ $nf_mono_init = $nf_mono_range = $nf_mono_step = "N/A"
+}
+
+# this gives the pitch and yaw of the HRMA and FAM
+# positive pitch is facing the source "looking down"
+# positive yaw is looking left
+# 0 az is north 90 is up
+# this also adds in the FAM X,Y,Z positions
+
+function polaz2yawpitch(polar, az) {
+ theta = az * pi / 180
+ phi = polar * pi / 180 / 60
+
+
+ if( polar == 0 ) {
+ add2output( 0 )
+ add2output( 0 )
+ } else {
+ if(az == 0 || az == 180)
+ add2output( 0 )
+ else
+ add2output( - polar * sin(theta) )
+
+
+# x = cos (phi)
+# y = sin (phi) * cos (theta)
+# add2output( atan2(y,x)*180 / pi * 60 )
+
+ if(az == 90 || az ==270 )
+ add2output( 0 )
+ else
+ add2output( - polar * cos(theta) )
+
+ }
+# x = cos (phi)
+# z= sin (phi) * sin (theta)
+# add2output( atan2(z,x)*180 / pi * 60 )
+
+ if(config !~ /HXDA/) {
+# negative values of defocus move us farther from the source thus
+# increasing radius
+ radius = fullradius - defocus
+
+# FAM_x; FAM_y; FAM_z
+ if((offset_y == 0) && (offset_z == 0)){
+ add2output( fullradius - radius * cos (phi) )
+
+ if (az == 90 || az ==270)
+ add2output( 0 )
+ else
+ add2output( radius * sin (phi) * cos (theta) )
+
+ if (az == 0 || az == 180)
+ add2output( 0 )
+ else
+ add2output( - radius * sin (phi) * sin (theta) )
+ } else {
+# ******* THIS SEGMENT OF CODE IS NOT MATHEMATICALLY CORRECT FOR ****
+# OFF AXIS ANGLES AND IS SUPPLIED AS A WORKAROUND SINCE IT WILL
+# PROBABLY ONLY BE USED ON AXIS.
+ add2output( defocus )
+ add2output( offset_y )
+ add2output( offset_z )
+ }
+
+ } else {
+ add2output( "N/A" )
+ add2output( "N/A" )
+ add2output( "N/A" )
+ }
+}
+
+# set TIGHT/LOOSE to N/A if it is not one of the two allowed values
+function tight_na() {
+ if( $nf_tight !~ /TIGHT|LOOSE/ ) {
+ $nf_tight == "N/A"
+ }
+}
+
+# this entry is used to give certain entries names
+{
+ type = $nf_type
+ item = $nf_item
+ suite = $nf_suite
+ order = $nf_order
+ detector = $nf_detector
+ grating = $nf_grating
+ offset_y= $nf_offset_y
+ offset_z= $nf_offset_z
+ bnd = $nf_bnd
+ defocus = $nf_defocus
+}
+
+{
+ # make configuration parameter
+ # as well as setting configuration-dependent N/A values
+
+ if( $nf_bnd ~ "SCAN" ) {
+ # BND is scanning beam
+ config = "BND"
+ hxda_na()
+ fpsi_na()
+ } else {
+ if( grating == "NONE" ) {
+ config = "HRMA"
+ } else {
+ if( grating == "HETG" ) {
+ if( order != "Both" ) {
+ $nf_shutter = order substr($nf_shutter, \
+ index($nf_shutter, ",") )
+ }
+ } else {
+ order = "N/A"
+ }
+ config = "HRMA/" grating
+ }
+
+ if( detector ~ /ACIS|HRC/ ) {
+ detsys = detector
+ nsub = sub("-", ",", detsys)
+ config = config "/" detsys
+ hxda_na()
+ } else {
+ config = config "/HXDA"
+ fpsi_na()
+ if( detector == "HSI" ) {
+ hxda_na()
+ }
+ }
+ }
+
+ add2output( config )
+
+ if( $nf_src ~ /EIPS|Penning/ ) mono_na()
+
+ if( $nf_src == "Penning" ) $nf_voltage = "N/A"
+
+ itm = sprintf("%03d", item)
+
+ if(config in mnemonic) {
+ if( type in mnemonic ) {
+ ID = mnemonic[config] "-" mnemonic[type] "-" suite "." itm
+ add2output( ID )
+ } else {
+ error(type, "measurement type not in list")
+ }
+ } else {
+ error(config, "measurement configuration not in list")
+ }
+
+ # add date to output line
+ add2output( out_date )
+
+ # Convert HRMA polar and azimuthal angles to yaw and pitch
+ polaz2yawpitch($nf_hrma_polar, $nf_hrma_az)
+
+ # set TIGHT/LOOSE to N/A if it is not one of the two allowed values
+ tight_na()
+
+ # compute number of HXDA apertures
+ if( config ~ /HXDA/ && $nf_hxda_aplist != "N/A")
+ add2output( split( $nf_hxda_aplist, dummy, "," ) )
+ else
+ add2output( "N/A" )
+
+ # make sure the BND value is properly set
+ if($nf_bnd == "FIXED" && detector ~ /ACIS/)
+ $nf_bnd =bnd"-SYNC"
+ else
+ $nf_bnd = bnd"-FREE"
+ print
+}
diff --git a/test/tweakfld.in b/test/tweakfld.in
new file mode 100644
index 00000000..e27a9dde
--- /dev/null
+++ b/test/tweakfld.in
@@ -0,0 +1,3 @@
+0.277 N/A N/A 1 1 ASC/Hank Donnelly N/A NONE ALL,ALL N/A N/A N/A Count Rate Linearity EIPS C-Ka 1.108 0.13484 N/A N/A C8H8 10.32 C8H8 20.64 FIXED 1000 NO 0 0 0 HRC,I 1000 N/A N/A N/A N/A N/A N/A N/A N/A N/A 0 N/A APT APT LISSAJOUS 44.7175 44.7175 1 N/A N/A N/A N/A N/A 0 N/A HRCCTRTLIN 0 N/A N/A N/A 10 N/A 180 0 0 N/A N/A FPSI rate
+1.486 N/A N/A 2 1 ASC/Hank Donnelly N/A NONE ALL,ALL N/A N/A N/A Count Rate Linearity EIPS Al-Ka 4.458 0.642119 N/A N/A Al 18.38 Al 36.76 FIXED 1000 NO 0 0 0 HRC,I 1000 N/A N/A N/A N/A N/A N/A N/A N/A N/A 0 N/A APT APT LISSAJOUS 5.55556 5.55556 1 N/A N/A N/A N/A N/A 0 N/A HRCCTRTLIN 0 N/A N/A N/A 10 N/A 180 0 0 N/A N/A FPSI rate
+4.51 N/A N/A 3 1 ASC/Hank Donnelly N/A NONE ALL,ALL N/A N/A N/A Count Rate Linearity EIPS Ti-Ka 22.55 3.02894 N/A N/A Ti 40.6 N/A N/A FIXED 1000 NO 0 0 0 HRC,I 1000 N/A N/A N/A N/A N/A N/A N/A N/A N/A 0 N/A APT APT LISSAJOUS 5.55556 5.55556 1 N/A N/A N/A N/A N/A 0 N/A HRCCTRTLIN 0 N/A N/A N/A 10 N/A 180 0 0 N/A N/A FPSI rate
diff --git a/test/tweakfld.ok b/test/tweakfld.ok
new file mode 100644
index 00000000..3c4d8947
--- /dev/null
+++ b/test/tweakfld.ok
@@ -0,0 +1,3 @@
+0.277 N/A N/A 1 1 ASC/Hank Donnelly N/A NONE ALL,ALL N/A N/A N/A Count Rate Linearity EIPS C-Ka 1.108 0.13484 N/A N/A C8H8 10.32 C8H8 20.64 FIXED-FREE 1000 NO 0 0 0 HRC,I 1000 N/A N/A N/A N/A N/A N/A N/A N/A N/A 0 N/A APT APT LISSAJOUS 44.7175 44.7175 1 N/A N/A N/A N/A N/A 0 N/A HRCCTRTLIN 0 N/A N/A N/A 10 N/A 180 0 0 N/A N/A FPSI rate HRMA/HRC,I Mar 10, 1996 0 0 0 0 0 N/A
+1.486 N/A N/A 2 1 ASC/Hank Donnelly N/A NONE ALL,ALL N/A N/A N/A Count Rate Linearity EIPS Al-Ka 4.458 0.642119 N/A N/A Al 18.38 Al 36.76 FIXED-FREE 1000 NO 0 0 0 HRC,I 1000 N/A N/A N/A N/A N/A N/A N/A N/A N/A 0 N/A APT APT LISSAJOUS 5.55556 5.55556 1 N/A N/A N/A N/A N/A 0 N/A HRCCTRTLIN 0 N/A N/A N/A 10 N/A 180 0 0 N/A N/A FPSI rate HRMA/HRC,I Mar 10, 1996 0 0 0 0 0 N/A
+4.51 N/A N/A 3 1 ASC/Hank Donnelly N/A NONE ALL,ALL N/A N/A N/A Count Rate Linearity EIPS Ti-Ka 22.55 3.02894 N/A N/A Ti 40.6 N/A N/A FIXED-FREE 1000 NO 0 0 0 HRC,I 1000 N/A N/A N/A N/A N/A N/A N/A N/A N/A 0 N/A APT APT LISSAJOUS 5.55556 5.55556 1 N/A N/A N/A N/A N/A 0 N/A HRCCTRTLIN 0 N/A N/A N/A 10 N/A 180 0 0 N/A N/A FPSI rate HRMA/HRC,I Mar 10, 1996 0 0 0 0 0 N/A
diff --git a/version.c b/version.c
index 62729551..e84bb7e9 100644
--- a/version.c
+++ b/version.c
@@ -1,4 +1,4 @@
-char *version_string = "@(#)Gnu Awk (gawk) 3.0";
+char *version_string = "@(#)GNU Awk 3.0";
/* 1.02 fixed /= += *= etc to return the new Left Hand Side instead
of the Right Hand Side */
@@ -46,5 +46,5 @@ char *version_string = "@(#)Gnu Awk (gawk) 3.0";
`delete array'. OS/2 port added. */
/* 3.0 RS as regexp, RT variable, FS = "", fflush builtin, posix
- regexps, IGNORECASE applies everywhere, autoconf, source
+ regexps, IGNORECASE applies to all comparison, autoconf, source
code cleanup. See the NEWS file. */
diff --git a/vms/ChangeLog b/vms/ChangeLog
index 570c031b..4d5a0918 100644
--- a/vms/ChangeLog
+++ b/vms/ChangeLog
@@ -1,3 +1,64 @@
+Fri Dec 6 20:55:57 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * redirect.h, vms-conf.h: Refine Sep 20th change: include
+ <stdlib.h> and <string.h> in redirect.h rather than vms-conf.h
+ so that it occurs for VMS POSIX as well as for normal VMS.
+
+Wed Nov 20 15:47:02 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * descrip.mms (LIBOBJS): Rename from GNUOBJS; add random.obj.
+ (LIBSRC): Rename from GNUSRC; add random.c.
+ (AWKSRC): Add random.h.
+ (random.obj, builtin.obj): Depend upon random.h.
+ * vmsbuild.com: compile random.c, link random.obj.
+
+ * vmstest.com (childin): Split message about expected failure
+ in order to avoid consecutive tick marks in the quoted string.
+
+Wed Nov 13 15:32:58 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vmstest.com: New file to execute test suite.
+
+Fri Nov 8 18:29:42 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ Revise makefiles so that no editing should be needed.
+
+ * descrip.mms: Use DEC C as the default compiler, since
+ the same compile and link options for it can be used as-is
+ on both VAX and Alpha.
+ (GNUC, VAXC): New `make' macros for specifying an alternate
+ compiler on the MMS or MMK command line.
+ (PATCHLVL): Update to 1.
+ * vmsbuild.com: Make the equivalent changes.
+
+Mon Oct 28 17:02:39 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vms.h (U_Long, U_Short): Replace u_long and u_short typedefs.
+ * vms_*.c: Use them.
+
+ * vms.h, vms_*.c: Change SYS$ and LIB$ routines to lower case
+ equivalents; fully prototype sys$ and lib$ routines rather than
+ just declare them.
+
+Fri Sep 20 17:33:05 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vms-conf.h: directly include <stdlib.h> and <string.h>.
+ * vms-conf.h (strftime): delete this macro.
+ * redirect.h (strftime): define it here instead.
+
+Fri May 17 09:08:16 1996 Arnold Robbins <arnold@skeeve.atl.ga.us>
+
+ * gawkmisc.vms (envsep): Now initialized to ',' instead of ':',
+ per email from Pat Rankin.
+
+Thu Jan 11 15:20:14 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vms-conf.h [#if __DECC]: Changes to support V5.x of DEC C.
+ (_DECC_V4SOURCE, __SOCKET_TYPEDEFS): Define these to avoid
+ duplicate u_long and u_short typedefs.
+ (__VMS_VER): If value indicates VMS V6.2 or later, redefine it to
+ indicate V6.1 in order to avoid conflicting prototype for getopt.
+
Wed Jan 10 22:58:55 1996 Arnold D. Robbins <arnold@skeeve.atl.ga.us>
* ChangeLog created.
diff --git a/vms/descrip.mms b/vms/descrip.mms
index 6d01aa75..f5de76f3 100644
--- a/vms/descrip.mms
+++ b/vms/descrip.mms
@@ -2,13 +2,15 @@
#
# usage:
# $ MMS /Description=[.vms]Descrip.MMS gawk
+# possibly add `/Macro=(GNUC)' to compile with GNU C,
+# or add `/Macro=(GNUC,DO_GNUC_SETUP)' to compile with GNU C on
+# a system where GCC is not installed as a defined command,
+# or add `/Macro=(VAXC)' to compile with VAX C,
+# or add `/Macro=(VAXC,"CC=cc/VAXC")' to compile with VAX C on
+# a system which has DEC C installed as the default compiler.
#
# gawk.exe :
-# You'll need to modify this Makefile to use gcc or vaxc v2.x rather
-# than vaxc v3.x. Change the CFLAGS macro definition (move '#' from
-# beginning of 2nd alternative to beginning of 1st), and also perhaps
-# enable the following ".first" rule and its associated action. For
-# GNU C, change the LIBS macro definition.
+# This is the default target. DEC C has become the default compiler.
#
# awktab.c :
# If you don't have bison but do have VMS POSIX or DEC/Shell,
@@ -39,33 +41,33 @@ MAKEFILE = $(VMSDIR)Descrip.MMS
# debugging &c !'ccflags' is an escape to allow external compile flags
#CCFLAGS = /noOpt/Debug
-# work within the main directory, even when handling files in [.vms]
-# note: use 2nd variant for either VAX C V2.x or for GNU C
-CFLAGS = /Include=[]/Object=[]/Opt=noInline/Define=("GAWK","HAVE_CONFIG_H") $(CCFLAGS)
-#CFLAGS = /Include=([],$(VMSDIR))/Object=[]/Define=("GAWK","HAVE_CONFIG_H") $(CCFLAGS)
-
-# uncomment this for GNU C
-#CC = gcc
-# beta VAX/VMS -> Alpha/VMS cross-compiler
-#CC = gemcc/Standard=VAXC/G_Float
-# Alpha/VMS
-#CC = cc/Standard=VAXC/G_Float
-
-# uncomment these two lines for GNU C _if_ it's not installed system-wide
-#.first !compiler init, needed if there's no system-wide setup
-# set command gnu_cc:[000000]gcc
-
-# uncomment these three lines for VAX C V2.x
-#.first !compiler init, find all #include files
-# define/nolog vaxc$library sys$library:,sys$disk:$(VMSDIR)
-# define/nolog c$library [],$(VMSDIR)
-#!(it appears that if vaxc$library is defined, then the /Include
-#! qualifier is ignored, making a c$library definition essential)
-
-# run-time libraries; use the 2nd one for GNU C
+# a comma separated list of macros to define
+CDEFS = "GAWK","HAVE_CONFIG_H"
+
+.ifdef GNUC
+# assumes VAX
+CC = gcc
+CFLAGS = /Incl=([],$(VMSDIR))/Obj=[]/Def=($(CDEFS)) $(CCFLAGS)
+LIBS = gnu_cc:[000000]gcclib.olb/Library,sys$library:vaxcrtl.olb/Library
+.ifdef DO_GNUC_SETUP
+# in case GCC command verb needs to be manually defined
+.first
+ set command gnu_cc:[000000]gcc
+.endif !DO_GNUC_SETUP
+.else !!GNUC
+.ifdef VAXC
+# always VAX; version V3.x of VAX C assumed (for V2.x, remove /Opt=noInline)
+CC = cc
+CFLAGS = /Incl=[]/Obj=[]/Opt=noInline/Def=($(CDEFS)) $(CCFLAGS)
LIBS = sys$share:vaxcrtl.exe/Shareable
-#LIBS = gnu_cc:[000000]gcclib.olb/Library,sys$library:vaxcrtl.olb/Library
-#LIBS = # DECC$SHR instead of VAXCRTL; for Alpha/VMS (or VMS V6.x?)
+.else !!VAXC
+# neither GNUC nor VAXC, assume DECC (same for either VAX or Alpha)
+CC = cc/DECC/Prefix=All
+CFLAGS = /Incl=[]/Obj=[]/Def=($(CDEFS)) $(CCFLAGS)
+LIBS = # DECC$SHR instead of VAXCRTL, no special link option needed
+.endif !VAXC
+.endif !GNUC
+
PARSER = bison
PARSERINIT = set command gnu_bison:[000000]bison
@@ -93,9 +95,9 @@ AWKOBJS = array.obj,builtin.obj,eval.obj,field.obj,gawkmisc.obj,\
ALLOBJS = $(AWKOBJS),awktab.obj
-# GNUOBJS
-# GNU stuff that gawk uses as library routines.
-GNUOBJS = getopt.obj,getopt1.obj,regex.obj,dfa.obj,$(ALLOCA)
+# LIBOBJS
+# GNU and other stuff that gawk uses as library routines.
+LIBOBJS = getopt.obj,getopt1.obj,regex.obj,dfa.obj,random.obj,$(ALLOCA)
# VMSOBJS
# VMS specific stuff
@@ -110,9 +112,9 @@ SRC = array.c,builtin.c,eval.c,field.c,gawkmisc.c,io.c,main.c,\
ALLSRC= $(SRC),awktab.c
-AWKSRC= awk.h,awk.y,$(ALLSRC),patchlevel.h,protos.h
+AWKSRC= awk.h,awk.y,$(ALLSRC),patchlevel.h,protos.h,random.h
-GNUSRC = alloca.c,dfa.c,dfa.h,regex.c,regex.h,getopt.h,getopt.c,getopt1.c
+LIBSRC = alloca.c,dfa.c,dfa.h,regex.c,regex.h,getopt.h,getopt.c,getopt1.c,random.c
VMSSRCS = $(VMSDIR)gawkmisc.vms,$(VMSDIR)vms_misc.c,$(VMSDIR)vms_popen.c,\
$(VMSDIR)vms_fwrite.c,$(VMSDIR)vms_args.c,$(VMSDIR)vms_gawk.c,\
@@ -126,7 +128,7 @@ DOCS= $(DOCDIR)gawk.1,$(DOCDIR)gawk.texi,$(DOCDIR)texinfo.tex
# Release of gawk
REL=3.0
-PATCHLVL=0
+PATCHLVL=1
# generic target
all : gawk
@@ -137,19 +139,19 @@ gawk : gawk.exe
$(ECHO) " GAWK "
# rules to build gawk
-gawk.exe : $(ALLOBJS) $(GNUOBJS) $(VMSOBJS) gawk.opt
+gawk.exe : $(ALLOBJS) $(LIBOBJS) $(VMSOBJS) gawk.opt
$(LINK) $(LINKFLAGS) gawk.opt/options
gawk.opt : $(MAKEFILE) # create linker options file
open/write opt gawk.opt ! ~ 'cat <<close >gawk.opt'
- write opt "! GAWK -- Gnu AWK"
+ write opt "! GAWK -- GNU awk"
@ write opt "$(ALLOBJS)"
- @ write opt "$(GNUOBJS)"
+ @ write opt "$(LIBOBJS)"
@ write opt "$(VMSOBJS)"
- @ write opt "$(LIBS)"
- @ write opt "psect_attr=environ,noshr !extern [noshare] char **"
- @ write opt "stack=48 !preallocate more pages (default is 20)"
- @ write opt "iosegment=128 !ditto (default is 32)"
+ @ write opt "psect_attr=environ,noshr !extern [noshare] char **"
+ @ write opt "stack=48 !preallocate more pages (default is 20)"
+ @ write opt "iosegment=128 !ditto (default is 32)"
+ write opt "$(LIBS)"
write opt "identification=""V$(REL).$(PATCHLVL)"""
close opt
@@ -163,9 +165,11 @@ $(VMSCODE) : awk.h config.h $(VMSDIR)vms.h
gawkmisc.obj : gawkmisc.c $(VMSDIR)gawkmisc.vms
-$(ALLOBJS) : awk.h dfa.h regex.h config.h
-getopt.obj : getopt.h
-getopt1.obj : getopt.h
+$(ALLOBJS) : awk.h dfa.h regex.h config.h $(VMSDIR)redirect.h
+getopt.obj : getopt.h config.h $(VMSDIR)redirect.h
+getopt1.obj : getopt.h config.h $(VMSDIR)redirect.h
+random.obj : random.h
+builtin.obj : random.h
main.obj : patchlevel.h
awktab.obj : awk.h awktab.c
@@ -184,8 +188,8 @@ config.h : $(VMSDIR)vms-conf.h
copy $< $@
# Alloca - C simulation
-alloca.obj : alloca.c
- $(CC) $(CFLAGS) /define=("STACK_DIRECTION=(-1)","exit=vms_exit") $<
+alloca.obj : alloca.c config.h $(VMSDIR)redirect.h
+ $(CC) $(CFLAGS) /define=($(CDEFS),"STACK_DIRECTION=(-1)","exit=vms_exit") $<
$(VMSCMD) : $(VMSDIR)gawk.cld
set command $(CLDFLAGS)/object=$@ $<
@@ -206,6 +210,8 @@ spotless : clean tidy
- delete gawk.dvi;*,gawk.exe;*,[.support]texindex.exe;*
#
+# note: this is completely out of date
+#
# build gawk.dvi from within the 'support' subdirectory
#
gawk.dvi : [.support]texindex.exe gawk.texi
@@ -223,6 +229,10 @@ gawk.dvi : [.support]texindex.exe gawk.texi
@ rename/new_vers gawk.dvi [-]*.*
@ set default [-]
+#
+# note: besides being out of date, this assumes VAX C
+#
+
[.support]texindex.exe : [.support]texindex.c
@ set default [.support]
$(CC) /noOpt/noList/Define=("lines=tlines") texindex.c
diff --git a/vms/gawkmisc.vms b/vms/gawkmisc.vms
index 9d58b51e..95983351 100644
--- a/vms/gawkmisc.vms
+++ b/vms/gawkmisc.vms
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-1995 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-1996 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Progamming Language.
@@ -25,7 +25,7 @@
char quote = '\'';
char *defpath = DEFPATH;
-char envsep = ':';
+char envsep = ',';
/* gawk_name --- pull out the "gawk" part from how the OS called us */
diff --git a/vms/redirect.h b/vms/redirect.h
index 74fe622e..ce58901d 100644
--- a/vms/redirect.h
+++ b/vms/redirect.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 88, 89, 91-93, 1995 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 88, 89, 91-93, 1996 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -40,6 +40,16 @@
#define regexec gnu_regexec
#define regfree gnu_regfree
#define regerror gnu_regerror
+#ifndef VMS_POSIX
+#define strftime gnu_strftime /* always use missing/strftime.c */
+#endif
+
+#ifdef STDC_HEADERS
+/* This is for getopt.c and alloca.c (compiled with HAVE_CONFIG_H defined),
+ to prevent diagnostics about various implicitly declared functions. */
+#include <stdlib.h>
+#include <string.h>
+#endif
#else /* awk.h, not POSIX */
diff --git a/vms/vms-conf.h b/vms/vms-conf.h
index d1593e6a..b8b98de1 100644
--- a/vms/vms-conf.h
+++ b/vms/vms-conf.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 1991, 1992, 1995 the Free Software Foundation, Inc.
+ * Copyright (C) 1991, 1992, 1995, 1996 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -128,6 +128,13 @@
#ifdef __DECC
/* DEC C implies DECC$SHR, which doesn't have the %g problem of VAXCRTL */
#undef GFMT_WORKAROUND
+ /* DEC C V5.x introduces incompatibilities with prior porting efforts */
+#define _DECC_V4_SOURCE
+#define __SOCKET_TYPEDEFS
+#if __VMS_VER >= 60200000
+# undef __VMS_VER
+# define __VMS_VER 60100000
+#endif
#endif
/*
@@ -154,15 +161,6 @@
#undef REGEX_MALLOC /* use true alloca() in regex.c */
#endif
-#ifndef HAVE_STRFTIME
-/*
- * Always use the version of strftime() in missing/strftime.c instead of
- * the [as yet undocumented/unsupported] one in VAXCRTL. Renaming it here
- * guarantees that it won't clash with the library routine.
- */
-#define strftime gnu_strftime
-#endif
-
#define IN_CONFIG_H
#include "vms/redirect.h"
#undef IN_CONFIG_H
diff --git a/vms/vms.h b/vms/vms.h
index 4fc16f50..74fba00c 100644
--- a/vms/vms.h
+++ b/vms/vms.h
@@ -39,13 +39,13 @@
#define PSL$C_USER 3 /* user mode */
#endif
-#if !defined(_TYPES_) || !defined(__GNUC__)
-typedef unsigned long u_long;
-typedef unsigned short u_short;
-#endif
+/* note: `ulong' and `u_long' end up conflicting with various header files */
+typedef unsigned long U_Long;
+typedef unsigned short U_Short;
+
typedef struct _dsc { int len; char *adr; } Dsc; /* limited string descriptor */
/* standard VMS itemlist-3 structure */
-typedef struct _itm { u_short len, code; void *buffer; u_short *retlen; } Itm;
+typedef struct _itm { U_Short len, code; void *buffer; U_Short *retlen; } Itm;
#define vmswork(sts) ((sts)&1)
#define vmsfail(sts) (!vmswork(sts))
@@ -53,23 +53,26 @@ typedef struct _itm { u_short len, code; void *buffer; u_short *retlen; } Itm;
#define Descrip(strdsc,strbuf) Dsc strdsc = {sizeof strbuf - 1, (char *)strbuf}
extern int shell$is_shell P((void));
-extern u_long LIB$FIND_FILE P((const Dsc *, Dsc *, void *, ...));
-extern u_long LIB$FIND_FILE_END P((void *));
+extern U_Long lib$find_file P((const Dsc *, Dsc *, void *, ...));
+extern U_Long lib$find_file_end P((void *));
#ifndef NO_TTY_FWRITE
-extern u_long LIB$GET_EF P((long *));
-extern u_long SYS$ASSIGN P((const Dsc *, short *, long, const Dsc *));
-extern u_long SYS$DASSGN P((short));
-extern u_long SYS$QIO P((u_long, u_long, u_long, void *, void (*)(), u_long,
- const char *, int, int, u_long, int, int));
-extern u_long SYS$SYNCH P((long, void *));
+extern U_Long lib$get_ef P((long *));
+extern U_Long sys$assign P((const Dsc *, short *, long, const Dsc *));
+extern U_Long sys$dassgn P((short));
+extern U_Long sys$qio P((U_Long, U_Long, U_Long, void *,
+ void (*)(U_Long), U_Long,
+ const char *, int, int, U_Long, int, int));
+extern U_Long sys$synch P((long, void *));
#endif /*!NO_TTY_FWRITE*/
+extern U_Long lib$spawn P((const Dsc *,const Dsc *,const Dsc *,
+ const U_Long *,const Dsc *,U_Long *,U_Long *,...));
/* system services for logical name manipulation */
-extern u_long SYS$TRNLNM P((const u_long *,const Dsc *,const Dsc *,
+extern U_Long sys$trnlnm P((const U_Long *,const Dsc *,const Dsc *,
const unsigned char *,Itm *));
-extern u_long SYS$CRELNM P((const u_long *,const Dsc *,const Dsc *,
+extern U_Long sys$crelnm P((const U_Long *,const Dsc *,const Dsc *,
const unsigned char *,const Itm *));
-extern u_long SYS$CRELOG P((int,const Dsc *,const Dsc *,unsigned char));
-extern u_long SYS$DELLNM P((const Dsc *,const Dsc *,const unsigned char *));
+extern U_Long sys$crelog P((int,const Dsc *,const Dsc *,unsigned char));
+extern U_Long sys$dellnm P((const Dsc *,const Dsc *,const unsigned char *));
extern void v_add_arg P((int, const char *));
extern void vms_exit P((int));
@@ -78,7 +81,7 @@ extern char *vms_strdup P((const char *));
extern int vms_devopen P((const char *,int));
extern int vms_execute P((const char *, const char *, const char *));
extern int vms_gawk P((void));
-extern u_long Cli_Present P((const char *));
-extern u_long Cli_Get_Value P((const char *, char *, int));
-extern u_long Cli_Parse_Command P((const void *, const char *));
+extern U_Long Cli_Present P((const char *));
+extern U_Long Cli_Get_Value P((const char *, char *, int));
+extern U_Long Cli_Parse_Command P((const void *, const char *));
diff --git a/vms/vms_args.c b/vms/vms_args.c
index 945d7bf6..5371dfb8 100644
--- a/vms/vms_args.c
+++ b/vms/vms_args.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 1991-1995 the Free Software Foundation, Inc.
+ * Copyright (C) 1991-1996 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -92,7 +92,7 @@
void v_add_arg(int, const char *);
static char *skipblanks(const char *);
static void vms_expand_wildcards(const char *);
-static u_long vms_define(const char *, const char *);
+static U_Long vms_define(const char *, const char *);
static char *t_strstr(const char *, const char *);
#define strstr t_strstr /* strstr() missing from vaxcrtl for V4.x */
@@ -302,7 +302,7 @@ ordinary_arg:
static void
vms_expand_wildcards( const char *prospective_filespec )
{
- char *p, spec_buf[255+1], res_buf[255+1], *strstr();
+ char *p, spec_buf[255+1], res_buf[255+1];
Dsc spec, result;
void *context;
register int len = strlen(prospective_filespec);
@@ -325,12 +325,12 @@ vms_expand_wildcards( const char *prospective_filespec )
*/
len = -1; /* overload 'len' with flag value */
context = NULL; /* init */
- while (vmswork(LIB$FIND_FILE(&spec, &result, &context))) {
+ while (vmswork(lib$find_file(&spec, &result, &context))) {
for (len = sizeof(res_buf)-1; len > 0 && res_buf[len-1] == ' '; len--) ;
res_buf[len] = '\0'; /* terminate after discarding trailing blanks */
v_add_arg(v_argc++, strdup(res_buf)); /* store result */
}
- (void)LIB$FIND_FILE_END(&context);
+ (void)lib$find_file_end(&context);
if (len >= 0) /* (still -1 => never entered loop) */
--v_argc; /* undo final post-increment */
return;
@@ -376,12 +376,12 @@ skipblanks( const char *ptr )
}
/* vms_define() - assign a value to a logical name [define/process/user_mode] */
-static u_long
+static U_Long
vms_define( const char *log_name, const char *trans_val )
{
Dsc log_dsc;
static Descrip(lnmtable,"LNM$PROCESS_TABLE");
- static u_long attr = LNM$M_CONFINE;
+ static U_Long attr = LNM$M_CONFINE;
static Itm itemlist[] = { {0,LNM$_STRING,0,0}, {0,0} };
static unsigned char acmode = PSL$C_USER;
unsigned len = strlen(log_name);
@@ -395,10 +395,11 @@ vms_define( const char *log_name, const char *trans_val )
log_dsc.len = len;
itemlist[0].buffer = (char *)trans_val;
itemlist[0].len = strlen(trans_val);
- return SYS$CRELNM(&attr, &lnmtable, &log_dsc, &acmode, itemlist);
+ return sys$crelnm(&attr, &lnmtable, &log_dsc, &acmode, itemlist);
}
/* t_strstr -- strstr() substitute; search 'str' for 'sub' */
+/* [strstr() was not present in VAXCRTL prior to VMS V5.0] */
static char *t_strstr ( const char *str, const char *sub )
{
register const char *s0, *s1, *s2;
diff --git a/vms/vms_cli.c b/vms/vms_cli.c
index 2f475b11..a9386216 100644
--- a/vms/vms_cli.c
+++ b/vms/vms_cli.c
@@ -11,21 +11,21 @@
#include <string.h>
#endif
-extern u_long CLI$PRESENT(const Dsc *);
-extern u_long CLI$GET_VALUE(const Dsc *, Dsc *, short *);
-extern u_long CLI$DCL_PARSE(const Dsc *, const void *, ...);
-extern u_long SYS$CLI(void *, ...);
-extern u_long SYS$FILESCAN(const Dsc *, void *, long *);
-extern void *LIB$ESTABLISH(u_long (*handler)(void *, void *));
-extern u_long LIB$SIG_TO_RET(void *, void *); /* condition handler */
+extern U_Long CLI$PRESENT(const Dsc *);
+extern U_Long CLI$GET_VALUE(const Dsc *, Dsc *, short *);
+extern U_Long CLI$DCL_PARSE(const Dsc *, const void *, ...);
+extern U_Long sys$cli(void *, ...);
+extern U_Long sys$filescan(const Dsc *, void *, long *);
+extern void *lib$establish(U_Long (*handler)(void *, void *));
+extern U_Long lib$sig_to_ret(void *, void *); /* condition handler */
/* Cli_Present() - call CLI$PRESENT to determine whether a parameter or */
/* qualifier is present on the [already parsed] command line */
-u_long
+U_Long
Cli_Present( const char *item )
{
Dsc item_dsc;
- (void)LIB$ESTABLISH(LIB$SIG_TO_RET);
+ (void)lib$establish(lib$sig_to_ret);
item_dsc.len = strlen(item_dsc.adr = (char *)item);
return CLI$PRESENT(&item_dsc);
@@ -33,13 +33,13 @@ Cli_Present( const char *item )
/* Cli_Get_Value() - call CLI$GET_VALUE to retreive the value of a */
/* parameter or qualifier from the command line */
-u_long
+U_Long
Cli_Get_Value( const char *item, char *result, int size )
{
Dsc item_dsc, res_dsc;
- u_long sts;
+ U_Long sts;
short len = 0;
- (void)LIB$ESTABLISH(LIB$SIG_TO_RET);
+ (void)lib$establish(lib$sig_to_ret);
item_dsc.len = strlen(item_dsc.adr = (char *)item);
res_dsc.len = size, res_dsc.adr = result;
@@ -52,20 +52,20 @@ Cli_Get_Value( const char *item, char *result, int size )
/* retreive the actual command line (which might be */
/* "run prog" or "mcr prog [params]") and then call */
/* CLI$DCL_PARSE to parse it using specified tables */
-u_long
+U_Long
Cli_Parse_Command( const void *cmd_tables, const char *cmd_verb )
{
struct { short len, code; void *adr; } fscn[2];
struct { char rqtype, rqindx, rqflags, rqstat; unsigned :32;
Dsc rdesc; unsigned :32; unsigned :32; unsigned :32; } cmd;
- u_long sts;
+ U_Long sts;
int ltmp;
char longbuf[2600];
- (void)LIB$ESTABLISH(LIB$SIG_TO_RET);
+ (void)lib$establish(lib$sig_to_ret);
memset(&cmd, 0, sizeof cmd);
cmd.rqtype = CLI$K_GETCMD; /* command line minus the verb */
- sts = SYS$CLI( &cmd, (void *)0, (void *)0); /* get actual command line */
+ sts = sys$cli(&cmd, (void *)0, (void *)0); /* get actual command line */
if (vmswork(sts)) { /* ok => cli available & verb wasn't "RUN" */
/* invoked via symbol => have command line (which might be empty) */
@@ -74,7 +74,7 @@ Cli_Parse_Command( const void *cmd_tables, const char *cmd_verb )
/* need to strip image name from MCR invocation */
memset(fscn, 0, sizeof fscn);
fscn[0].code = FSCN$_FILESPEC; /* full file specification */
- (void)SYS$FILESCAN( &cmd.rdesc, fscn, (long *)0);
+ (void)sys$filescan(&cmd.rdesc, fscn, (long *)0);
cmd.rdesc.len -= fscn[0].len; /* shrink size */
cmd.rdesc.adr += fscn[0].len; /* advance ptr */
}
diff --git a/vms/vms_fwrite.c b/vms/vms_fwrite.c
index ab9bbbd0..8f0ebcab 100644
--- a/vms/vms_fwrite.c
+++ b/vms/vms_fwrite.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1991-1995 the Free Software Foundation, Inc.
+ * Copyright (C) 1991-1996 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -85,20 +85,20 @@ tty_fwrite( const void *buf, size_t size, size_t number, FILE *file )
char devnam[255+1];
fgetname(file, devnam); /* get 'file's name */
device.len = strlen(device.adr = devnam); /* create descriptor */
- if (vmswork(SYS$ASSIGN(&device, &chan, 0, (Dsc *)0))) {
+ if (vmswork(sys$assign(&device, &chan, 0, (Dsc *)0))) {
/* get an event flag; use #0 if problem */
- if (evfn == -1 && vmsfail(LIB$GET_EF(&evfn))) evfn = 0;
+ if (evfn == -1 && vmsfail(lib$get_ef(&evfn))) evfn = 0;
} else chan = 0; /* $ASSIGN failed */
}
/* store channel for later use; -1 => don't repeat failed init attempt */
channel[file_num] = (chan > 0 ? chan : -1);
}
if (chan > 0) { /* chan > 0 iff 'file' is a terminal */
- struct _iosbw { u_short status, count; u_long rt_kludge; } iosb;
- register u_long sts = 1;
+ struct _iosbw { U_Short status, count; U_Long rt_kludge; } iosb;
+ register U_Long sts = 1;
register char *pt = (char *)buf;
register int offset, pos, count = size * number;
- u_long cc_fmt, io_func = IO$_WRITEVBLK;
+ U_Long cc_fmt, io_func = IO$_WRITEVBLK;
int extra = 0;
result = 0;
if (is_stderr(file_num)) /* if it's SYS$ERROR (stderr)... */
@@ -118,19 +118,19 @@ tty_fwrite( const void *buf, size_t size, size_t number, FILE *file )
else if (pos < count) pos++, cc_fmt |= POSTFIX_CR, extra++;
/* wait for previous write, if any, to complete */
if (pt > (char *)buf) {
- sts = SYS$SYNCH(evfn, &iosb);
+ sts = sys$synch(evfn, &iosb);
if (vmswork(sts)) sts = iosb.status, result += iosb.count;
if (vmsfail(sts)) break;
}
/* queue an asynchronous write */
- sts = SYS$QIO(evfn, chan, io_func, &iosb, (void (*)())0, 0L,
+ sts = sys$qio(evfn, chan, io_func, &iosb, (void (*)(U_Long))0, 0L,
pt, pos, 0, cc_fmt, 0, 0);
if (vmsfail(sts)) break; /*(should never happen)*/
pt += pos, count -= pos;
}
/* wait for last write to complete */
if (pt > (char *)buf && vmswork(sts)) {
- sts = SYS$SYNCH(evfn, &iosb);
+ sts = sys$synch(evfn, &iosb);
if (vmswork(sts)) sts = iosb.status, result += iosb.count;
}
if (vmsfail(sts)) errno = EVMSERR, vaxc$errno = sts;
@@ -199,7 +199,7 @@ tty_fclose( FILE *file )
int file_num = fileno(file);
short chan = file_num < _NFILE ? channel[file_num] : -1;
if (chan > 0)
- (void)SYS$DASSGN(chan); /* deassign the channel (ie, close) */
+ (void)sys$dassgn(chan); /* deassign the channel (ie, close) */
if (file_num < _NFILE)
channel[file_num] = 0; /* clear stale info */
}
diff --git a/vms/vms_gawk.c b/vms/vms_gawk.c
index f65b9cbd..d98bb801 100644
--- a/vms/vms_gawk.c
+++ b/vms/vms_gawk.c
@@ -1,9 +1,9 @@
/*
- * vms_gawk.c -- parse GAWK command line using DCL syntax ]
+ * vms_gawk.c -- parse GAWK command line using DCL syntax
*/
/*
- * Copyright (C) 1991-1993 the Free Software Foundation, Inc.
+ * Copyright (C) 1991-1993, 1996 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -67,7 +67,7 @@ union arg_w_prefix { /* structure used to simplify prepending of "-" */
int
vms_gawk()
{
- u_long sts;
+ U_Long sts;
union arg_w_prefix buf;
char misc_args[10], *misc_argp;
int argc, W_cnt;
diff --git a/vms/vms_misc.c b/vms/vms_misc.c
index 748b3b94..d876534c 100644
--- a/vms/vms_misc.c
+++ b/vms/vms_misc.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1991-1993 the Free Software Foundation, Inc.
+ * Copyright (C) 1991-1993, 1996 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -58,11 +58,12 @@ vms_exit( int final_status )
#ifdef strerror
# undef strerror
#endif
+extern char *strerror P((int,...));
+
/* vms_strerror() -- convert numeric error code into text string */
char *
vms_strerror( int errnum )
{
- extern char *strerror P((int,...));
return ( errnum != EVMSERR ? strerror(errnum)
: strerror(EVMSERR, vaxc$errno) );
}
@@ -169,14 +170,14 @@ vms_devopen( const char *name, int mode )
}
/*
- * VMS has no timezone support.
+ * VMS prior to V7.x has no timezone support unless DECnet/OSI is used.
*/
/* these are global for use by missing/strftime.c */
char *tzname[2] = { "local", "" };
int daylight = 0, timezone = 0, altzone = 0;
-/* dummy to satisfy linker */
-void tzset()
+/* tzset() -- dummy to satisfy linker */
+void tzset(void)
{
return;
}
@@ -184,7 +185,7 @@ void tzset()
/* getpgrp() -- there's no such thing as process group under VMS;
* job tree might be close enough to be useful though.
*/
-int getpgrp()
+int getpgrp(void)
{
return 0;
}
diff --git a/vms/vms_popen.c b/vms/vms_popen.c
index dcd8425b..d92dca90 100644
--- a/vms/vms_popen.c
+++ b/vms/vms_popen.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1991-1993 the Free Software Foundation, Inc.
+ * Copyright (C) 1991-1993, 1996 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -161,7 +161,7 @@ int
vms_execute( const char *command, const char *input, const char *output )
{
Dsc cmd, in, out, *in_p, *out_p;
- u_long sts, cmpltn_sts, LIB$SPAWN();
+ U_Long sts, cmpltn_sts;
cmd.len = strlen(cmd.adr = (char *)command);
if (input)
@@ -174,8 +174,8 @@ vms_execute( const char *command, const char *input, const char *output )
out_p = 0;
push_logicals(); /* guard against user-mode definitions of sys$Xput */
- sts = LIB$SPAWN(&cmd, in_p, out_p, (long *)0,
- (Dsc *)0, (u_long *)0, &cmpltn_sts);
+ sts = lib$spawn(&cmd, in_p, out_p, (U_Long *)0,
+ (Dsc *)0, (U_Long *)0, &cmpltn_sts);
pop_logicals(); /* restore environment */
if (vmswork(sts) && vmsfail(cmpltn_sts)) sts = cmpltn_sts;
@@ -221,14 +221,14 @@ static const Descrip(sys_output,"SYS$OUTPUT");
static const unsigned char acmode = PSL$C_USER; /* only care about user-mode */
/* macros for simplfying the code a bunch */
-#define DelTrans(l) SYS$DELLNM(&lnmtable, (l), &acmode)
-#define GetTrans(l,i) SYS$TRNLNM((u_long *)0, &lnmtable, (l), &acmode, (i))
-#define SetTrans(l,i) SYS$CRELNM((u_long *)0, &lnmtable, (l), &acmode, (i))
+#define DelTrans(l) sys$dellnm(&lnmtable, (l), &acmode)
+#define GetTrans(l,i) sys$trnlnm((U_Long *)0, &lnmtable, (l), &acmode, (i))
+#define SetTrans(l,i) sys$crelnm((U_Long *)0, &lnmtable, (l), &acmode, (i))
/* itemlist manipulation macros; separate versions for aggregate and scalar */
#define SetItmA(i,c,p,r) ((i).code = (c), (i).len = sizeof (p),\
- (i).buffer = (p), (i).retlen = (u_short *)(r))
+ (i).buffer = (p), (i).retlen = (U_Short *)(r))
#define SetItmS(i,c,p) ((i).code = (c), (i).len = sizeof *(p),\
- (i).buffer = (p), (i).retlen = (u_short *)0)
+ (i).buffer = (p), (i).retlen = (U_Short *)0)
#define EndItm0(i) ((i).code = (i).len = 0)
/* translate things once, then hold the results here for multiple re-use */
@@ -282,10 +282,10 @@ save_translation( const Dsc *logname )
itmlst_size = (3 * (max_trans_indx + 1) + 1) * sizeof(Itm);
emalloc(itmlst, Itm *, itmlst_size, "save_translation");
for (i = 0; i <= max_trans_indx; i++) {
- struct def { u_long indx, attr; u_short len;
+ struct def { U_Long indx, attr; U_Short len;
char str[LNM$C_NAMLENGTH], eos; } *wrk;
emalloc(wrk, struct def *, sizeof (struct def), "save_translation");
- wrk->indx = (u_long)i; /* this one's an input value for $trnlnm */
+ wrk->indx = (U_Long)i; /* this one's an input value for $trnlnm */
SetItmS(itmlst[3*i+0], LNM$_INDEX, &wrk->indx);
SetItmS(itmlst[3*i+1], LNM$_ATTRIBUTES, &wrk->attr), wrk->attr = 0;
SetItmA(itmlst[3*i+2], LNM$_STRING, &wrk->str, &wrk->len), wrk->len = 0;
@@ -298,7 +298,7 @@ save_translation( const Dsc *logname )
*/
if (vmswork(GetTrans(logname, itmlst))) {
for (i = 0, j = -1; i <= max_trans_indx; i++) {
- u_long *attr_p;
+ U_Long *attr_p;
attr_p = itmlst[3*i+1].buffer; /* copy (void *) to true type */
if (*attr_p & LNM$M_EXISTS) {
*attr_p &= ~LNM$M_EXISTS; /* must clear this bit */
@@ -307,7 +307,7 @@ save_translation( const Dsc *logname )
itmlst[3*j+2] = itmlst[3*i+2];
if (itmlst[3*j+2].retlen) { /* fixup buffer length */
itmlst[3*j+2].len = *itmlst[3*j+2].retlen;
- itmlst[3*j+2].retlen = (u_short *)0;
+ itmlst[3*j+2].retlen = (U_Short *)0;
}
}
}
@@ -322,12 +322,12 @@ static void
restore_translation( const Dsc *logname, const Itm *itemlist )
{
Dsc trans_val;
- u_long *attr_p;
+ U_Long *attr_p;
# define LOG_PROCESS_TABLE 2 /* <obsolete> */
# define LOG_USERMODE PSL$C_USER
/* assert( itemlist[1].code == LNM$_ATTRIBUTES ); */
- attr_p = itemlist[1].buffer; /* copy (void *) to (u_long *) */
+ attr_p = itemlist[1].buffer; /* copy (void *) to (U_Long *) */
if (*attr_p & LNM$M_CRELOG) { /* check original creation method */
/* $crelog values can have only one translation;
so it'll be the first string entry in the itemlist.
@@ -335,7 +335,7 @@ restore_translation( const Dsc *logname, const Itm *itemlist )
/* assert( itemlist[2].code == LNM$_STRING ); */
trans_val.adr = itemlist[2].buffer;
trans_val.len = itemlist[2].len;
- (void) SYS$CRELOG(LOG_PROCESS_TABLE, logname, &trans_val, LOG_USERMODE);
+ (void) sys$crelog(LOG_PROCESS_TABLE, logname, &trans_val, LOG_USERMODE);
} else {
/* $crelnm definition; itemlist could specify multiple translations,
but has already been setup properly for use as-is.
diff --git a/vms/vmsbuild.com b/vms/vmsbuild.com
index 40a9307c..04a54792 100644
--- a/vms/vmsbuild.com
+++ b/vms/vmsbuild.com
@@ -4,31 +4,50 @@ $! gawk 2.13 revised, Jun'91
$! gawk 2.14 revised, Sep'92
$! gawk 2.15 revised, Oct'93
$! gawk 3.0 revised, Dec'95
+$! gawk 3.0.1 revised, Nov'96
$!
$ REL = "3.0" !release version number
-$ PATCHLVL = "0"
+$ PATCHLVL = "1"
$!
-$! [ remove "/optimize=noinline" for VAX C V2.x or DEC C ]
-$! [ add "/standard=VAXC" for DEC C and "/g_float" for Alpha ]
-$ if f$type(cc) .nes."STRING" then cc := cc/nolist/optimize=noinline
-$ if f$type(link).nes."STRING" then link := link/nomap
-$ if f$type(set_command).nes."STRING" then set_command := set command
$!
-$ cc := 'cc'/Include=[]/Define="(""GAWK"",""HAVE_CONFIG_H"")"
-$ libs = "sys$share:vaxcrtl.exe/Shareable"
-$
-$! uncomment for DEC C
-$ ! libs = ""
-$
-$! uncomment the next two lines for VAX C V2.x
-$ ! define vaxc$library sys$library:,sys$disk:[.vms]
-$ ! define c$library [],[.vms]
+$ CCFLAGS = "/noList" ! "/noOpt/Debug"
+$ CDEFS = "GAWK,HAVE_CONFIG_H"
$!
-$! uncomment next two lines for GNU C
-$ ! cc := gcc/Include=([],[.vms])/Define="(""GAWK"",""HAVE_CONFIG_H"")"
-$ ! libs = "gnu_cc:[000000]gcclib.olb/Library,sys$library:vaxcrtl.olb/Library"
+$ if p1.eqs."" then p1 = "DECC" !default compiler
+$ if p1.eqs."GNUC"
+$ then
+$! assumes VAX
+$ CC = "gcc"
+$ if f$type(gcc).eqs."STRING" then CC = gcc
+$ CFLAGS = "/Incl=([],[.vms])/Obj=[]/Def=(''CDEFS')''CCFLAGS'"
+$ LIBS = "gnu_cc:[000000]gcclib.olb/Library,sys$library:vaxcrtl.olb/Library"
+$ if p2.eqs."DO_GNUC_SETUP" then set command gnu_cc:[000000]gcc
+$ else !!GNUC
+$ if p1.eqs."VAXC"
+$ then
+$! always VAX; version V3.x of VAX C assumed (for V2.x, remove /Opt=noInline)
+$ CC = "cc"
+$ if f$trnlnm("DECC$CC_DEFAULT").nes."" then CC = "cc/VAXC"
+$ CFLAGS = "/Incl=[]/Obj=[]/Opt=noInline/Def=(''CDEFS')''CCFLAGS'"
+$ LIBS = "sys$share:vaxcrtl.exe/Shareable"
+$ else !!VAXC
+$! neither GNUC nor VAXC, assume DECC (same for either VAX or Alpha)
+$ CC = "cc/DECC/Prefix=All"
+$ CFLAGS = "/Incl=[]/Obj=[]/Def=(''CDEFS')''CCFLAGS'"
+$ LIBS = "" ! DECC$SHR instead of VAXCRTL, no special link option needed
+$ endif !VAXC
+$ endif !GNUC
$!
-$ if f$search("config.h").eqs."" then copy [.vms]vms-conf.h []config.h
+$ cc = CC + CFLAGS
+$ show symbol cc
+$!
+$ if f$search("config.h").nes."" then -
+ if f$cvtime(f$file_attr("config.h","RDT")).ges.-
+ f$cvtime(f$file_attr("[.vms]vms-conf.h","RDT")) then goto config_ok
+$ v = f$verify(1)
+$ copy [.vms]vms-conf.h []config.h
+$! 'f$verify(v)'
+$config_ok:
$ if f$search("awktab.c").nes."" then goto awktab_ok
$ write sys$output " You must process `awk.y' with ""yacc"" or ""bison"""
$ if f$search("awk_tab.c").nes."" then - !bison was run manually
@@ -37,6 +56,7 @@ $ if f$search("ytab.c").nes."" .or. f$search("y_tab.c").nes."" then - !yacc
write sys$output " or else rename `ytab.c' or `y_tab.c' to `awktab.c'."
$ exit
$awktab_ok:
+$ v = f$verify(1)
$ cc array.c
$ cc builtin.c
$ cc eval.c
@@ -54,20 +74,23 @@ $ cc getopt.c
$ cc getopt1.c
$ cc regex.c
$ cc dfa.c
-$ cc/define=("STACK_DIRECTION=(-1)","exit=vms_exit") alloca.c
+$ cc random.c
+$ cc/Define=('CDEFS',"STACK_DIRECTION=(-1)","exit=vms_exit") alloca.c
$ cc [.vms]vms_misc.c
$ cc [.vms]vms_popen.c
$ cc [.vms]vms_fwrite.c
$ cc [.vms]vms_args.c
$ cc [.vms]vms_gawk.c
$ cc [.vms]vms_cli.c
-$ set_command/object=[]gawk_cmd.obj [.vms]gawk.cld
+$ set command/Object=[]gawk_cmd.obj [.vms]gawk.cld
+$! 'f$verify(v)'
$!
+$ close/noLog Fopt
$ create gawk.opt
-! GAWK -- Gnu AWK
+! GAWK -- GNU awk
array.obj,builtin.obj,eval.obj,field.obj,gawkmisc.obj
io.obj,main.obj,missing.obj,msg.obj,node.obj,re.obj,version.obj,awktab.obj
-getopt.obj,getopt1.obj,regex.obj,dfa.obj,alloca.obj
+getopt.obj,getopt1.obj,regex.obj,dfa.obj,random.obj,alloca.obj
[]vms_misc.obj,vms_popen.obj,vms_fwrite.obj,vms_args.obj
[]vms_gawk.obj,vms_cli.obj,gawk_cmd.obj
psect_attr=environ,noshr !extern [noshare] char **
@@ -78,4 +101,7 @@ $ write Fopt libs
$ write Fopt "identification=""V''REL'.''PATCHLVL'"""
$ close Fopt
$!
+$ v = f$verify(1)
$ link/exe=gawk.exe gawk.opt/options
+$! 'f$verify(v)'
+$ exit
diff --git a/vms/vmstest.com b/vms/vmstest.com
new file mode 100644
index 00000000..59a3cd67
--- /dev/null
+++ b/vms/vmstest.com
@@ -0,0 +1,587 @@
+$! vmstest.com -- DCL script to perform test/Makefile actions for VMS
+$!
+$! Usage:
+$! $ set default [-.test]
+$! $ @[-.vms]vmstest.com bigtest
+$! This assumes that newly built gawk.exe is in the next directory up.
+$!
+$ echo = "write sys$output"
+$ cmp = "diff/Output=_NL:/Maximum=1"
+$ rm = "delete/noConfirm/noLog"
+$ gawk = "$sys$disk:[-]gawk"
+$ AWKPATH_srcdir = "define/User AWKPATH sys$disk:[]"
+$
+$ if p1.eqs."" then p1 = "bigtest"
+$ gosub 'p1'
+$ if p2.nes."" then gosub 'p2'
+$ if p3.nes."" then gosub 'p3'
+$ if p4.nes."" then gosub 'p4'
+$ if p5.nes."" then gosub 'p5'
+$ if p6.nes."" then gosub 'p6'
+$ if p7.nes."" then gosub 'p7'
+$ if p8.nes."" then gosub 'p8'
+$ exit
+$
+$all:
+$bigtest: bigtest_list = "basic unix_tests gawk_ext"
+$ echo "bigtest"
+$bigtest_loop: bigtest_test = f$element(0," ",bigtest_list)
+$ bigtest_list = bigtest_list - bigtest_test - " "
+$ if bigtest_test.nes." " then gosub 'bigtest_test'
+$ if bigtest_list.nes."" then goto bigtest_loop
+$ return
+$
+$basic: basic_list = "msg swaplns messages argarray longwrds" -
+ + " getline fstabplus compare arrayref rs fsrs rand" -
+ + " fsbs negexp asgext anchgsub splitargv awkpath nfset" -
+ + " reparse convfmt arrayparm paramdup nonl defref" -
+ + " nofmtch litoct resplit rswhite prmarscl sclforin" -
+ + " sclifin intprec childin noeffect numsubstr pcntplus" -
+ + " prmreuse math fldchg fldchgnf reindops sprintfc" -
+ + " backgsub tweakfld clsflnam mmap8k fnarray dynlj" -
+ + " substr eofsplit prt1eval splitwht back89 tradanch"
+$ echo "basic"
+$basic_loop: basic_test = f$element(0," ",basic_list)
+$ basic_list = basic_list - basic_test - " "
+$ if basic_test.nes." " then gosub 'basic_test'
+$ if basic_list.nes."" then goto basic_loop
+$ return
+$
+$unix_tests: unix_tst_list = "poundbang fflush getlnhd"
+$ echo "unix_tests"
+$unix_tst_loop: unix_tst_test = f$element(0," ",unix_tst_list)
+$ unix_tst_list = unix_tst_list - unix_tst_test - " "
+$ if unix_tst_test.nes." " then gosub 'unix_tst_test'
+$ if unix_tst_list.nes."" then goto unix_tst_loop
+$ return
+$
+$gawk_ext: gawk_ext_list = "fieldwdth ignrcase posix manyfiles" -
+ + " igncfs argtest badargs strftime gensub gnureops"
+$ echo "gawk_ext (gawk.extensions)"
+$gawk_ext_loop: gawk_ext_test = f$element(0," ",gawk_ext_list)
+$ gawk_ext_list = gawk_ext_list - gawk_ext_test - " "
+$ if gawk_ext_test.nes." " then gosub 'gawk_ext_test'
+$ if gawk_ext_list.nes."" then goto gawk_ext_loop
+$ return
+$
+$extra: extra_list = "regtest inftest"
+$ echo "extra"
+$ gosub "regtest"
+$ gosub "inftest"
+$ return
+$
+$poundbang:
+$ echo "poundbang: useless for VMS, so skipped"
+$ return
+$
+$msg:
+$ echo "Any output from ""DIFF"" is bad news, although some differences"
+$ echo "in floating point values are probably benign -- in particular,"
+$ echo "some systems may omit a leading zero and the floating point"
+$ echo "precision may lead to slightly different output in a few cases."
+$ return
+$
+$swaplns: echo "swaplns"
+$ gawk -f swaplns.awk swaplns.in >tmp.
+$ cmp swaplns.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$messages: echo "messages"
+$ set noOn
+$ gawk -f messages.awk > out2 >& out3
+$ cmp out1.ok out1.
+$ if $status then rm out1.;
+$ cmp out2.ok out2.
+$ if $status then rm out2.;
+$ cmp out3.ok out3.
+$ if $status then rm out3.;
+$ set On
+$ return
+$
+$argarray: echo "argarray"
+$ define/User TEST "test" !this is useless...
+$ gawk -f argarray.awk ./argarray.in - >tmp.
+just a test
+$ cmp argarray.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fstabplus: echo "fstabplus"
+$ gawk -f fstabplus.awk >tmp.
+1 2
+$ cmp fstabplus.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fsrs: echo "fsrs"
+$ gawk -f fsrs.awk fsrs.in >tmp.
+$ cmp fsrs.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$igncfs: echo "igncfs"
+$ gawk -f igncfs.awk igncfs.in >tmp.
+$ cmp igncfs.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$longwrds: echo "longwrds"
+$ gawk -f longwrds.awk manpage >tmp.too
+$ sort tmp.too tmp.
+$ cmp longwrds.ok tmp.
+$ if $status then rm tmp.;,tmp.too;
+$ return
+$
+$fieldwdth: echo "fieldwdth"
+$ gawk -v "FIELDWIDTHS=2 3 4" "{ print $2}" >tmp.
+123456789
+$ cmp fieldwdth.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$ignrcase: echo "ignrcase"
+$ gawk -v "IGNORECASE=1" "{ sub(/y/, """"); print}" >tmp.
+xYz
+$ cmp ignrcase.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$regtest:
+$ if f$search("regtest.com").eqs.""
+$ then echo "regtest: not available"
+$ else echo "regtest"
+$ echo "Some of the output from regtest is very system specific, do not"
+$ echo "be distressed if your output differs from that distributed."
+$ echo "Manual inspection is called for."
+$ @regtest.com
+$ endif
+$ return
+$
+$posix: echo "posix"
+$ gawk -f posix.awk >tmp.
+1:2,3 4
+$ cmp posix.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$manyfiles: echo "manyfiles"
+$ if f$search("[.junk]*.*").nes."" then rm [.junk]*.*;*
+$ if f$parse("[.junk]").eqs."" then create/Dir/Prot=(O:rwed) [.junk]
+$ gawk "BEGIN { for (i = 1; i <= 300; i++) print i, i}" >tmp.
+$ echo "This may take quite a while..."
+$ echo ""
+$ gawk -f manyfiles.awk tmp. tmp.
+$ define/User sys$error _NL:
+$ define/User sys$output tmp.too
+$ search/Match=Nor/Output=_NL:/Log [.junk]*.* ""
+$!/Log output: "%SEARCH-S-NOMATCH, <filename> - <#> records" plus 1 line summary
+$ gawk "$4!=2{++count}; END{if(NR!=301||count!=1){print ""Failed!""}}" tmp.too
+$ rm tmp.;,tmp.too;,[.junk]*.*;*,[]junk.dir;
+$ return
+$
+$compare: echo "compare"
+$ gawk -f compare.awk 0 1 compare.in >tmp.
+$ cmp compare.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$arrayref: echo "arrayref"
+$ gawk -f arrayref.awk >tmp.
+$ cmp arrayref.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$rs: echo "rs"
+$ gawk -v "RS=" "{ print $1, $2}" rs.in >tmp.
+$ cmp rs.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fsbs: echo "fsbs"
+$ gawk -v "FS=\" "{ print $1, $2 }" fsbs.in >tmp.
+$ cmp fsbs.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$inftest: echo "inftest"
+$ !! echo "This test is very machine specific..."
+$ gawk -f inftest.awk >tmp.
+$ !! cmp inftest.ok tmp. !just care that gawk doesn't crash...
+$ if $status then rm tmp.;
+$ return
+$
+$getline: echo "getline"
+$ gawk -f getline.awk getline.awk getline.awk >tmp.
+$ cmp getline.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$rand: echo "rand"
+$ echo "The following line should just be 19 random numbers between 1 and 100"
+$ echo ""
+$ gawk -f rand.awk
+$ return
+$
+$negexp: echo "negexp"
+$ gawk "BEGIN { a = -2; print 10^a }" >tmp.
+$ cmp negexp.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$asgext: echo "asgext"
+$ gawk -f asgext.awk asgext.in >tmp.
+$ cmp asgext.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$anchgsub: echo "anchgsub"
+$ gawk -f anchgsub.awk anchgsub.in >tmp.
+$ cmp anchgsub.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$splitargv: echo "splitargv"
+$ gawk -f splitargv.awk splitargv.in >tmp.
+$ cmp splitargv.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$awkpath: echo "awkpath"
+$ define/User AWK_LIBRARY [],[.lib]
+$ gawk -f awkpath.awk >tmp.
+$ cmp awkpath.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$nfset: echo "nfset"
+$ gawk -f nfset.awk nfset.in >tmp.
+$ cmp nfset.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$reparse: echo "reparse"
+$ gawk -f reparse.awk reparse.in >tmp.
+$ cmp reparse.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$argtest: echo "argtest"
+$ gawk -f argtest.awk -x -y abc >tmp.
+$ cmp argtest.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$badargs: echo "badargs"
+$ on error then continue
+$ gawk -f 2>&1 >tmp.too
+$! search/Match=Nor tmp. "patchlevel" /Output=tmp.
+$ gawk "/patchlevel/{next}; {gsub(""\"""",""'""); print}" <tmp.too >tmp.
+$ cmp badargs.ok tmp.
+$ if $status then rm tmp.;,tmp.too;
+$ return
+$
+$convfmt: echo "convfmt"
+$ gawk -f convfmt.awk >tmp.
+$ cmp convfmt.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$arrayparm: echo "arrayparm"
+$ set noOn
+$ AWKPATH_srcdir
+$ gawk -f arrayparm.awk >tmp. 2>&1
+$ set On
+$ cmp arrayparm.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$paramdup: echo "paramdup"
+$ set noOn
+$ AWKPATH_srcdir
+$ gawk -f paramdup.awk >tmp. 2>&1
+$ set On
+$ cmp paramdup.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$nonl: echo "nonl"
+$ ! this one might fail, depending on how the distribution was unpacked,
+$ ! because the nonl.awk might actually end up with a final newline
+$ AWKPATH_srcdir
+$ gawk --lint -f nonl.awk _NL: >tmp. 2>&1
+$ cmp nonl.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$defref: echo "defref"
+$ set noOn
+$ AWKPATH_srcdir
+$ gawk --lint -f defref.awk >tmp. 2>&1
+$ set On
+$ cmp defref.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$nofmtch: echo "nofmtch"
+$ AWKPATH_srcdir
+$ gawk --lint -f nofmtch.awk >tmp. 2>&1
+$ cmp nofmtch.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$strftime: echo "strftime"
+$ ! this test could fail on slow machines or on a second boundary,
+$ ! so if it does, double check the actual results
+$!! date | gawk -- "{$3 = sprintf(""%02d"",$3+0); print >""strftime.ok""; print strftime() >""tmp.""}"
+$ ! note: original test is too Unix-specific, so substitute an easier one
+$ gawk -- "BEGIN {""show time"" | getline; print >""strftime.ok""; print strftime("" %v %T"") >""tmp.""}"
+$ set noOn
+$ cmp strftime.ok tmp.
+$ if $status then rm tmp.;,strftime.ok;*
+$ set On
+$ return
+$
+$litoct: echo "litoct"
+$ gawk --traditional -f litoct.awk >tmp.
+ab
+$ cmp litoct.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$gensub: echo "gensub"
+$ gawk -f gensub.awk gensub.in >tmp.
+$ cmp gensub.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$resplit: echo "resplit"
+$ gawk -- "{ FS = "":""; $0 = $0; print $2 }" >tmp.
+a:b:c d:e:f
+$ cmp resplit.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$rswhite: echo "rswhite"
+$ gawk -f rswhite.awk rswhite.in >tmp.
+$ cmp rswhite.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$prmarscl: echo "prmarscl"
+$ set noOn
+$ AWKPATH_srcdir
+$ gawk -f prmarscl.awk >tmp. 2>&1
+$ set On
+$ cmp prmarscl.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$sclforin: echo "sclforin"
+$ set noOn
+$ AWKPATH_srcdir
+$ gawk -f sclforin.awk >tmp. 2>&1
+$ set On
+$ cmp sclforin.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$sclifin: echo "sclifin"
+$ set noOn
+$ AWKPATH_srcdir
+$ gawk -f sclifin.awk >tmp. 2>&1
+$ set On
+$ cmp sclifin.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$intprec: echo "intprec"
+$ gawk -f intprec.awk >tmp. 2>&1
+$ cmp intprec.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$! note: this `childin' test currently [gawk 3.0.1] fails for vms
+$childin: echo "childin"
+$ echo "note: type ``hi<return><ctrl/Z>'",-
+ "' if testing appears to hang in `childin'"
+$!! @echo hi | gawk "BEGIN { ""cat"" | getline; print; close(""cat"") }" >tmp.
+$ gawk "BEGIN { ""type sys$input:"" | getline; print; close(""type sys$input:"") }" >tmp.
+hi
+$ cmp childin.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$noeffect: echo "noeffect"
+$ AWKPATH_srcdir
+$ gawk --lint -f noeffect.awk >tmp. 2>&1
+$ cmp noeffect.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$numsubstr: echo "numsubstr"
+$ AWKPATH_srcdir
+$ gawk -f numsubstr.awk numsubstr.in >tmp.
+$ cmp numsubstr.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$gnureops: echo "gnureops"
+$ gawk -f gnureops.awk >tmp.
+$ cmp gnureops.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$pcntplus: echo "pcntplus"
+$ gawk -f pcntplus.awk >tmp.
+$ cmp pcntplus.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$prmreuse: echo "prmreuse"
+$ if f$search("prmreuse.ok").eqs."" then create prmreuse.ok
+$ gawk -f prmreuse.awk >tmp.
+$ cmp prmreuse.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$math: echo "math"
+$ gawk -f math.awk >tmp.
+$ cmp math.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fflush:
+$ echo "fflush: hopeless for VMS, so skipped"
+$ return
+$!!fflush: echo "fflush"
+$ ! hopelessly Unix-specific
+$!! @fflush.sh >tmp.
+$ cmp fflush.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fldchg: echo "fldchg"
+$ gawk -f fldchg.awk fldchg.in >tmp.
+$ cmp fldchg.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fldchgnf: echo "fldchgnf"
+$ gawk -f fldchgnf.awk fldchgnf.in >tmp.
+$ cmp fldchgnf.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$reindops: echo "reindops"
+$ gawk -f reindops.awk reindops.in >tmp.
+$ cmp reindops.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$sprintfc: echo "sprintfc"
+$ gawk -f sprintfc.awk sprintfc.in >tmp.
+$ cmp sprintfc.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$getlnhd:
+$ echo "getlnhd: uses Unix-specific command so won't work on VMS"
+$ return
+$!!getlnhd: echo "getlnhd"
+$ gawk -f getlnhd.awk >tmp.
+$ cmp getlnhd.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$backgsub: echo "backgsub"
+$ gawk -f backgsub.awk backgsub.in >tmp.
+$ cmp backgsub.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$tweakfld: echo "tweakfld"
+$ gawk -f tweakfld.awk tweakfld.in >tmp.
+$ if f$search("errors.cleanup").nes."" then rm errors.cleanup;*
+$ cmp tweakfld.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$clsflnam: echo "clsflnam"
+$ if f$search("clsflnam.ok").eqs."" then create clsflnam.ok
+$ gawk -f clsflnam.awk clsflnam.in >tmp.
+$ cmp clsflnam.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$mmap8k: echo "mmap8k"
+$ gawk "{ print }" mmap8k.in >tmp.
+$ cmp mmap8k.in tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$fnarray: echo "fnarray"
+$ set noOn
+$ AWKPATH_srcdir
+$ gawk -f fnarray.awk >tmp. 2>&1
+$ set On
+$ cmp fnarray.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$dynlj: echo "dynlj"
+$ gawk -f dynlj.awk >tmp.
+$ cmp dynlj.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$substr: echo "substr"
+$ gawk -f substr.awk >tmp.
+$ cmp substr.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$eofsplit: echo "eofsplit"
+$ if f$search("eofsplit.ok").eqs."" then create eofsplit.ok
+$ gawk -f eofsplit.awk >tmp.
+$ cmp eofsplit.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$prt1eval: echo "prt1eval"
+$ gawk -f prt1eval.awk >tmp.
+$ cmp prt1eval.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$splitwht: echo "splitwht"
+$ gawk -f splitwht.awk >tmp.
+$ cmp splitwht.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$back89: echo "back89"
+$ gawk "/a\8b/" back89.in >tmp.
+$ cmp back89.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$tradanch: echo "tradanch"
+$ if f$search("tradanch.ok").eqs."" then create tradanch.ok
+$ gawk --traditional -f tradanch.awk tradanch.in >tmp.
+$ cmp tradanch.ok tmp.
+$ if $status then rm tmp.;
+$ return
+$
+$
+$clean:
+$ if f$search("tmp.") .nes."" then rm tmp.;*
+$ if f$search("tmp.too") .nes."" then rm tmp.too;*
+$ if f$search("out%.") .nes."" then rm out%.;*
+$ if f$search("strftime.ok").nes."" then rm strftime.ok;*
+$ if f$search("[.junk]*.*").nes."" then rm [.junk]*.*;*
+$ if f$parse("[.junk]") .nes."" then rm []junk.dir;1
+$ return
+$
+$!NOTREACHED
+$ exit