# This is patch 3 to gawk 2.15. # Change to the gawk 2.15.2 distribution directory, and sh this file. # Running it through patch is not enough; several files and directories # must be moved and/or renamed first, and some file and directory permissions # need fixing too. # # Make sure that the patch program is in your search path. mv README.ibmrt-aos README.rt-aos rm -fr pc awktab.c getopt.[ch] getopt1.c README.dos support/texinfo.tex find . -print | while read name do chmod a+r $name chmod u+w $name done patch -p1 << \EOF diff -crN gawk-2.15.2/ACKNOWLEDGMENT gawk-2.15.3/ACKNOWLEDGMENT *** gawk-2.15.2/ACKNOWLEDGMENT Fri Jul 17 11:48:29 1992 --- gawk-2.15.3/ACKNOWLEDGMENT Sun Nov 7 10:09:13 1993 *************** *** 10,19 **** Pat Rankin (VMS) Michal Jaegermann (Atari, NeXT, DEC 3100) Mike Lijewski (IBM RS6000) ! Scott Deifik (MSDOS 2.14) Kent Williams (MSDOS 2.11) Conrad Kwok (MSDOS earlier versions) Scott Garfinkle (MSDOS earlier versions) Last, but far from least, we would like to thank Brian Kernighan who has helped to clear up many dark corners of the language and provided a --- 10,21 ---- Pat Rankin (VMS) Michal Jaegermann (Atari, NeXT, DEC 3100) Mike Lijewski (IBM RS6000) ! Scott Deifik (MSDOS 2.14 and 2.15) Kent Williams (MSDOS 2.11) Conrad Kwok (MSDOS earlier versions) Scott Garfinkle (MSDOS earlier versions) + Kai Uwe Rommel (OS/2) + Darrel Hankerson (OS/2) Last, but far from least, we would like to thank Brian Kernighan who has helped to clear up many dark corners of the language and provided a diff -crN gawk-2.15.2/Makefile.bsd44 gawk-2.15.3/Makefile.bsd44 *** gawk-2.15.2/Makefile.bsd44 Tue May 18 12:34:03 1993 --- gawk-2.15.3/Makefile.bsd44 Tue Jun 1 14:55:04 1993 *************** *** 9,12 **** --- 9,14 ---- MANDIR= /usr/share/man/cat CLEANFILES+=awk.c y.tab.h awk.0 + awk.0: gawk.1 + nroff -man gawk.1 > awk.0 .include diff -crN gawk-2.15.2/Makefile.cline gawk-2.15.3/Makefile.cline *** gawk-2.15.2/Makefile.cline Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/Makefile.cline Thu Jun 10 15:38:48 1993 *************** *** 0 **** --- 1,65 ---- + # >>> CenterLine Make Targets <<< + # + gawk_obj: + #cd /net/ecum/src/system/david/awk/gawk-2.15.3 + #load -DGAWK -DHAVE_CONFIG_H main.o + #instrument main.o + #load -DGAWK -DHAVE_CONFIG_H eval.o + #instrument eval.o + #load -DGAWK -DHAVE_CONFIG_H builtin.o + #instrument builtin.o + #load -DGAWK -DHAVE_CONFIG_H msg.o + #instrument msg.o + #load -DGAWK -DHAVE_CONFIG_H iop.o + #instrument iop.o + #load -DGAWK -DHAVE_CONFIG_H io.o + #instrument io.o + #load -DGAWK -DHAVE_CONFIG_H field.o + #instrument field.o + #load -DGAWK -DHAVE_CONFIG_H array.o + #instrument array.o + #load -DGAWK -DHAVE_CONFIG_H node.o + #instrument node.o + #load -DGAWK -DHAVE_CONFIG_H version.o + #instrument version.o + #load -DGAWK -DHAVE_CONFIG_H missing.o + #instrument missing.o + #load -DGAWK -DHAVE_CONFIG_H re.o + #instrument re.o + #load -DGAWK -DHAVE_CONFIG_H getopt.o + #instrument getopt.o + #load -DGAWK -DHAVE_CONFIG_H getopt1.o + #instrument getopt1.o + #load -DGAWK -DHAVE_CONFIG_H awktab.o + #instrument awktab.o + #load -DGAWK -DHAVE_CONFIG_H regex.o + #instrument regex.o + #load -DGAWK -DHAVE_CONFIG_H dfa.o + #instrument dfa.o + #load -lm + #setopt program_name gawk + + gawk_src: + #cd /net/ecum/src/system/david/awk/gawk-2.15.3 + #load -C -DGAWK -DHAVE_CONFIG_H main.c + #load -C -DGAWK -DHAVE_CONFIG_H eval.c + #load -C -DGAWK -DHAVE_CONFIG_H builtin.c + #load -C -DGAWK -DHAVE_CONFIG_H msg.c + #load -C -DGAWK -DHAVE_CONFIG_H iop.c + #load -C -DGAWK -DHAVE_CONFIG_H io.c + #load -C -DGAWK -DHAVE_CONFIG_H field.c + #load -C -DGAWK -DHAVE_CONFIG_H array.c + #load -C -DGAWK -DHAVE_CONFIG_H node.c + #load -C -DGAWK -DHAVE_CONFIG_H version.c + #load -C -DGAWK -DHAVE_CONFIG_H missing.c + #load -C -DGAWK -DHAVE_CONFIG_H re.c + #load -C -DGAWK -DHAVE_CONFIG_H getopt.c + #load -C -DGAWK -DHAVE_CONFIG_H getopt1.c + #load -C -DGAWK -DHAVE_CONFIG_H awktab.c + #load -C -DGAWK -DHAVE_CONFIG_H regex.c + #load -C -DGAWK -DHAVE_CONFIG_H dfa.c + #load -lm + #setopt program_name gawk + + # + # >>> End of CenterLine Make Targets <<< diff -crN gawk-2.15.2/Makefile.in gawk-2.15.3/Makefile.in *** gawk-2.15.2/Makefile.in Wed May 19 12:36:31 1993 --- gawk-2.15.3/Makefile.in Sun Nov 7 10:26:41 1993 *************** *** 33,56 **** manext = .1 infodir = $(prefix)/info - # CFLAGS: options to the C compiler - # - # -O optimize - # -g include dbx/sdb info - # -pg include new (gmon) profiling info - # # The provided "configure" is used to turn a config file (samples in # the "config" directory into commands to edit config.in into # a suitable config.h and to edit Makefile.in into Makefile. # To port GAWK, create an appropriate config file using the ones in # the config directory as examples and using the comments in config.in # as a guide. - # CC= gcc ##MAKE_CC## CC = cc - OPTIMIZE= -g -O PROFILE= #-pg DEBUG= #-DMALLOCDEBUG #-DDEBUG #-DFUNC_TRACE #-DMPROF LINKSTATIC= #-Bstatic --- 33,48 ---- *************** *** 81,104 **** ##MAKE_ALLOCA_C## ALLOCA= alloca.o ##MAKE_ALLOCA_S## ALLOCA= alloca.o ! FLAGS= # VMS POSIX, VAXC V3.2 ! ##MAKE_VMS-Posix## FLAGS = -UVMS -D__STDC__=0 # HP/Apollo running cc version 6.7 or earlier ! ##MAKE_Apollo## FLAGS = -U__STDC__ -A run,sys5.3 ##MAKE_Apollo## LIBS = -A sys,any # SGI IRIX 4.0.5 cc flags ! ##MAKE_SGI## FLAGS = -cckr ! # Use -s -Xlinker -object flags when you are satisfied that ! # that the program compiles correctly ! ##MAKE_NeXT## FLAGS = -DGFMT_WORKAROUND #-s -Xlinker -object ! CFLAGS= -DGAWK $(FLAGS) $(DEBUG) $(LINKSTATIC) $(PROFILE) $(OPTIMIZE) $(WARN) # object files AWKOBJS = main.o eval.o builtin.o msg.o iop.o io.o field.o array.o \ node.o version.o missing.o re.o getopt.o getopt1.o --- 73,99 ---- ##MAKE_ALLOCA_C## ALLOCA= alloca.o ##MAKE_ALLOCA_S## ALLOCA= alloca.o ! VFLAGS= # VMS POSIX, VAXC V3.2 ! ##MAKE_VMS-Posix## VFLAGS = -UVMS -D__STDC__=0 # HP/Apollo running cc version 6.7 or earlier ! ##MAKE_Apollo## VFLAGS = -U__STDC__ -A run,sys5.3 ##MAKE_Apollo## LIBS = -A sys,any # SGI IRIX 4.0.5 cc flags ! ##MAKE_SGI## VFLAGS = -cckr ! ##MAKE_NeXT## VFLAGS = -DGFMT_WORKAROUND ! CFLAGS = -g -O ! FLAGS = -DGAWK -DHAVE_CONFIG_H $(VFLAGS) $(DEBUG) $(PROFILE) $(WARN) ! LDFLAGS = $(LINKSTATIC) $(PROFILE) + .c.o: + $(CC) $(CFLAGS) $(FLAGS) -c $< + # object files AWKOBJS = main.o eval.o builtin.o msg.o iop.o io.o field.o array.o \ node.o version.o missing.o re.o getopt.o getopt1.o *************** *** 127,133 **** SUPPORT = support/texindex.c support/texinfo.tex ! DOCS= gawk.1 gawk.texi gawk.info 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 --- 122,128 ---- SUPPORT = support/texindex.c support/texinfo.tex ! DOCS= gawk.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 *************** *** 144,150 **** # rules to build gawk gawk: $(ALLOBJS) $(GNUOBJS) $(REOBJS) ! $(CC) -o gawk $(CFLAGS) $(ALLOBJS) $(GNUOBJS) $(REOBJS) -lm $(LIBS) $(AWKOBJS) regex.o dfa.o: awk.h dfa.h regex.h --- 139,145 ---- # rules to build gawk gawk: $(ALLOBJS) $(GNUOBJS) $(REOBJS) ! $(CC) -o gawk $(LDFLAGS) $(ALLOBJS) $(GNUOBJS) $(REOBJS) -lm $(LIBS) $(AWKOBJS) regex.o dfa.o: awk.h dfa.h regex.h *************** *** 161,166 **** --- 156,163 ---- sed '/^extern char .malloc(), .realloc();$$/d' y.tab.c >awktab.c rm y.tab.c + awktab.o: awk.h + config.h: config.in @echo You must provide a config.h! @echo Run \"./configure\" to build it for known systems *************** *** 200,205 **** --- 197,203 ---- clean: rm -rf gawk *.o core + cd test && make clean distclean: clean rm -f Makefile *.orig *.rej */*.orig */*.rej awk.output gmon.out \ *************** *** 217,225 **** --- 215,225 ---- rm -f $(ALLDOC) gawk.log config.h gawk.dvi: gawk.texi + cp support/texinfo.tex . tex gawk.texi; texindex gawk.?? tex gawk.texi; texindex gawk.?? tex gawk.texi + rm -f texinfo.tex gawk.info: gawk.texi makeinfo gawk.texi *************** *** 227,264 **** dist: $(AWKSRC) $(GNUSRC) $(DOCS) $(MISC) $(COPIES) $(SUPPORT) distclean -rm -rf gawk-$(REL)* dir=gawk-$(REL).`gawk '{print $$3}' patchlevel.h` && \ - ./configure msdos && \ - mv config.h pc && \ mkdir $$dir && \ ! cp -p $(AWKSRC) $(GNUSRC) $(DOCS) gawk.info-* $(MISC) $$dir && \ mkdir $$dir/missing && cp -p $(COPIES) $$dir/missing && \ mkdir $$dir/atari && cp -p atari/* $$dir/atari && \ mkdir $$dir/pc && cp -p pc/* $$dir/pc && \ mkdir $$dir/vms && cp -p vms/* $$dir/vms && \ mkdir $$dir/config && cp -p config/* $$dir/config && \ mkdir $$dir/support && cp -p support/* $$dir/support && \ ! mv test $$dir && \ chmod -R a-w $$dir && \ ! cd $$dir && chmod u+w . test missing atari pc vms config support && \ ! cd .. && \ ! tar -cf - $$dir | gzip > $$dir.tar.z && \ ! mv $$dir/test . ! gawk-doc-$(REL).tar.z: gawk.info gawk.dvi gawk.1 ! -rm -rf gawk-doc-$(REL) gawk-doc-$(REL).tar.z -mkdir gawk-doc-$(REL) ! cp -p gawk.dvi gawk-doc-$(REL) ! nroff -man gawk.1 > gawk-doc-$(REL)/gawk.1.pr ! tar -cf - gawk-doc-$(REL) | gzip > gawk-doc-$(REL).tar.z ! gawk-ps-$(REL).tar.z: gawk.dvi gawk.1 ! -rm -rf gawk-ps-$(REL) gawk-ps-$(REL).tar.z -mkdir gawk-ps-$(REL) ! dvips -o !cat gawk.dvi > gawk-ps-$(REL)/gawk.postscript ! pstroff -man gawk.1 > gawk-ps-$(REL)/gawk.1.ps ! tar -cf - gawk-ps-$(REL) | gzip > gawk-ps-$(REL).tar.z ! release: dist gawk-doc-$(REL).tar.z gawk-ps-$(REL).tar.z test: gawk cd test; make -k --- 227,263 ---- dist: $(AWKSRC) $(GNUSRC) $(DOCS) $(MISC) $(COPIES) $(SUPPORT) distclean -rm -rf gawk-$(REL)* dir=gawk-$(REL).`gawk '{print $$3}' patchlevel.h` && \ mkdir $$dir && \ ! cp -p $(AWKSRC) $(GNUSRC) $(DOCS) $(MISC) $$dir && \ mkdir $$dir/missing && cp -p $(COPIES) $$dir/missing && \ mkdir $$dir/atari && cp -p atari/* $$dir/atari && \ mkdir $$dir/pc && cp -p pc/* $$dir/pc && \ mkdir $$dir/vms && cp -p vms/* $$dir/vms && \ mkdir $$dir/config && cp -p config/* $$dir/config && \ mkdir $$dir/support && cp -p support/* $$dir/support && \ ! cp -pr test $$dir && \ ! chmod -R a+r $$dir && \ chmod -R a-w $$dir && \ ! find $$dir -type d -exec chmod 755 {} ';' && \ ! find $$dir -print | doschk && \ ! tar -cf - $$dir | gzip > $$dir.tar.gz && \ ! rm -fr $$dir ! gawk-doc-$(REL).tar.gz: gawk.info gawk.dvi gawk.1 ! -rm -rf gawk-doc-$(REL) gawk-doc-$(REL).tar.gz -mkdir gawk-doc-$(REL) ! cp -p $(ALLDOC) gawk-doc-$(REL) ! groff -Tascii -man gawk.1 > gawk-doc-$(REL)/gawk.1.pr ! tar -cf - gawk-doc-$(REL) | gzip > gawk-doc-$(REL).tar.gz ! gawk-ps-$(REL).tar.gz: gawk.dvi gawk.1 ! -rm -rf gawk-ps-$(REL) gawk-ps-$(REL).tar.gz -mkdir gawk-ps-$(REL) ! dvips -o gawk-ps-$(REL)/gawk.postscript gawk.dvi ! groff -man gawk.1 > gawk-ps-$(REL)/gawk.1.ps ! tar -cf - gawk-ps-$(REL) | gzip > gawk-ps-$(REL).tar.gz ! release: dist gawk-doc-$(REL).tar.gz gawk-ps-$(REL).tar.gz test: gawk cd test; make -k diff -crN gawk-2.15.2/NEWS gawk-2.15.3/NEWS *** gawk-2.15.2/NEWS Wed May 19 20:08:31 1993 --- gawk-2.15.3/NEWS Sun Nov 7 11:44:14 1993 *************** *** 1,5 **** Changes from 2.15.1 to 2.15.2 ! --------------------------- Additions to the FUTURES file. --- 1,53 ---- + Changes from 2.15.2 to 2.15.3 + ----------------------------- + + Increased HASHSIZE to a decent number, 127 was way too small. + + FILENAME is now the null string in a BEGIN rule. + + Argument processing fixed for invalid options and missing arguments. + + This version will build on VMS. This included a fix to close all files + and pipes opened with redirections before closing stdout and stderr. + + More getpgrp() defines. + + Changes for BSD44: in io.c and Makefile.bsd44. + + All directories in the distribution are now writeable. + + Separated LDFLAGS and CFLAGS in Makefile. CFLAGS can now be overridden by + user. + + Make dist now builds compressed archives ending in .gz and runs doschk. + + Amiga port. + + New getopt.c fixes Alpha OSF/1 problem. + + Make clean now removes possible test output. + + Improved algorithm for multiple adjacent string concatenations leads to + performance improvements. + + Fix nasty bug whereby command-line assignments, both with -v and at run time, + could create variables with syntactically illegal names. + + Fix obscure bug in printf with %0 flag and filling. + + Add a lint check for substr if provided length exceeds remaining characters + in string. + + Update atari support. + + PC support enhanced to include support for both DOS and OS/2. (Lots more + #ifdefs. Sigh.) + + Config files for Hitachi Unix and OSF/1, courtesy of Yoko Morishita + (morisita@sra.co.jp) + Changes from 2.15.1 to 2.15.2 ! ----------------------------- Additions to the FUTURES file. *************** *** 10,16 **** Clean up the distribution generation in Makefile.in: the info files are now included, the distributed files are marked read-only and patched distributions are now unpacked in a directory named with the patch level. - Changes from 2.15 to 2.15.1 --------------------------- --- 58,63 ---- diff -crN gawk-2.15.2/README gawk-2.15.3/README *** gawk-2.15.2/README Tue Apr 27 21:47:21 1993 --- gawk-2.15.3/README Fri Oct 22 06:04:15 1993 *************** *** 54,63 **** The next release will use the FSF autoconfig program, so we are no longer soliciting new config files. ! If you have an MS-DOS system, use the stuff in the pc directory. For an Atari there is an atari directory and similarly one for VMS. Chapter 16 of The GAWK Manual discusses configuration in detail. After successful compilation, do 'make test' to run a small test suite. There should be no output from the 'cmp' invocations except in --- 54,65 ---- The next release will use the FSF autoconfig program, so we are no longer soliciting new config files. ! If you have an MS-DOS or OS/2 system, use the stuff in the pc directory. For an Atari there is an atari directory and similarly one for VMS. Chapter 16 of The GAWK Manual discusses configuration in detail. + (However, it does not discuss OS/2 configuration, see README.pc for + the details. The manual is being massively revised for 2.16.) After successful compilation, do 'make test' to run a small test suite. There should be no output from the 'cmp' invocations except in *************** *** 114,116 **** --- 116,122 ---- Atari ST: Michal Jaegermann NTOMCZAK@vm.ucs.UAlberta.CA (e-mail only) + + OS/2: + Kai Uwe Rommel + rommel@ars.muc.de (e-mail only) diff -crN gawk-2.15.2/README.VMS gawk-2.15.3/README.VMS *** gawk-2.15.2/README.VMS Fri Oct 23 15:46:02 1992 --- gawk-2.15.3/README.VMS Fri Oct 22 06:08:11 1993 *************** *** 21,27 **** 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-1 using VAX C V3.2, GNU C 1.40 and 2.3. Should work without modifications for VMS V4.6 and up. --- 21,27 ---- 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. *************** *** 89,95 **** 'configure' and 'mungeconf', are executable; use `chmod +x' on them if necessary. Then execute the following two commands: |psx> configure vms-posix ! |psx> make 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 --- 89,95 ---- '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 diff -crN gawk-2.15.2/README.amiga gawk-2.15.3/README.amiga *** gawk-2.15.2/README.amiga Tue Apr 27 21:48:19 1993 --- gawk-2.15.3/README.amiga Tue Jun 1 15:22:31 1993 *************** *** 64,89 **** you should have an executable version of `gawk'. That's all there is to it! ! ! Testing ( %-/ ------- ! Testing gawk with the included shell-scripts and .awk-files is not ! possible. As far as I found out this is a Shell problem (shell- ! metas), not a gawk problem. Using gawk from the commandline requires ! modifications, too. To perform at least some of the tests I'd ! suggest: ! ! make >amitest -n bigtest ! ! then modifying 'amitest' to work with your shell and ! ! execute amitest ! ! All tests that are depending on UNIX-shell specifics will fail (eg. ! redirection of stderr: stderr and stdout are identical on the Amiga). ! If I really have the time (currently I'm finishing my studies) I'll ! write an amiga-script for the tests ... ! ! Despite testing is not a thankful task, `gawk' works and I found it ! very useful for tasks where both shell scripts and C-programs are ! inadequate. --- 64,83 ---- you should have an executable version of `gawk'. That's all there is to it! ! Testing ------- ! Gawk succeeds in all tests, but not with 'make test'. When executing ! the tests by hand (e.g. 'make swaplns' and so on) gawk runs all tests ! ok except for the following: ! - argarray, awkpath: these do not work due to insufficient environment ! variable handling by pdksh ('bin:sh') ! - poundbang, regtest: pdksh refuses to handle the #! statement ! properly ! Modifying these tests in a way that only *gawk-features, not *sh- ! features are tested, it is found that gawk succeeds here too. ! - manyfiles: (error: too many open files) ixemul.library v39.45 uses ! OPEN_MAX=64; manyfiles required at least OPEN_MAX=106 ! This may only be overcome when mwild releases a new ixemul.library. ! Changing the number '100' in the 'manyfiles::'-target in ! 'test/Makefile' to some value <= 58 (depends on the number of ! currently open files in ixemul.library) gawk tests successfully, too. diff -crN gawk-2.15.2/README.atari gawk-2.15.3/README.atari *** gawk-2.15.2/README.atari Mon Sep 28 15:02:00 1992 --- gawk-2.15.3/README.atari Thu Oct 21 22:51:34 1993 *************** *** 1,5 **** Gawk on Atari has been compiled and tested using gcc compiler ! (versions 1.4 and 2.2.2) both with and without -mshort flag. Other compilers can be used but if sizeof(pointer) != sizeof(int) this code will not compile correctly with non-ANSI compiler (prototypes and library). --- 1,5 ---- Gawk on Atari has been compiled and tested using gcc compiler ! (versions 1.4 and 2.4.4) both with and without -mshort flag. Other compilers can be used but if sizeof(pointer) != sizeof(int) this code will not compile correctly with non-ANSI compiler (prototypes and library). diff -crN gawk-2.15.2/README.pc gawk-2.15.3/README.pc *** gawk-2.15.2/README.pc Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/README.pc Fri Oct 15 15:49:10 1993 *************** *** 0 **** --- 1,112 ---- + This is the README for GNU awk 2.15 under OS/2 and MS-DOS. + + Gawk has been compiled and tested under OS/2 1.x--2.x and MS-DOS + using MSC 5.1, MSC 6.00A, and EMX/gcc 0.8g. + + + Compiling for DOS from a DOS (or OS/2) host + ------------------------------------------- + + Move the stuff in the pc directory to the directory with the rest + of the gawk sources. The files Makefile.emx (for EMX/gcc) and + Makefile.msc (for MSC 5.1 or 6.00A) should work with any Unix-like + make, including Ndmake 4.5 and dmake 3.8. + + An alternative makegawk.bat file exists for compiling with MSC 5.1 + or 6.00A. You may need to put CRs at the end of each line in the + makegawk.bat, Makefile.emx, and Makefile.msc files. + + If using MSC 5.1, you will also have to copy the Microsoft library + routine setargv.obj to the gawk directory for the link to work. + + Please note: Gawk is very sensitive to compiler optimization; + using -Oa or -Ox with MSC 5.1 WILL cause errors. It is recommended + to only use the default optimization. Also, you should get warning + messages with MSC, but you can ignore them. + + Additional information can be found in the notes at the end of + this file. + + + Compiling for OS/2 or DOS from an OS/2 host + ------------------------------------------- + + Move the files in the pc dirctory to the directory with the rest + of the gawk sources. Makefile.os2 has been tested with dmake 3.8 + and GNU make 3.68. Enter "make -f Makefile.os2" to see a list of + targets. As an example, an OS/2 and DOS 32-bit executable using + EMX/gcc can be created with the command "make -f Makefile.os2 emxbnd". + + If using MSC 5.1, you will also have to copy the Microsoft library + routine setargv.obj to the gawk directory for the link to work. + + + Notes + ----- + + 1. The usual shells for OS/2 and DOS (command.com for DOS and cmd.exe + for OS/2) do not handle command-lines very well. Stewartson's sh (OS/2 + and DOS) and GNU bash (OS/2 2.x) are good choices. Stewartson's shell + 2.2 is in beta (as of 17-Sep-93). Earlier versions can be found at + + ftp.informatik.tu-muenchen.de:pub/comp.os/os2/shells/sh164-2.zip + oak.oakland.edu:pub/msdos/sysutl/ms_sh21b.zip + ftp-os2.cdrom.com:pub/os2/all/unix/shells/ms_sh21c.zip + + OS/2 HPFS users should obtain ms_sh21c.zip over ms_sh21b.zip. ksh + may be another possibility, available from ftp.informatik.tu-muenchen.de. + + Bash for OS/2 2.x can be found at + + ftp.informatik.tu-muenchen.de:pub/comp.os/os2/gnu/gnubash.zip + ftp-os2.cdrom.com:pub/os2/2_x/unix/shells/bash.zip + + + 2. Stewartson's shell contains sources for a setargv-replacement + for MSC, which can add enhanced command-line processing capabilities + to gawk. See Makefile.os2. + + + 3. dmake is by Dennis Vadura (dvadura@watdragon.uwaterloo.ca), CS Dept., + University of Waterloo. An OS/2 and DOS version can be found at + + ftp.informatik.tu-muenchen.de:pub/comp.os/os2/devtools/dmake38.zip + ftp-os2.cdrom.com:pub/os2/all/program/dmake38x.zip + + Ndmake is by D.G. Kneller. This ShareWare program was later released + as Opus Make (which is available for OS/2 and DOS). Ndmake 4.5 is + available at + + oak.oakland.edu:pub/msdos/c/ndmake45.zip + + GNU make is from the FSF. An OS/2 2.x version can be found at + + ftp.informatik.tu-muenchen.de:pub/comp.os/os2/devtools/gnumake.zip + + The "lookup" feature of ncftp reports: + + ncftp>lookup ftp.informatik.tu-muenchen.de + hpsystem2.informatik.tu-muenchen.de 131.159.0.198 + + ncftp>lookup ftp-os2.cdrom.com + wcarchive.cdrom.com 192.153.46.2 + + ncftp>lookup oak.oakland.edu + rigel.acs.oakland.edu 141.210.10.117 + + + 4. Known bugs. The MSC 5.1 bound version has not received extensive + testing. When running under OS/2 2.1, there is a bug which may be + related to the 20-file limit. It can be observed in the "manyfiles" + test of test/Makefile. This does not occur when running under DOS. + + + ---- + + If you have any problems with the DOS or OS/2 versions of Gawk, + please send them to + + Scott Deifik, scottd@amgen.com (DOS versions) + or + Kai Uwe Rommel, rommel@ars.muc.de (OS/2 or bound versions) + Darrel Hankerson, hankedr@mail.auburn.edu diff -crN gawk-2.15.2/array.c gawk-2.15.3/array.c *** gawk-2.15.2/array.c Tue Apr 27 21:52:20 1993 --- gawk-2.15.3/array.c Tue Nov 2 06:33:23 1993 *************** *** 34,42 **** register NODE *r; char *str; char *s; ! unsigned len; int offset; ! int subseplen; char *subsep; if (tree->type != Node_expression_list) --- 34,42 ---- register NODE *r; char *str; char *s; ! size_t len; int offset; ! size_t subseplen; char *subsep; if (tree->type != Node_expression_list) *************** *** 101,107 **** unsigned int hash(s, len) register char *s; ! register int len; { register unsigned long h = 0, g; --- 101,107 ---- unsigned int hash(s, len) register char *s; ! register size_t len; { register unsigned long h = 0, g; *************** *** 187,193 **** if (symbol->var_array == 0) { /* this table really should grow * dynamically */ ! unsigned size; size = sizeof(NODE *) * HASHSIZE; emalloc(symbol->var_array, NODE **, size, "assoc_lookup"); --- 187,193 ---- if (symbol->var_array == 0) { /* this table really should grow * dynamically */ ! size_t size; size = sizeof(NODE *) * HASHSIZE; emalloc(symbol->var_array, NODE **, size, "assoc_lookup"); diff -crN gawk-2.15.2/atari/Makefile.st gawk-2.15.3/atari/Makefile.st *** gawk-2.15.2/atari/Makefile.st Fri Oct 23 15:44:21 1992 --- gawk-2.15.3/atari/Makefile.st Tue Nov 2 06:30:46 1993 *************** *** 1,145 **** ! # Makefile for GNU Awk - sample ST version. ! # This makefile for ST version of gcc compiler and associated libraries. # ! # This is a subset of the full Makefile cut down for Atari ST ! # gcc compiler is assumed ! # It is known to work with gulam shell. ! # It may need some customization depending on your setup! ! # Replace with it 'Makefile' from the source directory. # - # You need sed.ttp for an automatic creation of config.h file! - # Check gulam script mkconf.g in atari directory. - # In a pinch you may create one by checking config/atari file and - # editing config.in by hand. - # # Copyright (C) 1986, 1988-1992 the Free Software Foundation, Inc. ! # # This file is part of GAWK, the GNU implementation of the # AWK Progamming Language. ! # # GAWK is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. ! # # GAWK is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. ! # ! ! # cross-compiler ! CC= cgcc ! # native ! CC= gcc ! # comment out the following two lines if you do not want use ! # 16-bit wide ints ! WIDTH = -mshort ! EXT=16 ! ! # for gcc 1.40 ! OPTIMIZE= -O -fstrength-reduce -fcombine-regs -fomit-frame-pointer ! # for gcc 2.2.2 ! #OPTIMIZE= -O2 -fstrength-reduce -fomit-frame-pointer ! PROFILE= #-pg ! DEBUG= #-DMALLOCDEBUG #-DDEBUG #-DFUNC_TRACE #-DMPROF ! LINKSTATIC= #-Bstatic ! WARN= #-W -Wunused -Wimplicit -Wreturn-type -Wcomment # for gcc only ! ! # Parser to use on grammar - any one of the following will work ! #PARSER = yacc ! PARSER = byacc ! #PARSER = bison -y # basename of parser output - adjust to your parser requirements ! POUTPUT = awk_tab - # Set LIBS to any libraries that are machine specific - LIBS = -lpml$(EXT) ! FLAGS=-G -Xlinker -x $(WIDTH) ! CFLAGS= -DGAWK $(FLAGS) $(DEBUG) $(LINKSTATIC) $(PROFILE) $(OPTIMIZE) $(WARN) # object files AWKOBJS = main.o eval.o builtin.o msg.o iop.o io.o field.o array.o \ ! node.o version.o missing.o re.o # getopt.o ALLOBJS = $(AWKOBJS) awktab.o # GNUOBJS ! # GNU stuff that gawk uses as library routines. ! GNUOBJS= regex.o dfa.o $(ALLOCA) ! ! # source and documentation files ! SRC = main.c eval.c builtin.c msg.c version.c \ ! iop.c io.c field.c array.c node.c missing.c re.c getopt.c ! ! ALLSRC= $(SRC) awktab.c ! ! AWKSRC= awk.h awk.y $(ALLSRC) patchlevel.h protos.h config.in getopt.h ! ! GNUSRC = alloca.c alloca.s dfa.c dfa.h regex.c regex.h ! ! COPIES = missing/system.c missing/tzset.c \ ! missing/memcmp.c missing/memcpy.c missing/memset.c \ ! missing/random.c missing/strcase.c missing/strchr.c \ ! missing/strerror.c missing/strtod.c \ ! missing/strftime.c missing/strftime.3 ! SUPPORT = support/texindex.c support/texinfo.tex ! DOCS= gawk.1 gawk.texi ! INFOFILES= gawk.info gawk.info-* \ ! gawk.aux gawk.cp gawk.cps gawk.fn gawk.fns gawk.ky gawk.kys \ ! gawk.pg gawk.pgs gawk.toc gawk.tp gawk.tps gawk.vr gawk.vrs ! MISC = NEWS COPYING FUTURES Makefile.* PROBLEMS README* PORTS POSIX \ ! mungeconf configure ACKNOWLEDGMENT LIMITATIONS ! ! OTHERS= pc/* atari/* vms/* ! ! ALLDOC= gawk.dvi $(INFOFILES) ! ALLFILES= $(AWKSRC) $(GNUSRC) $(COPIES) $(MISC) $(DOCS) $(ALLDOC) $(OTHERS) \ ! $(SUPPORT) ! # set this for a version of toglclr you are using ! TOGLFLAGS = -fload ! # rules to build gawk ! gawk.ttp: $(ALLOBJS) $(GNUOBJS) $(REOBJS) ! $(CC) -o $@ $(CFLAGS) $(ALLOBJS) $(GNUOBJS) $(REOBJS) $(LIBS) ! toglclr $(TOGLFLAGS) $@ ! $(AWKOBJS) regex.o dfa.o: awk.h dfa.h regex.h ! getopt.o: getopt.h ! main.o: patchlevel.h ! awktab.c: awk.y ! $(PARSER) -v awk.y ! sed '/^extern char .malloc(), .realloc();$$/d' $(POUTPUT).c >awktab.c ! rm $(POUTPUT).c ! ! config.h: config.in ! @echo You must provide a config.h! ! @echo Run \"./configure\" to build it for known systems ! @echo or copy config.in to config.h and edit it.; exit 1 gawk.dvi: gawk.texi tex gawk.texi; texindex gawk.?? tex gawk.texi gawk.info: gawk.texi makeinfo gawk.texi ! clean: ! rm *.o *.orig *.rej */*.orig */*.rej ! ! cleaner: clean ! rm gawk.ttp awktab.c ! clobber: clean ! rm $(ALLDOC) gawk.log --- 1,126 ---- ! # Makefile for GNU Awk - ST version. # ! # This makefile hand edited from Makefile automatically generated ! # by configure - gcc 2.x.x compiler with TOS version of libraries ! # and modified system(). ! # Check comments in this Makefile and adjust to your needs!! # # Copyright (C) 1986, 1988-1992 the Free Software Foundation, Inc. ! # # This file is part of GAWK, the GNU implementation of the # AWK Progamming Language. ! # # GAWK is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. ! # # GAWK is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. ! # ! # You should have received a copy of the GNU General Public License ! # along with GAWK; see the file COPYING. If not, write to ! # the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! ! srcdir = . ! VPATH = . ! ! # CC = gcc ! CC = cgcc # when cross-compiling ! #YACC = byacc ! YACC = bison -y # basename of parser output - adjust to your parser requirements ! YOUTPUT = awk_tab ! # WIDTH and EXT have to be both defined or both undefined ! # WIDTH = -mshort ! # EXT = 16 ! LIBS = -lpml$(EXT) ! LIBOBJS = strncasecmp.o ! ST_LIBOBJS = stack.o tmpnam.o system.o ! # CFLAGS= -g -DGAWK -DHAVE_CONFIG_H $(WIDTH) -I. -I.. ! CFLAGS= -DGAWK -DHAVE_CONFIG_H $(WIDTH) -O2 -I. -I.. -Wall \ ! -fomit-frame-pointer # -pipe # ! # keep only global symbols and use long symbol names ! # xstrip -k in target gawk.ttp removes all symbols but _stksize ! # allowing for stack size manipulations without recompiling (with fixstk) ! LDFLAGS= -Xlinker -x -G $(WIDTH) # object files AWKOBJS = main.o eval.o builtin.o msg.o iop.o io.o field.o array.o \ ! node.o version.o re.o getopt.o getopt1.o ALLOBJS = $(AWKOBJS) awktab.o # GNUOBJS ! # GNU stuff that gawk uses as library routines. ! GNUOBJS= rx.o dfa.o ! all: gawk.ttp ! gawk.ttp: $(ALLOBJS) $(GNUOBJS) $(REOBJS) $(LIBOBJS) $(ST_LIBOBJS) ! $(CC) -o $@ $(LDFLAGS) \ ! $(ALLOBJS) $(GNUOBJS) $(REOBJS) $(LIBOBJS) $(ST_LIBOBJS) $(LIBS) ! toglclr -fload $@ ! # xstrip -k $@ ! $(AWKOBJS) $(GNUOBJS): awk.h dfa.h regex.h config.h ! # cheat with defines to force an inclusion of a proper code ! getopt.o: getopt.h ! $(CC) $(CFLAGS) -D_LIBC -D__alloca=__builtin_alloca -c getopt.c ! getopt1.o: getopt.h ! main.o: patchlevel.h ! awktab.c: awk.y ! $(YACC) -v awk.y ! sed '/^extern char .malloc(), .realloc();$$/d' $(YOUTPUT).c >awktab.c ! rm $(YOUTPUT).c ! ! # rules for $(LIBOBJS) and $(ST_LIBOBJS) ! ! strncasecmp.o: missing/strncasecmp.c config.h ! $(CC) $(CFLAGS) -c missing/strncasecmp.c ! ! stack.o: atari/stack.c ! $(CC) $(CFLAGS) -c atari/stack.c ! ! tmpnam.o: atari/tmpnam.c ! $(CC) $(CFLAGS) -c atari/tmpnam.c ! ! # this is an optional replacement for a library module. ! system.o: atari/system.c ! $(CC) $(CFLAGS) -c atari/system.c ! clean: ! rm -rf gawk.ttp *.o core ! distclean: clean ! rm -f Makefile *.orig *.rej */*.orig */*.rej awk.output gmon.out \ ! make.out y.output config.h config.status ! mostlyclean: clean ! realclean: distclean ! rm -f awktab.c $(ALLDOC) gawk.dvi: gawk.texi tex gawk.texi; texindex gawk.?? + tex gawk.texi; texindex gawk.?? tex gawk.texi + rm -f gawk.?? gawk.??? gawk.info: gawk.texi makeinfo gawk.texi ! # not really (or not with every shell) - but you have an idea ! test: gawk ! cd test; $(MAKE) -k ! check: test diff -crN gawk-2.15.2/atari/config.h gawk-2.15.3/atari/config.h *** gawk-2.15.2/atari/config.h Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/atari/config.h Tue Nov 2 06:33:31 1993 *************** *** 0 **** --- 1,63 ---- + /* + * config.h for Atari ST. + * Assumes gcc compiler and TOS libraries. + * Edited by hand from a config.h generated automatically by configure. + */ + + /* Default path for Awk library */ + #define DEFPATH ".,c:\\lib\\awk,c:\\gnu\\lib\\awk" + /* Path separator in use */ + #define ENVSEP ',' + #define SZTC (size_t) + #define INTC (int) + + #define HAVE_STRING_H 1 /* have */ + #ifdef HAVE_STRING_H + #undef NEED_MEMORY_H /* need to declare memcpy() et al. */ + #endif + + #define STDC_HEADERS 1 /* have the usual ANSI header files */ + #undef HAVE_UNISTD_H /* have */ + #undef HAVE_ALLOCA_H /* have -- only used if bison is used */ + #undef HAVE_SIGNUM_H /* have */ + #undef REGEX_MALLOC /* don't use alloca in regex.c */ + + #define HAVE_VPRINTF 1 /* have vprintf() */ + + #define HAVE_RANDOM 1 /* have random(), or using missing/random.c */ + + #define HAVE_STRCHR 1 /* have strchr() and strrchr() */ + #ifndef HAVE_STRCHR + #ifdef HAVE_RINDEX /* use index() and rindex() if present */ + #define strchr index + #define strrchr rindex + #endif + #endif + + #define HAVE_FMOD 1 /* have fmod(), otherwise use modf() */ + + #define HAVE_MEMCPY 1 /* have memcpy() et al. */ + + #define HAVE_ST_BLKSIZE 1 /* have st_blksize member in the stat(2) structure */ + + #define HAVE_STRFTIME 1 + + #define HAVE_STRINGIZE 1 /* have ANSI "stringizing" capability */ + + #undef __CHAR_UNSIGNED__ /* default char is signed */ + + #define RETSIGTYPE void /* type used in signal() */ + #define SPRINTF_RET int /* type returned by sprintf() */ + + #undef _ALL_SOURCE /* on AIX, used to get some BSD functions */ + /* + * srandom already has a prototype defined - don't redefine it + */ + #define SRANDOM_PROTO 1 + + #undef _POSIX_SOURCE /* on Minix, used to get Posix functions */ + #undef _MINIX /* on Minix, used to get Posix functions */ + #undef _POSIX_1_SOURCE /* on Minix, define to 2 */ + + + diff -crN gawk-2.15.2/atari/mkconf.g gawk-2.15.3/atari/mkconf.g *** gawk-2.15.2/atari/mkconf.g Fri Oct 23 15:34:31 1992 --- gawk-2.15.3/atari/mkconf.g Thu Oct 21 22:51:35 1993 *************** *** 5,18 **** # if { -e ..\config\atari } sed -n -f mkscrpt.sed ..\config\atari > sedscr ! sed -f sedscr ..\config.h-d > config.h sed -n '/^#echo./s///p' ..\config\atari rm sedscr mv config.h .. ef echo "'..\config\atari' was lost somewhere" echo "Either construct one based on the examples in the config directory," ! echo "or, in source directory, copy config.h-dist to config.h and edit it." exit 1 endif exit 0 --- 5,18 ---- # if { -e ..\config\atari } sed -n -f mkscrpt.sed ..\config\atari > sedscr ! sed -f sedscr ..\config.in > config.h sed -n '/^#echo./s///p' ..\config\atari rm sedscr mv config.h .. ef echo "'..\config\atari' was lost somewhere" echo "Either construct one based on the examples in the config directory," ! echo "or, in source directory, copy config.in to config.h and edit it." exit 1 endif exit 0 diff -crN gawk-2.15.2/atari/system.c gawk-2.15.3/atari/system.c *** gawk-2.15.2/atari/system.c Tue Jul 28 08:32:36 1992 --- gawk-2.15.3/atari/system.c Tue Nov 2 06:30:48 1993 *************** *** 19,34 **** #define _COOKIE(x) puts(x);putchar('\n') #endif ! void static parse_args(char *cmdln, register char **argv) { register char *p; static char delim[] = " \t\r\n"; ! if(p = strtok(cmdln, delim)) { do { *argv++ = p; ! } while(p = strtok(NULL, delim)); } } --- 19,34 ---- #define _COOKIE(x) puts(x);putchar('\n') #endif ! static void parse_args(char *cmdln, register char **argv) { register char *p; static char delim[] = " \t\r\n"; ! if(NULL != (p = strtok(cmdln, delim))) { do { *argv++ = p; ! } while(NULL != (p = strtok(NULL, delim))); } } diff -crN gawk-2.15.2/awk.h gawk-2.15.3/awk.h *** gawk-2.15.2/awk.h Sat May 1 21:38:58 1993 --- gawk-2.15.3/awk.h Sun Nov 7 10:51:52 1993 *************** *** 31,37 **** #include #include #include ! #if !defined(errno) && !defined(MSDOS) extern int errno; #endif #ifdef __GNU_LIBRARY__ --- 31,37 ---- #include #include #include ! #if !defined(errno) && !defined(MSDOS) && !defined(OS2) extern int errno; #endif #ifdef __GNU_LIBRARY__ *************** *** 88,94 **** #if defined(atarist) || defined(VMS) #include #else /* atarist || VMS */ ! #ifndef MSDOS #include #endif /* MSDOS */ #endif /* atarist || VMS */ --- 88,94 ---- #if defined(atarist) || defined(VMS) #include #else /* atarist || VMS */ ! #if !defined(MSDOS) && !defined(_MSC_VER) #include #endif /* MSDOS */ #endif /* atarist || VMS */ *************** *** 111,117 **** --- 111,121 ---- #endif #else /* not sparc */ #if !defined(alloca) && !defined(ALLOCA_PROTO) + #if defined(_MSC_VER) + #include + #else extern char *alloca(); + #endif /* _MSC_VER */ #endif #endif /* sparc */ #endif /* __GNUC__ */ *************** *** 158,171 **** extern int fileno P((FILE *)); #endif extern int close(), dup(), dup2(), fstat(), read(), stat(); #endif /*VMS*/ - #ifdef MSDOS - #include - extern FILE *popen P((char *, char *)); - extern int pclose P((FILE *)); - #endif - #define GNU_REGEX #ifdef GNU_REGEX #include "regex.h" --- 162,170 ---- extern int fileno P((FILE *)); #endif extern int close(), dup(), dup2(), fstat(), read(), stat(); + extern int getpgrp P((void)); #endif /*VMS*/ #define GNU_REGEX #ifdef GNU_REGEX #include "regex.h" *************** *** 184,189 **** --- 183,191 ---- #ifdef atarist #define read _text_read /* we do not want all these CR's to mess our input */ extern int _text_read (int, char *, int); + #ifndef __MINT__ + #undef NGROUPS_MAX + #endif /* __MINT__ */ #endif #ifndef DEFPATH *************** *** 362,368 **** struct { struct exp_node *next; char *name; ! int length; struct exp_node *value; } hash; #define hnext sub.hash.next --- 364,370 ---- struct { struct exp_node *next; char *name; ! size_t length; struct exp_node *value; } hash; #define hnext sub.hash.next *************** *** 430,436 **** int primes[] = {31, 61, 127, 257, 509, 1021, 2053, 4099, 8191, 16381}; #endif /* a quick profile suggests that the following is a good value */ ! #define HASHSIZE 127 typedef struct for_loop_header { NODE *init; --- 432,438 ---- int primes[] = {31, 61, 127, 257, 509, 1021, 2053, 4099, 8191, 16381}; #endif /* a quick profile suggests that the following is a good value */ ! #define HASHSIZE 1021 typedef struct for_loop_header { NODE *init; *************** *** 558,564 **** --- 560,570 ---- #ifdef DEBUG #define tree_eval(t) r_tree_eval(t) + #define get_lhs(p, a) r_get_lhs((p), (a)) + #undef freenode #else + #define get_lhs(p, a) ((p)->type == Node_var ? (&(p)->var_value) : \ + r_get_lhs((p), (a))) #define tree_eval(t) (_t = (t),(_t) == NULL ? Nnull_string : \ ((_t)->type == Node_val ? (_t) : \ ((_t)->type == Node_var ? (_t)->var_value : \ *************** *** 567,574 **** r_tree_eval((_t)))))) #endif ! #define make_number(x) mk_number((x), (MALLOC|NUM|NUMBER)) ! #define tmp_number(x) mk_number((x), (MALLOC|TEMP|NUM|NUMBER)) #define free_temp(n) do {if ((n)->flags&TEMP) { unref(n); }} while (0) #define make_string(s,l) make_str_node((s), SZTC (l),0) --- 573,580 ---- r_tree_eval((_t)))))) #endif ! #define make_number(x) mk_number((x), (unsigned int)(MALLOC|NUM|NUMBER)) ! #define tmp_number(x) mk_number((x), (unsigned int)(MALLOC|TEMP|NUM|NUMBER)) #define free_temp(n) do {if ((n)->flags&TEMP) { unref(n); }} while (0) #define make_string(s,l) make_str_node((s), SZTC (l),0) *************** *** 620,626 **** /* array.c */ extern NODE *concat_exp P((NODE *tree)); extern void assoc_clear P((NODE *symbol)); ! extern unsigned int hash P((char *s, int len)); extern int in_array P((NODE *symbol, NODE *subs)); extern NODE **assoc_lookup P((NODE *symbol, NODE *subs)); extern void do_delete P((NODE *symbol, NODE *tree)); --- 626,632 ---- /* array.c */ extern NODE *concat_exp P((NODE *tree)); extern void assoc_clear P((NODE *symbol)); ! extern unsigned int hash P((char *s, size_t len)); extern int in_array P((NODE *symbol, NODE *subs)); extern NODE **assoc_lookup P((NODE *symbol, NODE *subs)); extern void do_delete P((NODE *symbol, NODE *tree)); *************** *** 663,669 **** extern int interpret P((NODE *volatile tree)); extern NODE *r_tree_eval P((NODE *tree)); extern int cmp_nodes P((NODE *t1, NODE *t2)); ! extern NODE **get_lhs P((NODE *ptr, Func_ptr *assign)); extern void set_IGNORECASE P((void)); void set_OFS P((void)); void set_ORS P((void)); --- 669,675 ---- extern int interpret P((NODE *volatile tree)); extern NODE *r_tree_eval P((NODE *tree)); extern int cmp_nodes P((NODE *t1, NODE *t2)); ! extern NODE **r_get_lhs P((NODE *ptr, Func_ptr *assign)); extern void set_IGNORECASE P((void)); void set_OFS P((void)); void set_ORS P((void)); *************** *** 702,714 **** extern char *arg_assign P((char *arg)); extern SIGTYPE catchsig P((int sig, int code)); /* msg.c */ ! #ifdef MSDOS ! extern void err P((char *s, char *emsg, char *va_list, ...)); ! extern void msg P((char *va_alist, ...)); ! extern void warning P((char *va_alist, ...)); ! extern void fatal P((char *va_alist, ...)); #else - extern void err (); extern void msg (); extern void warning (); extern void fatal (); --- 708,719 ---- extern char *arg_assign P((char *arg)); extern SIGTYPE catchsig P((int sig, int code)); /* msg.c */ ! extern void err P((char *s, char *emsg, va_list argp)); ! #if _MSC_VER == 510 ! extern void msg P((va_list va_alist, ...)); ! extern void warning P((va_list va_alist, ...)); ! extern void fatal P((va_list va_alist, ...)); #else extern void msg (); extern void warning (); extern void fatal (); diff -crN gawk-2.15.2/awk.y gawk-2.15.3/awk.y *** gawk-2.15.2/awk.y Tue May 18 12:34:03 1993 --- gawk-2.15.3/awk.y Sat Nov 6 22:20:03 1993 *************** *** 116,121 **** --- 116,122 ---- %left LEX_GETLINE %nonassoc LEX_IN %left FUNC_CALL LEX_BUILTIN LEX_LENGTH + %nonassoc ',' %nonassoc MATCHOP %nonassoc RELOP '<' '>' '|' APPEND_OP %left CONCAT_OP *************** *** 276,282 **** pattern : exp { $$ = $1; } ! | exp comma exp { $$ = mkrangenode ( node($1, Node_cond_pair, $3) ); } ; --- 277,283 ---- pattern : exp { $$ = $1; } ! | exp ',' exp { $$ = mkrangenode ( node($1, Node_cond_pair, $3) ); } ; *************** *** 1036,1041 **** --- 1037,1052 ---- if (!nextc()) return 0; pushback(); + #ifdef OS2 + /* + * added for OS/2's extproc feature of cmd.exe + * (like #! in BSD sh) + */ + if (strncasecmp(lexptr, "extproc ", 8) == 0) { + while (*lexptr && *lexptr != '\n') + lexptr++; + } + #endif lexeme = lexptr; thisline = NULL; if (want_regexp) { *************** *** 1115,1121 **** sourceline++; goto retry; } else ! yyerror("inappropriate use of backslash"); break; case '$': --- 1126,1132 ---- sourceline++; goto retry; } else ! yyerror("backslash not last character on line"); break; case '$': *************** *** 1638,1644 **** NODE *value; { register NODE *hp; ! register int len, bucket; len = strlen(name); bucket = hash(name, len); --- 1649,1656 ---- NODE *value; { register NODE *hp; ! register size_t len; ! register int bucket; len = strlen(name); bucket = hash(name, len); *************** *** 1659,1665 **** char *name; { register NODE *bucket; ! register int len; len = strlen(name); bucket = variables[hash(name, len)]; --- 1671,1677 ---- char *name; { register NODE *bucket; ! register size_t len; len = strlen(name); bucket = variables[hash(name, len)]; *************** *** 1721,1727 **** int freeit; { register NODE *bucket, **save; ! register int len; char *name; name = np->param; --- 1733,1739 ---- int freeit; { register NODE *bucket, **save; ! register size_t len; char *name; name = np->param; diff -crN gawk-2.15.2/builtin.c gawk-2.15.3/builtin.c *** gawk-2.15.2/builtin.c Tue May 18 12:34:03 1993 --- gawk-2.15.3/builtin.c Sun Nov 7 10:25:05 1993 *************** *** 63,76 **** #define Ceil(n) ceil(n) #endif static void efwrite(ptr, size, count, fp, from, rp, flush) void *ptr; ! unsigned size, count; FILE *fp; char *from; struct redirect *rp; int flush; { errno = 0; if (fwrite(ptr, size, count, fp) != count) --- 63,82 ---- #define Ceil(n) ceil(n) #endif + #if __STDC__ static void + efwrite(void *ptr, size_t size, size_t count, FILE *fp, + char *from, struct redirect *rp,int flush) + #else + static void efwrite(ptr, size, count, fp, from, rp, flush) void *ptr; ! size_t size, count; FILE *fp; char *from; struct redirect *rp; int flush; + #endif { errno = 0; if (fwrite(ptr, size, count, fp) != count) *************** *** 117,123 **** { NODE *s1, *s2; register char *p1, *p2; ! register int l1, l2; long ret; --- 123,129 ---- { NODE *s1, *s2; register char *p1, *p2; ! register size_t l1, l2; long ret; *************** *** 184,190 **** NODE *tree; { NODE *tmp; ! int len; tmp = tree_eval(tree->lnode); len = force_string(tmp)->stlen; --- 190,196 ---- NODE *tree; { NODE *tmp; ! size_t len; tmp = tree_eval(tree->lnode); len = force_string(tmp)->stlen; *************** *** 224,230 **** ofre+=osiz;\ osiz*=2;\ }\ ! memcpy(obuf+olen,s,(l));\ olen+=(l);\ ofre-=(l);\ } --- 230,236 ---- ofre+=osiz;\ osiz*=2;\ }\ ! memcpy(obuf+olen,s,(size_t)(l));\ olen+=(l);\ ofre-=(l);\ } *************** *** 251,257 **** NODE *r; int toofew = 0; char *obuf; ! int osiz, ofre, olen; static char chbuf[] = "0123456789abcdef"; static char sp[] = " "; char *s0, *s1; --- 257,263 ---- NODE *r; int toofew = 0; char *obuf; ! size_t osiz, ofre, olen; static char chbuf[] = "0123456789abcdef"; static char sp[] = " "; char *s0, *s1; *************** *** 275,281 **** char *pr_str; int ucasehex = 0; char signchar = 0; ! int len; emalloc(obuf, char *, 120, "do_sprintf"); --- 281,287 ---- char *pr_str; int ucasehex = 0; char signchar = 0; ! size_t len; emalloc(obuf, char *, 120, "do_sprintf"); *************** *** 391,404 **** dopr_string: if (fw > prec && !lj) { while (fw > prec) { ! bchunk(sp, 1); fw--; } } bchunk(pr_str, (int) prec); if (fw > prec) { while (fw > prec) { ! bchunk(sp, 1); fw--; } } --- 397,410 ---- dopr_string: if (fw > prec && !lj) { while (fw > prec) { ! bchunk(fill, 1); fw--; } } bchunk(pr_str, (int) prec); if (fw > prec) { while (fw > prec) { ! bchunk(fill, 1); fw--; } } *************** *** 654,659 **** --- 660,666 ---- NODE *r; register int indx; size_t length; + int is_long; t1 = tree_eval(tree->lnode); t2 = tree_eval(tree->rnode->lnode); *************** *** 669,680 **** t1 = force_string(t1); if (indx < 0) indx = 0; ! if (indx >= t1->stlen || length <= 0) { free_temp(t1); return Nnull_string; } ! if (indx + length > t1->stlen || LONG_MAX - indx < length) length = t1->stlen - indx; r = tmp_string(t1->stptr + indx, length); free_temp(t1); return r; --- 676,691 ---- t1 = force_string(t1); if (indx < 0) indx = 0; ! if (indx >= t1->stlen || (long) length <= 0) { 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; *************** *** 688,694 **** struct tm *tm; time_t fclock; char buf[100]; - int ret; t1 = force_string(tree_eval(tree->lnode)); --- 699,704 ---- *************** *** 701,709 **** } tm = localtime(&fclock); ! ret = strftime(buf, 100, t1->stptr, tm); ! ! return tmp_string(buf, ret); } NODE * --- 711,717 ---- } tm = localtime(&fclock); ! return tmp_string(buf, strftime(buf, 100, t1->stptr, tm)); } NODE * *************** *** 723,735 **** NODE *tmp; int ret = 0; char *cmd; ! (void) flush_io (); /* so output is synchronous with gawk's */ tmp = tree_eval(tree->lnode); cmd = force_string(tmp)->stptr; if (cmd && *cmd) { ret = system(cmd); ret = (ret >> 8) & 0xff; } free_temp(tmp); return tmp_number((AWKNUM) ret); --- 731,766 ---- NODE *tmp; int ret = 0; char *cmd; + char save; ! (void) flush_io (); /* so output is synchronous with gawk's */ tmp = tree_eval(tree->lnode); cmd = force_string(tmp)->stptr; + if (cmd && *cmd) { + /* insure arg to system is zero-terminated */ + + /* + * From: David Trueman + * To: arnold@cc.gatech.edu (Arnold Robbins) + * Date: Wed, 3 Nov 1993 12:49:41 -0400 + * + * It may not be necessary to save the character, but + * I'm not sure. It would normally be the field + * separator. If the parse has not yet gone beyond + * that, it could mess up (although I doubt it). If + * FIELDWIDTHS is being used, it might be the first + * character of the next field. Unless someone wants + * to check it out exhaustively, I suggest saving it + * for now... + */ + save = cmd[tmp->stlen]; + cmd[tmp->stlen] = '\0'; + ret = system(cmd); ret = (ret >> 8) & 0xff; + + cmd[tmp->stlen] = save; } free_temp(tmp); return tmp_number((AWKNUM) ret); *************** *** 775,786 **** if (tree) { s = OFS; if (OFSlen) ! efwrite(s, sizeof(char), OFSlen, fp, "print", rp, 0); } } s = ORS; if (ORSlen) ! efwrite(s, sizeof(char), ORSlen, fp, "print", rp, 1); } NODE * --- 806,817 ---- if (tree) { s = OFS; if (OFSlen) ! efwrite(s, sizeof(char), (size_t)OFSlen, fp, "print", rp, 0); } } s = ORS; if (ORSlen) ! efwrite(s, sizeof(char), (size_t)ORSlen, fp, "print", rp, 1); } NODE * *************** *** 938,952 **** register char *scan; register char *bp, *cp; char *buf; ! int buflen; register char *matchend; ! register int len; char *matchstart; char *text; ! int textlen; char *repl; char *replend; ! int repllen; int sofar; int ampersands; int matches = 0; --- 969,983 ---- register char *scan; register char *bp, *cp; char *buf; ! size_t buflen; register char *matchend; ! register size_t len; char *matchstart; char *text; ! size_t textlen; char *repl; char *replend; ! size_t repllen; int sofar; int ampersands; int matches = 0; *************** *** 968,976 **** tmp = tree->lnode; t = force_string(tree_eval(tmp)); /* do the search early to avoid work on non-match */ if (research(rp, t->stptr, 0, t->stlen, 1) == -1 || ! (RESTART(rp, t->stptr) > t->stlen) && (matches = 1)) { free_temp(t); return tmp_number((AWKNUM) matches); } --- 999,1008 ---- tmp = tree->lnode; t = force_string(tree_eval(tmp)); + /* XXX - fix this in 2.16 */ /* do the search early to avoid work on non-match */ if (research(rp, t->stptr, 0, t->stlen, 1) == -1 || ! ((RESTART(rp, t->stptr) > t->stlen) && (matches = 1))) { free_temp(t); return tmp_number((AWKNUM) matches); } *************** *** 1007,1013 **** if (*scan == '&') { repllen--; ampersands++; ! } else if (*scan == '\\' && (*(scan+1) == '&' || *(scan+1) == '\\')) { repllen--; scan++; } --- 1039,1045 ---- if (*scan == '&') { repllen--; ampersands++; ! } else if (*scan == '\\' && *(scan+1) == '&') { repllen--; scan++; } *************** *** 1026,1032 **** len = matchstart - text + repllen + ampersands * (matchend - matchstart); sofar = bp - buf; ! while (buflen - sofar - len - 1 < 0) { buflen *= 2; erealloc(buf, char *, buflen, "do_sub"); bp = buf + sofar; --- 1058,1064 ---- len = matchstart - text + repllen + ampersands * (matchend - matchstart); sofar = bp - buf; ! while ((long)(buflen - sofar - len - 1) < 0) { buflen *= 2; erealloc(buf, char *, buflen, "do_sub"); bp = buf + sofar; *************** *** 1037,1043 **** if (*scan == '&') for (cp = matchstart; cp < matchend; cp++) *bp++ = *cp; ! else if (*scan == '\\' && (*(scan+1) == '&' || *(scan+1) == '\\')) { scan++; *bp++ = *scan; } else --- 1069,1075 ---- if (*scan == '&') for (cp = matchstart; cp < matchend; cp++) *bp++ = *cp; ! else if (*scan == '\\' && *(scan+1) == '&') { scan++; *bp++ = *scan; } else *************** *** 1048,1054 **** } textlen = text + textlen - matchend; text = matchend; ! if (!global || textlen <= 0 || research(rp, t->stptr, text-t->stptr, textlen, 1) == -1) break; } --- 1080,1086 ---- } textlen = text + textlen - matchend; text = matchend; ! if (!global || (long)textlen <= 0 || research(rp, t->stptr, text-t->stptr, textlen, 1) == -1) break; } diff -crN gawk-2.15.2/config/hiosf1 gawk-2.15.3/config/hiosf1 *** gawk-2.15.2/config/hiosf1 Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/config/hiosf1 Fri Oct 22 06:16:00 1993 *************** *** 0 **** --- 1,5 ---- + For HITACHI S systems hitm-hitachi-osf1. + RANDOM_MISSING 1 + STDC_HEADERS 1 + CHAR_UNSIGNED 1 + MAKE_CC diff -crN gawk-2.15.2/config/hiuxwe2 gawk-2.15.3/config/hiuxwe2 *** gawk-2.15.2/config/hiuxwe2 Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/config/hiuxwe2 Fri Oct 22 06:16:01 1993 *************** *** 0 **** --- 1,5 ---- + For HITACHI PA-RISC hppa1.0-hitachi-hiuxwe2 systems. + STDC_HEADERS 1 + RANDOM_MISSING 1 + MAKE_ALLOCA_PW + MAKE_CC diff -crN gawk-2.15.2/config/hpux7.0 gawk-2.15.3/config/hpux7.0 *** gawk-2.15.2/config/hpux7.0 Wed Apr 28 21:43:51 1993 --- gawk-2.15.3/config/hpux7.0 Mon Oct 18 09:06:09 1993 *************** *** 6,8 **** --- 6,9 ---- STRCASE_MISSING 1 BSDSTDIO 1 RANDOM_MISSING 1 + GETPGRP_NOARG 1 diff -crN gawk-2.15.2/config/hpux8x gawk-2.15.3/config/hpux8x *** gawk-2.15.2/config/hpux8x Tue May 18 12:34:04 1993 --- gawk-2.15.3/config/hpux8x Mon Oct 18 09:06:24 1993 *************** *** 2,4 **** --- 2,5 ---- STDC_HEADERS 1 RANDOM_MISSING 1 MAKE_ALLOCA_PW + GETPGRP_NOARG 1 diff -crN gawk-2.15.2/config/ibmrt-aos gawk-2.15.3/config/ibmrt-aos *** gawk-2.15.2/config/ibmrt-aos Tue May 18 12:34:04 1993 --- gawk-2.15.3/config/ibmrt-aos Wed Jun 2 20:52:37 1993 *************** *** 1,4 **** ! For generic 4.3 BSD machine. SIGTYPE int HAVE_UNDERSCORE_SETJMP 1 MEMCMP_MISSING 1 --- 1,4 ---- ! For IBM RT running AOS SIGTYPE int HAVE_UNDERSCORE_SETJMP 1 MEMCMP_MISSING 1 Only in gawk-2.15.2/config: msdos diff -crN gawk-2.15.2/config/next21 gawk-2.15.3/config/next21 *** gawk-2.15.2/config/next21 Tue Jul 28 08:32:39 1992 --- gawk-2.15.3/config/next21 Tue Nov 2 06:30:50 1993 *************** *** 1,4 **** ! NeXT running 2.1 STDC_HEADERS 1 ALLOCA_PROTO 1 SZTC (size_t) --- 1,4 ---- ! NeXT running 2.1 or higher STDC_HEADERS 1 ALLOCA_PROTO 1 SZTC (size_t) diff -crN gawk-2.15.2/config/next30 gawk-2.15.3/config/next30 *** gawk-2.15.2/config/next30 Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/config/next30 Tue Nov 2 06:30:51 1993 *************** *** 0 **** --- 1,6 ---- + NeXT running 2.1 or higher + STDC_HEADERS 1 + ALLOCA_PROTO 1 + SZTC (size_t) + INTC (int) + MAKE_NeXT diff -crN gawk-2.15.2/config/sgi405 gawk-2.15.3/config/sgi405 *** gawk-2.15.2/config/sgi405 Tue May 4 20:15:27 1993 --- gawk-2.15.3/config/sgi405 Mon Oct 18 08:59:31 1993 *************** *** 1,4 **** --- 1,5 ---- SGI Personal Iris (Sys V derived) (this works with gcc) BLKSIZE_MISSING 1 STDC_HEADERS 1 + GETPGRP_NOARG 1 MAKE_ALLOCA_C diff -crN gawk-2.15.2/config/sgi405.cc gawk-2.15.3/config/sgi405.cc *** gawk-2.15.2/config/sgi405.cc Wed May 5 19:43:49 1993 --- gawk-2.15.3/config/sgi405.cc Mon Oct 18 08:59:54 1993 *************** *** 2,6 **** --- 2,7 ---- BLKSIZE_MISSING 1 STDC_HEADERS 1 CHAR_UNSIGNED 1 + GETPGRP_NOARG 1 MAKE_CC MAKE_SGI diff -crN gawk-2.15.2/config.in gawk-2.15.3/config.in *** gawk-2.15.2/config.in Wed Sep 23 08:58:22 1992 --- gawk-2.15.3/config.in Mon Oct 18 09:01:45 1993 *************** *** 268,270 **** --- 268,275 ---- * srandom already has a prototype defined - don't redefine it */ /* #define SRANDOM_PROTO 1 */ + + /* + * getpgrp() in sysvr4 and POSIX takes no argument + */ + /* #define GETPGRP_NOARG 0 */ diff -crN gawk-2.15.2/dfa.c gawk-2.15.3/dfa.c *** gawk-2.15.2/dfa.c Sun May 2 21:47:39 1993 --- gawk-2.15.3/dfa.c Tue Nov 2 06:49:08 1993 *************** *** 128,136 **** char * is; } must; ! static ptr_t xcalloc P((int n, size_t s)); ! static ptr_t xmalloc P((size_t n)); ! static ptr_t xrealloc P((ptr_t p, size_t n)); static int tstbit P((int b, _charset c)); static void setbit P((int b, _charset c)); static void clrbit P((int b, _charset c)); --- 128,136 ---- char * is; } must; ! static ptr_t xcalloc P((MALLOC_ARG_T n, MALLOC_ARG_T s)); ! static ptr_t xmalloc P((MALLOC_ARG_T n)); ! static ptr_t xrealloc P((ptr_t p, MALLOC_ARG_T n)); static int tstbit P((int b, _charset c)); static void setbit P((int b, _charset c)); static void clrbit P((int b, _charset c)); *************** *** 170,177 **** static ptr_t xcalloc(n, s) ! int n; ! size_t s; { ptr_t r = calloc(n, s); --- 170,177 ---- static ptr_t xcalloc(n, s) ! MALLOC_ARG_T n; ! MALLOC_ARG_T s; { ptr_t r = calloc(n, s); *************** *** 182,188 **** static ptr_t xmalloc(n) ! size_t n; { ptr_t r = malloc(n); --- 182,188 ---- static ptr_t xmalloc(n) ! MALLOC_ARG_T n; { ptr_t r = malloc(n); *************** *** 195,201 **** static ptr_t xrealloc(p, n) ptr_t p; ! size_t n; { ptr_t r = realloc(p, n); --- 195,201 ---- static ptr_t xrealloc(p, n) ptr_t p; ! MALLOC_ARG_T n; { ptr_t r = realloc(p, n); *************** *** 205,213 **** return r; } ! #define CALLOC(p, t, n) ((p) = (t *) xcalloc((n), sizeof (t))) #undef MALLOC ! #define MALLOC(p, t, n) ((p) = (t *) xmalloc((n) * sizeof (t))) #define REALLOC(p, t, n) ((p) = (t *) xrealloc((ptr_t) (p), (n) * sizeof (t))) /* Reallocate an array of type t if nalloc is too small for index. */ --- 205,213 ---- return r; } ! #define CALLOC(p, t, n) ((p) = (t *) xcalloc((MALLOC_ARG_T)(n), sizeof (t))) #undef MALLOC ! #define MALLOC(p, t, n) ((p) = (t *) xmalloc((MALLOC_ARG_T)(n) * sizeof (t))) #define REALLOC(p, t, n) ((p) = (t *) xrealloc((ptr_t) (p), (n) * sizeof (t))) /* Reallocate an array of type t if nalloc is too small for index. */ *************** *** 1864,1870 **** const char * new; { register char * result; ! register int oldsize, newsize; newsize = (new == NULL) ? 0 : strlen(new); if (old == NULL) --- 1864,1870 ---- const char * new; { register char * result; ! register size_t oldsize, newsize; newsize = (new == NULL) ? 0 : strlen(new); if (old == NULL) *************** *** 1893,1899 **** register char * lookfor; { register char * cp; ! register int len; len = strlen(lookfor); for (cp = lookin; *cp != '\0'; ++cp) --- 1893,1899 ---- register char * lookfor; { register char * cp; ! register size_t len; len = strlen(lookfor); for (cp = lookin; *cp != '\0'; ++cp) *************** *** 2110,2118 **** mp[i] = must0; for (i = 0; i <= reg->tindex; ++i) { mp[i].in = (char **) malloc(sizeof *mp[i].in); ! mp[i].left = malloc(2); ! mp[i].right = malloc(2); ! mp[i].is = malloc(2); if (mp[i].in == NULL || mp[i].left == NULL || mp[i].right == NULL || mp[i].is == NULL) goto done; --- 2110,2118 ---- mp[i] = must0; for (i = 0; i <= reg->tindex; ++i) { mp[i].in = (char **) malloc(sizeof *mp[i].in); ! mp[i].left = malloc((MALLOC_ARG_T)2); ! mp[i].right = malloc((MALLOC_ARG_T)2); ! mp[i].is = malloc((MALLOC_ARG_T)2); if (mp[i].in == NULL || mp[i].left == NULL || mp[i].right == NULL || mp[i].is == NULL) goto done; diff -crN gawk-2.15.2/dfa.h gawk-2.15.3/dfa.h *** gawk-2.15.2/dfa.h Tue Apr 27 22:02:32 1993 --- gawk-2.15.3/dfa.h Mon Jul 19 21:33:13 1993 *************** *** 129,151 **** parentheses are needed for literal searching. 0 means backslash-parentheses are grouping, and plain parentheses are for literal searching. */ #define RE_NO_BK_PARENS 1L /* 1 means plain | serves as the "or"-operator, and \| is a literal. 0 means \| serves as the "or"-operator, and | is a literal. */ ! #define RE_NO_BK_VBAR (1L << 1) /* 0 means plain + or ? serves as an operator, and \+, \? are literals. 1 means \+, \? are operators and plain +, ? are literals. */ ! #define RE_BK_PLUS_QM (1L << 2) /* 1 means | binds tighter than ^ or $. 0 means the contrary. */ ! #define RE_TIGHT_VBAR (1L << 3) /* 1 means treat \n as an _OR operator 0 means treat it as a normal character */ ! #define RE_NEWLINE_OR (1L << 4) /* 0 means that a special characters (such as *, ^, and $) always have their special meaning regardless of the surrounding context. --- 129,161 ---- parentheses are needed for literal searching. 0 means backslash-parentheses are grouping, and plain parentheses are for literal searching. */ + #ifndef RE_NO_BK_PARENS #define RE_NO_BK_PARENS 1L + #endif /* 1 means plain | serves as the "or"-operator, and \| is a literal. 0 means \| serves as the "or"-operator, and | is a literal. */ ! #ifndef RE_NO_BK_VBAR ! #define RE_NO_BK_VBAR (1L << 1) ! #endif /* 0 means plain + or ? serves as an operator, and \+, \? are literals. 1 means \+, \? are operators and plain +, ? are literals. */ ! #ifndef RE_BK_PLUS_QM ! #define RE_BK_PLUS_QM (1L << 2) ! #endif /* 1 means | binds tighter than ^ or $. 0 means the contrary. */ ! #ifndef RE_TIGHT_VBAR ! #define RE_TIGHT_VBAR (1L << 3) ! #endif /* 1 means treat \n as an _OR operator 0 means treat it as a normal character */ ! #ifndef RE_NEWLINE_OR ! #define RE_NEWLINE_OR (1L << 4) ! #endif /* 0 means that a special characters (such as *, ^, and $) always have their special meaning regardless of the surrounding context. *************** *** 154,160 **** ^ - only special at the beginning, or after ( or | $ - only special at the end, or before ) or | *, +, ? - only special when not after the beginning, (, or | */ ! #define RE_CONTEXT_INDEP_OPS (1L << 5) /* 1 means that \ in a character class escapes the next character (typically a hyphen. It also is overloaded to mean that hyphen at the end of the range --- 164,172 ---- ^ - only special at the beginning, or after ( or | $ - only special at the end, or before ) or | *, +, ? - only special when not after the beginning, (, or | */ ! #ifndef RE_CONTEXT_INDEP_OPS ! #define RE_CONTEXT_INDEP_OPS (1L << 5) ! #endif /* 1 means that \ in a character class escapes the next character (typically a hyphen. It also is overloaded to mean that hyphen at the end of the range diff -crN gawk-2.15.2/eval.c gawk-2.15.3/eval.c *** gawk-2.15.2/eval.c Tue Apr 27 22:03:13 1993 --- gawk-2.15.3/eval.c Tue Nov 2 06:33:29 1993 *************** *** 386,396 **** if (tree == NULL) return Nnull_string; if (tree->type == Node_val) { ! if (tree->stref <= 0) cant_happen(); return tree; } if (tree->type == Node_var) { ! if (tree->var_value->stref <= 0) cant_happen(); return tree->var_value; } if (tree->type == Node_param_list) { --- 386,396 ---- if (tree == NULL) return Nnull_string; if (tree->type == Node_val) { ! if ((char)tree->stref <= 0) cant_happen(); return tree; } if (tree->type == Node_var) { ! if ((char)tree->var_value->stref <= 0) cant_happen(); return tree->var_value; } if (tree->type == Node_param_list) { *************** *** 489,520 **** case Node_concat: { #define STACKSIZE 10 ! NODE *stack[STACKSIZE]; ! register NODE **sp; ! register int len; char *str; register char *dest; ! sp = stack; ! len = 0; while (tree->type == Node_concat) { ! *sp = force_string(tree_eval(tree->lnode)); ! tree = tree->rnode; ! len += (*sp)->stlen; ! if (++sp == &stack[STACKSIZE-2]) /* one more and NULL */ break; } ! *sp = force_string(tree_eval(tree)); ! len += (*sp)->stlen; ! *++sp = NULL; emalloc(str, char *, len+2, "tree_eval"); dest = str; ! sp = stack; ! while (*sp) { ! memcpy(dest, (*sp)->stptr, (*sp)->stlen); ! dest += (*sp)->stlen; ! free_temp(*sp); ! sp++; } r = make_str_node(str, len, ALREADY_MALLOCED); r->flags |= TEMP; --- 489,539 ---- case Node_concat: { #define STACKSIZE 10 ! NODE *treelist[STACKSIZE+1]; ! NODE *strlist[STACKSIZE+1]; ! register NODE **treep; ! register NODE **strp; ! register size_t len; char *str; register char *dest; ! /* ! * This is an efficiency hack for multiple adjacent string ! * concatenations, to avoid recursion and string copies. ! * ! * Node_concat trees grow downward to the left, so ! * descend to lowest (first) node, accumulating nodes ! * to evaluate to strings as we go. ! */ ! treep = treelist; while (tree->type == Node_concat) { ! *treep++ = tree->rnode; ! tree = tree->lnode; ! if (treep == &treelist[STACKSIZE]) break; } ! *treep = tree; ! /* ! * Now, evaluate to strings in LIFO order, accumulating ! * the string length, so we can do a single malloc at the ! * end. ! */ ! strp = strlist; ! len = 0; ! while (treep >= treelist) { ! *strp = force_string(tree_eval(*treep--)); ! len += (*strp)->stlen; ! strp++; ! } ! *strp = NULL; emalloc(str, char *, len+2, "tree_eval"); dest = str; ! strp = strlist; ! while (*strp) { ! memcpy(dest, (*strp)->stptr, (*strp)->stlen); ! dest += (*strp)->stlen; ! free_temp(*strp); ! strp++; } r = make_str_node(str, len, ALREADY_MALLOCED); r->flags |= TEMP; *************** *** 696,702 **** register NODE *t1, *t2; { register int ret; ! register int len1, len2; if (t1 == t2) return 0; --- 715,721 ---- register NODE *t1, *t2; { register int ret; ! register size_t len1, len2; if (t1 == t2) return 0; *************** *** 985,991 **** */ NODE ** ! get_lhs(ptr, assign) register NODE *ptr; Func_ptr *assign; { --- 1004,1010 ---- */ NODE ** ! r_get_lhs(ptr, assign) register NODE *ptr; Func_ptr *assign; { *************** *** 998,1004 **** case Node_var: aptr = &(ptr->var_value); #ifdef DEBUG ! if (ptr->var_value->stref <= 0) cant_happen(); #endif break; --- 1017,1023 ---- case Node_var: aptr = &(ptr->var_value); #ifdef DEBUG ! if ((char)ptr->var_value->stref <= 0) cant_happen(); #endif break; diff -crN gawk-2.15.2/field.c gawk-2.15.3/field.c *** gawk-2.15.2/field.c Sat May 1 23:08:21 1993 --- gawk-2.15.3/field.c Tue Nov 2 06:34:11 1993 *************** *** 112,124 **** static void rebuild_record() { ! register int tlen; register NODE *tmp; NODE *ofs; char *ops; register char *cops; register NODE **ptr; ! register int ofslen; tlen = 0; ofs = force_string(OFS_node->var_value); --- 112,124 ---- static void rebuild_record() { ! register size_t tlen; register NODE *tmp; NODE *ofs; char *ops; register char *cops; register NODE **ptr; ! register size_t ofslen; tlen = 0; ofs = force_string(OFS_node->var_value); *************** *** 130,136 **** ptr--; } tlen += (NF - 1) * ofslen; ! if (tlen < 0) tlen = 0; emalloc(ops, char *, tlen + 2, "fix_fields"); cops = ops; --- 130,136 ---- ptr--; } tlen += (NF - 1) * ofslen; ! if ((long)tlen < 0) tlen = 0; emalloc(ops, char *, tlen + 2, "fix_fields"); cops = ops; *************** *** 249,261 **** if (REEND(rp, scan) == RESTART(rp, scan)) { /* null match */ scan++; if (scan == end) { ! (*set)(++nf, field, scan - field, n); up_to = nf; break; } continue; } ! (*set)(++nf, field, scan + RESTART(rp, scan) - field, n); scan += REEND(rp, scan); field = scan; if (scan == end) /* FS at end of record */ --- 249,262 ---- if (REEND(rp, scan) == RESTART(rp, scan)) { /* null match */ scan++; if (scan == end) { ! (*set)(++nf, field, (int)(scan - field), n); up_to = nf; break; } continue; } ! (*set)(++nf, field, ! (int)(scan + RESTART(rp, scan) - field), n); scan += REEND(rp, scan); field = scan; if (scan == end) /* FS at end of record */ *************** *** 557,563 **** void set_FS() { - NODE *tmp = NULL; char buf[10]; NODE *fs; --- 558,563 ---- diff -crN gawk-2.15.2/gawk.1 gawk-2.15.3/gawk.1 *** gawk-2.15.2/gawk.1 Wed May 19 11:24:51 1993 --- gawk-2.15.3/gawk.1 Thu Nov 4 06:21:01 1993 *************** *** 1,7 **** .ds PX \s-1POSIX\s+1 .ds UX \s-1UNIX\s+1 .ds AN \s-1ANSI\s+1 ! .TH GAWK 1 "Apr 15 1993" "Free Software Foundation" "Utility Commands" .SH NAME gawk \- pattern scanning and processing language .SH SYNOPSIS --- 1,7 ---- .ds PX \s-1POSIX\s+1 .ds UX \s-1UNIX\s+1 .ds AN \s-1ANSI\s+1 ! .TH GAWK 1 "Nov 4 1993" "Free Software Foundation" "Utility Commands" .SH NAME gawk \- pattern scanning and processing language .SH SYNOPSIS *************** *** 505,510 **** --- 505,515 ---- If no files are specified on the command line, the value of .B FILENAME is ``\-''. + However, + .B FILENAME + is undefined inside the + .B BEGIN + block. .TP .B FNR The input record number in the current input file. diff -crN gawk-2.15.2/getopt.c gawk-2.15.3/getopt.c *** gawk-2.15.2/getopt.c Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/getopt.c Tue Nov 2 06:39:47 1993 *************** *** 0 **** --- 1,757 ---- + /* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu + before changing it! + + Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #ifdef HAVE_CONFIG_H + #if defined (emacs) || defined (CONFIG_BROKETS) + /* We use instead of "config.h" so that a compilation + using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h + (which it would do because it found this file in $srcdir). */ + #include + #else + #include "config.h" + #endif + #endif + + #ifndef __STDC__ + /* This is a separate conditional since some stdc systems + reject `defined (const)'. */ + #ifndef const + #define const + #endif + #endif + + /* This tells Alpha OSF/1 not to define a getopt prototype in . */ + #ifndef _NO_PROTO + #define _NO_PROTO + #endif + + #include + + /* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + + #if defined (_LIBC) || !defined (__GNU_LIBRARY__) + + + /* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ + #if defined(__GNU_LIBRARY__) || defined(OS2) || defined(MSDOS) || defined(atarist) + /* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ + #include + #endif /* GNU C library. */ + + /* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a + long-named option. Because this is not POSIX.2 compliant, it is + being phased out. */ + /* #define GETOPT_COMPAT */ + + /* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + + #include "getopt.h" + + /* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + + char *optarg = 0; + + /* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns EOF, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + + /* XXX 1003.2 says this must be 1 before any call. */ + int optind = 0; + + /* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + + static char *nextchar; + + /* Callers store zero here to inhibit the error message + for unrecognized options. */ + + int opterr = 1; + + /* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + + int optopt = '?'; + + /* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return EOF with `optind' != ARGC. */ + + static enum + { + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER + } ordering; + + #if defined(__GNU_LIBRARY__) || defined(OS2) || defined(MSDOS) || defined(atarist) + /* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ + #include + #define my_index strchr + #else + + /* Avoid depending on library functions or files + whose names are inconsistent. */ + + char *getenv (); + + static char * + my_index (str, chr) + const char *str; + int chr; + { + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; + } + + /* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. + (Supposedly there are some machines where it might get a warning, + but changing this conditional to __STDC__ is too risky.) */ + #ifdef __GNUC__ + #ifdef IN_GCC + #include "gstddef.h" + #else + #include + #endif + extern size_t strlen (const char *); + #endif + + #endif /* GNU C library. */ + + /* Handle permutation of arguments. */ + + /* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + + static int first_nonopt; + static int last_nonopt; + + /* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + + static void + exchange (argv) + char **argv; + { + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; + } + + /* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns `EOF'. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + + int + _getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; + { + int option_index; + + optarg = 0; + + /* Initialize the internal data when the first call is made. + Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + if (optind == 0) + { + first_nonopt = last_nonopt = optind = 1; + + nextchar = NULL; + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (getenv ("POSIXLY_CORRECT") != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + } + + if (nextchar == NULL || *nextchar == '\0') + { + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Now skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc + && (argv[optind][0] != '-' || argv[optind][1] == '\0') + #ifdef GETOPT_COMPAT + && (longopts == NULL + || argv[optind][0] != '+' || argv[optind][1] == '\0') + #endif /* GETOPT_COMPAT */ + ) + optind++; + last_nonopt = optind; + } + + /* Special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return EOF; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if ((argv[optind][0] != '-' || argv[optind][1] == '\0') + #ifdef GETOPT_COMPAT + && (longopts == NULL + || argv[optind][0] != '+' || argv[optind][1] == '\0') + #endif /* GETOPT_COMPAT */ + ) + { + if (ordering == REQUIRE_ORDER) + return EOF; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Start decoding its characters. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + if (longopts != NULL + && ((argv[optind][0] == '-' + && (argv[optind][1] == '-' || long_only)) + #ifdef GETOPT_COMPAT + || argv[optind][0] == '+' + #endif /* GETOPT_COMPAT */ + )) + { + const struct option *p; + char *s = nextchar; + int exact = 0; + int ambig = 0; + const struct option *pfound = NULL; + int indfound; + + while (*s && *s != '=') + s++; + + /* Test all options for either exact match or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; + p++, option_index++) + if (!strncmp (p->name, nextchar, s - nextchar)) + { + if (s - 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 nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (opterr) + fprintf (stderr, "%s: option `%s' is ambiguous\n", + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*s) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = s + 1; + else + { + if (opterr) + { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + "%s: option `--%s' doesn't allow an argument\n", + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + "%s: option `%c%s' doesn't allow an argument\n", + argv[0], argv[optind - 1][0], pfound->name); + } + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + fprintf (stderr, "%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; + } + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + #ifdef GETOPT_COMPAT + || argv[optind][0] == '+' + #endif /* GETOPT_COMPAT */ + || my_index (optstring, *nextchar) == NULL) + { + if (opterr) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, "%s: unrecognized option `--%s'\n", + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, "%s: unrecognized option `%c%s'\n", + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + return '?'; + } + } + + /* Look at and handle the next option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (opterr) + { + #if 0 + if (c < 040 || c >= 0177) + fprintf (stderr, "%s: unrecognized option, character code 0%o\n", + argv[0], c); + else + fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c); + #else + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); + #endif + } + optopt = c; + return '?'; + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = 0; + nextchar = NULL; + } + else + { + /* 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) + { + #if 0 + fprintf (stderr, "%s: option `-%c' requires an argument\n", + argv[0], c); + #else + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, "%s: option requires an argument -- %c\n", + argv[0], c); + #endif + } + 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++]; + nextchar = NULL; + } + } + return c; + } + } + + int + getopt (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; + { + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); + } + + #endif /* _LIBC or not __GNU_LIBRARY__. */ + + #ifdef TEST + + /* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + + int + main (argc, argv) + int argc; + char **argv; + { + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == EOF) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); + } + + #endif /* TEST */ diff -crN gawk-2.15.2/getopt.h gawk-2.15.3/getopt.h *** gawk-2.15.2/getopt.h Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/getopt.h Mon Oct 18 22:31:49 1993 *************** *** 0 **** --- 1,129 ---- + /* Declarations for getopt. + Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #ifndef _GETOPT_H + #define _GETOPT_H 1 + + #ifdef __cplusplus + extern "C" { + #endif + + /* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + + extern char *optarg; + + /* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns EOF, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + + extern int optind; + + /* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + + extern int opterr; + + /* Set to an option character which was unrecognized. */ + + extern int optopt; + + /* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + + struct option + { + #if __STDC__ + const char *name; + #else + char *name; + #endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; + }; + + /* Names for the values of the `has_arg' field of `struct option'. */ + + #define no_argument 0 + #define required_argument 1 + #define optional_argument 2 + + #if __STDC__ + #if defined(__GNU_LIBRARY__) + /* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ + extern int getopt (int argc, char *const *argv, const char *shortopts); + #else /* not __GNU_LIBRARY__ */ + extern int getopt (); + #endif /* not __GNU_LIBRARY__ */ + extern int getopt_long (int argc, char *const *argv, const char *shortopts, + const struct option *longopts, int *longind); + extern int getopt_long_only (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind); + + /* Internal only. Users should not call this directly. */ + extern int _getopt_internal (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind, + int long_only); + #else /* not __STDC__ */ + extern int getopt (); + extern int getopt_long (); + extern int getopt_long_only (); + + extern int _getopt_internal (); + #endif /* not __STDC__ */ + + #ifdef __cplusplus + } + #endif + + #endif /* _GETOPT_H */ diff -crN gawk-2.15.2/getopt1.c gawk-2.15.3/getopt1.c *** gawk-2.15.2/getopt1.c Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/getopt1.c Tue Nov 2 06:41:18 1993 *************** *** 0 **** --- 1,187 ---- + /* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #ifdef HAVE_CONFIG_H + #if defined (emacs) || defined (CONFIG_BROKETS) + /* We use instead of "config.h" so that a compilation + using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h + (which it would do because it found this file in $srcdir). */ + #include + #else + #include "config.h" + #endif + #endif + + #include "getopt.h" + + #ifndef __STDC__ + /* This is a separate conditional since some stdc systems + reject `defined (const)'. */ + #ifndef const + #define const + #endif + #endif + + #include + + /* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + + #if defined (_LIBC) || !defined (__GNU_LIBRARY__) + + + /* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ + #if defined(__GNU_LIBRARY__) || defined(OS2) || defined(MSDOS) || defined(atarist) + #include + #else + char *getenv (); + #endif + + #ifndef NULL + #define NULL 0 + #endif + + int + getopt_long (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; + { + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); + } + + /* Like getopt_long, but '-' as well as '--' can indicate a long option. + If an option that starts with '-' (not '--') doesn't match a long option, + but does match a short option, it is parsed as a short option + instead. */ + + int + getopt_long_only (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; + { + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); + } + + + #endif /* _LIBC or not __GNU_LIBRARY__. */ + + #ifdef TEST + + #include + + int + main (argc, argv) + int argc; + char **argv; + { + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = + { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == EOF) + break; + + switch (c) + { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case 'd': + printf ("option d with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); + } + + #endif /* TEST */ diff -crN gawk-2.15.2/io.c gawk-2.15.3/io.c *** gawk-2.15.2/io.c Tue May 18 12:34:04 1993 --- gawk-2.15.3/io.c Sun Nov 7 10:38:53 1993 *************** *** 23,28 **** --- 23,31 ---- * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + #if !defined(VMS) && !defined(VMS_POSIX) && !defined(_MSC_VER) + #include + #endif #include "awk.h" #ifndef O_RDONLY *************** *** 39,45 **** #define INVALID_HANDLE (__SMALLEST_VALID_HANDLE - 1) #endif ! #if defined(MSDOS) || defined(atarist) #define PIPES_SIMULATED #endif --- 42,48 ---- #define INVALID_HANDLE (__SMALLEST_VALID_HANDLE - 1) #endif ! #if defined(MSDOS) || defined(OS2) || defined(atarist) #define PIPES_SIMULATED #endif *************** *** 56,64 **** --- 59,84 ---- static IOBUF *iop_open P((char *file, char *how)); static int gawk_pclose P((struct redirect *rp)); static int do_pathopen P((char *file)); + static int str2mode P((char *mode)); + static void spec_setup P((IOBUF *iop, int len, int allocate)); + static int specfdopen P((IOBUF *iop, char *name, char *mode)); + static int pidopen P((IOBUF *iop, char *name, char *mode)); + static int useropen P((IOBUF *iop, char *name, char *mode)); extern FILE *fdopen(); + + #if defined (MSDOS) + #include "popen.h" + #define popen(c,m) os_popen(c,m) + #define pclose(f) os_pclose(f) + #elif defined (OS2) /* OS/2, but not family mode */ + #if defined (_MSC_VER) + #define popen(c,m) _popen(c,m) + #define pclose(f) _pclose(f) + #endif + #else extern FILE *popen(); + #endif static struct redirect *red_head = NULL; *************** *** 87,93 **** static int i = 1; static int files = 0; NODE *arg; - int fd = INVALID_HANDLE; static IOBUF *curfile = NULL; if (skipping) { --- 107,112 ---- *************** *** 121,128 **** /* NOTREACHED */ /* This is a kludge. */ unref(FILENAME_node->var_value); ! FILENAME_node->var_value = ! dupnode(arg); FNR = 0; i++; break; --- 140,146 ---- /* NOTREACHED */ /* This is a kludge. */ unref(FILENAME_node->var_value); ! FILENAME_node->var_value = dupnode(arg); FNR = 0; i++; break; *************** *** 131,138 **** if (files == 0) { files++; /* no args. -- use stdin */ - /* FILENAME is init'ed to "-" */ /* FNR is init'ed to 0 */ curfile = iop_alloc(fileno(stdin)); } return curfile; --- 149,156 ---- if (files == 0) { files++; /* no args. -- use stdin */ /* FNR is init'ed to 0 */ + FILENAME_node->var_value = make_string("-", 1); curfile = iop_alloc(fileno(stdin)); } return curfile; *************** *** 544,563 **** int status = 0; errno = 0; - if (fclose(stdout)) { - warning("error writing standard output (%s).", strerror(errno)); - status++; - } - if (fclose(stderr)) { - warning("error writing standard error (%s).", strerror(errno)); - status++; - } for (rp = red_head; rp != NULL; rp = next) { next = rp->next; if (close_redir(rp)) status++; rp = NULL; } return status; } --- 562,587 ---- int status = 0; errno = 0; for (rp = red_head; rp != NULL; rp = next) { next = rp->next; + /* close_redir() will print a message if needed */ if (close_redir(rp)) status++; rp = NULL; } + /* + * Some of the non-Unix os's have problems doing an fclose + * on stdout and stderr. Since we don't really need to close + * them, we just flush them, and do that across the board. + */ + if (fflush(stdout)) { + warning("error writing standard output (%s).", strerror(errno)); + status++; + } + if (fflush(stderr)) { + warning("error writing standard error (%s).", strerror(errno)); + status++; + } return status; } *************** *** 647,653 **** /* spec_setup --- setup an IOBUF for a special internal file */ ! void spec_setup(iop, len, allocate) IOBUF *iop; int len; --- 671,677 ---- /* spec_setup --- setup an IOBUF for a special internal file */ ! static void spec_setup(iop, len, allocate) IOBUF *iop; int len; *************** *** 674,680 **** /* specfdopen --- open a fd special file */ ! int specfdopen(iop, name, mode) IOBUF *iop; char *name, *mode; --- 698,704 ---- /* specfdopen --- open a fd special file */ ! static int specfdopen(iop, name, mode) IOBUF *iop; char *name, *mode; *************** *** 694,702 **** return 0; } /* pidopen --- "open" /dev/pid, /dev/ppid, and /dev/pgrpid */ ! int pidopen(iop, name, mode) IOBUF *iop; char *name, *mode; --- 718,751 ---- return 0; } + /* + * Following mess will improve in 2.16; this is written to avoid + * long lines, avoid splitting #if with backslash, and avoid #elif + * to maximize portability. + */ + #ifndef GETPGRP_NOARG + #if defined(__svr4__) || defined(BSD4_4) || defined(_POSIX_SOURCE) + #define GETPGRP_NOARG + #else + #if defined(i860) || defined(_AIX) || defined(hpux) || defined(VMS) + #define GETPGRP_NOARG + #else + #if defined(OS2) || defined(MSDOS) || defined(AMIGA) || defined(atarist) + #define GETPGRP_NOARG + #endif + #endif + #endif + #endif + + #ifdef GETPGRP_NOARG + #define getpgrp_ARG /* nothing */ + #else + #define getpgrp_ARG getpid() + #endif + /* pidopen --- "open" /dev/pid, /dev/ppid, and /dev/pgrpid */ ! static int pidopen(iop, name, mode) IOBUF *iop; char *name, *mode; *************** *** 705,716 **** int i; if (name[6] == 'g') ! /* following #if will improve in 2.16 */ ! #if defined(__svr4__) || defined(i860) || defined(_AIX) || defined(BSD4_4) ! sprintf(tbuf, "%d\n", getpgrp()); ! #else ! sprintf(tbuf, "%d\n", getpgrp(getpid())); ! #endif else if (name[6] == 'i') sprintf(tbuf, "%d\n", getpid()); else --- 754,760 ---- int i; if (name[6] == 'g') ! sprintf(tbuf, "%d\n", getpgrp( getpgrp_ARG )); else if (name[6] == 'i') sprintf(tbuf, "%d\n", getpid()); else *************** *** 733,739 **** * supplementary group set. */ ! int useropen(iop, name, mode) IOBUF *iop; char *name, *mode; --- 777,783 ---- * supplementary group set. */ ! static int useropen(iop, name, mode) IOBUF *iop; char *name, *mode; *************** *** 741,747 **** --- 785,795 ---- char tbuf[BUFSIZ], *cp; int i; #if defined(NGROUPS_MAX) && NGROUPS_MAX > 0 + #if defined(atarist) + gid_t groupset[NGROUPS_MAX]; + #else int groupset[NGROUPS_MAX]; + #endif int ngroups; #endif *************** *** 755,761 **** for (i = 0; i < ngroups; i++) { *cp++ = ' '; ! sprintf(cp, "%d", groupset[i]); cp += strlen(cp); } #endif --- 803,809 ---- for (i = 0; i < ngroups; i++) { *cp++ = ' '; ! sprintf(cp, "%d", (int)groupset[i]); cp += strlen(cp); } #endif *************** *** 776,784 **** char *name, *mode; { int openfd = INVALID_HANDLE; - char *cp, *ptr; int flag = 0; - int i; struct stat buf; IOBUF *iop; static struct internal { --- 824,830 ---- *************** *** 939,946 **** #else /* PIPES_SIMULATED */ /* use temporary file rather than pipe */ ! #ifdef VMS static IOBUF * gawk_popen(cmd, rp) char *cmd; --- 985,993 ---- #else /* PIPES_SIMULATED */ /* use temporary file rather than pipe */ + /* except if popen() provides real pipes too */ ! #if defined(VMS) || defined(OS2) || defined (MSDOS) static IOBUF * gawk_popen(cmd, rp) char *cmd; *************** *** 1160,1166 **** if (strchr(file, ':') != strchr(file, ']') || strchr(file, '>') != strchr(file, '/')) #else /*!VMS*/ ! #ifdef MSDOS if (strchr(file, '/') != strchr(file, '\\') || strchr(file, ':') != NULL) #else --- 1207,1213 ---- if (strchr(file, ':') != strchr(file, ']') || strchr(file, '>') != strchr(file, '/')) #else /*!VMS*/ ! #if defined(MSDOS) || defined(OS2) if (strchr(file, '/') != strchr(file, '\\') || strchr(file, ':') != NULL) #else *************** *** 1169,1174 **** --- 1216,1227 ---- #endif /*VMS*/ return (devopen(file, "r")); + #if defined(MSDOS) || defined(OS2) + _searchenv(file, "AWKPATH", trypath); + if (trypath[0] == '\0') + _searchenv(file, "PATH", trypath); + return (trypath[0] == '\0') ? 0 : devopen(trypath, "r"); + #else do { trypath[0] = '\0'; /* this should take into account limits on size of trypath */ *************** *** 1180,1186 **** #ifdef VMS if (strchr(":]>/", *(cp-1)) == NULL) #else ! #ifdef MSDOS if (strchr(":\\/", *(cp-1)) == NULL) #else if (*(cp-1) != '/') --- 1233,1239 ---- #ifdef VMS if (strchr(":]>/", *(cp-1)) == NULL) #else ! #if defined(MSDOS) || defined(OS2) if (strchr(":\\/", *(cp-1)) == NULL) #else if (*(cp-1) != '/') *************** *** 1204,1207 **** --- 1257,1261 ---- * Therefore try to open the file in the current directory. */ return (devopen(file, "r")); + #endif } diff -crN gawk-2.15.2/main.c gawk-2.15.3/main.c *** gawk-2.15.2/main.c Tue May 4 20:17:10 1993 --- gawk-2.15.3/main.c Tue Nov 2 23:23:32 1993 *************** *** 137,144 **** extern int optind; extern int opterr; extern char *optarg; ! int i; (void) signal(SIGFPE, (SIGTYPE (*) P((int))) catchsig); (void) signal(SIGSEGV, (SIGTYPE (*) P((int))) catchsig); #ifdef SIGBUS --- 137,150 ---- extern int optind; extern int opterr; extern char *optarg; ! char *optlist = "+F:f:v:W:"; + #ifdef __EMX__ + _response(&argc, &argv); + _wildcard(&argc, &argv); + setvbuf(stdout, NULL, _IOLBF, BUFSIZ); + #endif + (void) signal(SIGFPE, (SIGTYPE (*) P((int))) catchsig); (void) signal(SIGSEGV, (SIGTYPE (*) P((int))) catchsig); #ifdef SIGBUS *************** *** 183,189 **** opterr = 0; /* the + on the front tells GNU getopt not to rearrange argv */ ! while ((c = getopt_long(argc, argv, "+F:f:v:W:", optab, NULL)) != EOF) { if (do_posix) opterr = 1; switch (c) { --- 189,197 ---- opterr = 0; /* the + on the front tells GNU getopt not to rearrange argv */ ! for (optopt = 0; ! (c = getopt_long(argc, argv, optlist, optab, NULL)) != EOF; ! optopt = 0) { if (do_posix) opterr = 1; switch (c) { *************** *** 254,262 **** * option stops argument processing so that it can * go into ARGV for the awk program to see. This * makes use of ``#! /bin/gawk -f'' easier. */ ! if (! do_posix) goto out; /* else let getopt print error message for us */ break; --- 262,282 ---- * option stops argument processing so that it can * go into ARGV for the awk program to see. This * makes use of ``#! /bin/gawk -f'' easier. + * + * However, it's never simple. If optopt is set, + * an option that requires an argument didn't get the + * argument. We care because if opterr is 0, then + * getopt_long won't print the error message for us. */ ! if (! do_posix ! && (optopt == 0 || strchr(optlist, optopt) == NULL)) { ! optind--; goto out; + } else if (optopt) + /* Use 1003.2 required message format */ + fprintf (stderr, + "%s: option requires an argument -- %c\n", + myname, optopt); /* else let getopt print error message for us */ break; *************** *** 319,333 **** int exitval; { char *opt1 = " -f progfile [--]"; char *opt2 = " [--] 'program'"; char *regops = " [POSIX or GNU style options]"; version(); ! fprintf(stderr, "usage: %s%s%s file ...\n %s%s%s file ...\n", myname, regops, opt1, myname, regops, opt2); /* GNU long options info. Gack. */ ! fputs("\nPOSIX 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); --- 339,357 ---- int exitval; { char *opt1 = " -f progfile [--]"; + #if defined(MSDOS) || defined(OS2) + char *opt2 = " [--] \"program\""; + #else char *opt2 = " [--] 'program'"; + #endif char *regops = " [POSIX or GNU style options]"; version(); ! fprintf(stderr, "Usage: %s%s%s file ...\n\t%s%s%s file ...\n", myname, regops, opt1, myname, regops, opt2); /* 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); *************** *** 446,452 **** {&FS_node, "FS", Node_FS, " ", 0, 0 }, {&RS_node, "RS", Node_RS, "\n", 0, set_RS }, {&IGNORECASE_node, "IGNORECASE", Node_IGNORECASE, 0, 0, set_IGNORECASE }, ! {&FILENAME_node, "FILENAME", Node_var, "-", 0, 0 }, {&OFS_node, "OFS", Node_OFS, " ", 0, set_OFS }, {&ORS_node, "ORS", Node_ORS, "\n", 0, set_ORS }, {&OFMT_node, "OFMT", Node_OFMT, "%.6g", 0, set_OFMT }, --- 470,476 ---- {&FS_node, "FS", Node_FS, " ", 0, 0 }, {&RS_node, "RS", Node_RS, "\n", 0, set_RS }, {&IGNORECASE_node, "IGNORECASE", Node_IGNORECASE, 0, 0, set_IGNORECASE }, ! {&FILENAME_node, "FILENAME", Node_var, "", 0, 0 }, {&OFS_node, "OFS", Node_OFS, " ", 0, set_OFS }, {&ORS_node, "ORS", Node_ORS, "\n", 0, set_ORS }, {&OFMT_node, "OFMT", Node_OFMT, "%.6g", 0, set_OFMT }, *************** *** 477,483 **** void load_environ() { ! #if !defined(MSDOS) && !(defined(VMS) && defined(__DECC)) extern char **environ; #endif register char *var, *val; --- 501,507 ---- void load_environ() { ! #if !defined(MSDOS) && !defined(OS2) && !(defined(VMS) && defined(__DECC)) extern char **environ; #endif register char *var, *val; *************** *** 510,516 **** arg_assign(arg) char *arg; { ! char *cp; Func_ptr after_assign = NULL; NODE *var; NODE *it; --- 534,541 ---- arg_assign(arg) char *arg; { ! char *cp, *cp2; ! int badvar; Func_ptr after_assign = NULL; NODE *var; NODE *it; *************** *** 519,524 **** --- 544,562 ---- cp = strchr(arg, '='); if (cp != NULL) { *cp++ = '\0'; + /* first check that the variable name has valid syntax */ + badvar = 0; + if (! isalpha(arg[0]) && arg[0] != '_') + badvar = 1; + else + for (cp2 = arg+1; *cp2; cp2++) + if (! isalnum(*cp2) && *cp2 != '_') { + badvar = 1; + break; + } + if (badvar) + fatal("illegal name `%s' in variable assignment", arg); + /* * Recent versions of nawk expand escapes inside assignments. * This makes sense, so we do it too. *************** *** 691,728 **** fprintf(stderr, "%s, patchlevel %d\n", version_string, PATCHLEVEL); } ! /* static */ char * gawk_name(filespec) char *filespec; { ! char *p; ! #ifdef VMS /* "device:[root.][directory.subdir]GAWK.EXE;n" -> "GAWK" */ ! char *q; ! p = strrchr(filespec, ']'); /* directory punctuation */ ! q = strrchr(filespec, '>'); /* alternate punct */ ! if (p == NULL || q > p) p = q; p = strdup(p == NULL ? filespec : (p + 1)); if ((q = strrchr(p, '.')) != NULL) *q = '\0'; /* strip .typ;vers */ return p; #endif /*VMS*/ ! #if defined(MSDOS) || defined(atarist) ! char *q; ! p = filespec; ! ! if (q = strrchr(p, '\\')) ! p = q + 1; ! if (q = strchr(p, '.')) ! *q = '\0'; ! strlwr(p); ! return (p == NULL ? filespec : p); #endif /* MSDOS || atarist */ /* "path/name" -> "name" */ --- 729,767 ---- fprintf(stderr, "%s, patchlevel %d\n", version_string, PATCHLEVEL); } ! /* this mess will improve in 2.16 */ char * gawk_name(filespec) char *filespec; { ! char *p; ! #ifdef VMS /* "device:[root.][directory.subdir]GAWK.EXE;n" -> "GAWK" */ ! char *q; ! p = strrchr(filespec, ']'); /* directory punctuation */ ! q = strrchr(filespec, '>'); /* alternate punct */ ! if (p == NULL || q > p) p = q; p = strdup(p == NULL ? filespec : (p + 1)); if ((q = strrchr(p, '.')) != NULL) *q = '\0'; /* strip .typ;vers */ return p; #endif /*VMS*/ ! #if defined(MSDOS) || defined(OS2) || defined(atarist) ! char *q; ! for (p = filespec; (p = strchr(p, '\\')); *p = '/') ! ; ! p = filespec; ! if ((q = strrchr(p, '/'))) ! p = q + 1; ! if ((q = strchr(p, '.'))) ! *q = '\0'; ! strlwr(p); ! return (p == NULL ? filespec : p); #endif /* MSDOS || atarist */ /* "path/name" -> "name" */ diff -crN gawk-2.15.2/missing/strftime.c gawk-2.15.3/missing/strftime.c *** gawk-2.15.2/missing/strftime.c Fri May 7 13:06:24 1993 --- gawk-2.15.3/missing/strftime.c Thu Oct 21 22:51:40 1993 *************** *** 92,98 **** #define range(low, item, hi) max(low, min(item, hi)) ! #if !defined(MSDOS) && !defined(TZNAME_MISSING) extern char *tzname[2]; extern int daylight; #endif --- 92,98 ---- #define range(low, item, hi) max(low, min(item, hi)) ! #if !defined(OS2) && !defined(MSDOS) && !defined(TZNAME_MISSING) extern char *tzname[2]; extern int daylight; #endif diff -crN gawk-2.15.2/missing/strncasecmp.c gawk-2.15.3/missing/strncasecmp.c *** gawk-2.15.2/missing/strncasecmp.c Fri Oct 23 15:30:41 1992 --- gawk-2.15.3/missing/strncasecmp.c Thu Oct 21 22:51:41 1993 *************** *** 19,25 **** --- 19,29 ---- static char sccsid[] = "@(#)strcasecmp.c 5.6 (Berkeley) 6/27/88"; #endif /* LIBC_SCCS and not lint */ + #ifdef atarist + #include + #else #define u_char unsigned char + #endif /* * This array is designed for mapping upper and lower case letter diff -crN gawk-2.15.2/node.c gawk-2.15.3/node.c *** gawk-2.15.2/node.c Tue Apr 27 22:14:55 1993 --- gawk-2.15.3/node.c Thu Jun 3 16:27:24 1993 *************** *** 35,41 **** register char *cpend; char save; char *ptr; ! unsigned int newflags = 0; #ifdef DEBUG if (n == NULL) --- 35,41 ---- register char *cpend; char save; char *ptr; ! unsigned int newflags; #ifdef DEBUG if (n == NULL) *************** *** 69,75 **** if (n->flags & MAYBE_NUM) { newflags = NUMBER; n->flags &= ~MAYBE_NUM; ! } if (cpend - cp == 1) { if (isdigit(*cp)) { n->numbr = (AWKNUM)(*cp - '0'); --- 69,76 ---- if (n->flags & MAYBE_NUM) { newflags = NUMBER; n->flags &= ~MAYBE_NUM; ! } else ! newflags = 0; if (cpend - cp == 1) { if (isdigit(*cp)) { n->numbr = (AWKNUM)(*cp - '0'); diff -crN gawk-2.15.2/patchlevel.h gawk-2.15.3/patchlevel.h *** gawk-2.15.2/patchlevel.h Wed May 19 11:23:23 1993 --- gawk-2.15.3/patchlevel.h Sun Nov 7 10:45:11 1993 *************** *** 1 **** ! #define PATCHLEVEL 2 --- 1 ---- ! #define PATCHLEVEL 3 diff -crN gawk-2.15.2/pc/Makefile.emx gawk-2.15.3/pc/Makefile.emx *** gawk-2.15.2/pc/Makefile.emx Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/pc/Makefile.emx Tue Oct 19 21:58:04 1993 *************** *** 0 **** --- 1,53 ---- + # Makefile for gawk (GNU awk) using EMX/gcc + # + # This makefile is designed to work within the limits of the DOS + # command-line length. OS/2 users can use Makefile.os2, which + # has additional targets. + # + + + CC=gcc -O -s + O=.o + CFLAGS=-DOS2 -DMSDOS + + LFLAGS= + LFLAGS2=gawk-32.def + + #BIND=emxbind -u /emx/bin/emx.exe $@ + BIND= + + OBJ2=getid$O popen$O + + AWKOBJS = main$O eval$O builtin$O msg$O iop$O io$O field$O array$O \ + node$O version$O missing$O re$O + ALLOBJS = $(AWKOBJS) awktab$O + GNUOBJS= getopt$O getopt1$O regex$O dfa$O + + .SUFFIXES: $O .c .y + + .c$O: + $(CC) $(CFLAGS) -DGAWK -c $< + + all: gawk.exe + + gawk.exe: $(ALLOBJS) $(GNUOBJS) $(OBJ2) + $(CC) -o $@ $(LFLAGS) @names2.lnk $(LFLAGS2) + $(BIND) + + $(AWKOBJS): awk.h config.h + dfa$O: awk.h config.h dfa.h + regex$O: awk.h config.h regex.h + main$O: patchlev.h + awktab$O: awk.h awktab.c + + awktab.c: awk.y + bison -o $@ awk.y + + clean: + rm -f *.o core awk.output gmon.out make.out y.output + + .PHONY: test + test: + @echo Both dmake and GNU make require modifications to test/Makefile, + @echo but here we go... + cd test && $(MAKE) -k diff -crN gawk-2.15.2/pc/Makefile.msc gawk-2.15.3/pc/Makefile.msc *** gawk-2.15.2/pc/Makefile.msc Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/pc/Makefile.msc Sun Nov 7 10:42:05 1993 *************** *** 0 **** --- 1,68 ---- + # Makefile for gawk (GNU awk) using Microsoft C + # + # This makefile is designed to work within the limits of the DOS + # command-line length. OS/2 users can use Makefile.os2, which + # has additional targets. + # + + DEFS = -D_MSC_VER + + # For MSC 5.1 + #DEFS = -D_MSC_VER=510 + + # MSC 6.00A has _MSC_VER predefined + #DEFS = + + + #DEBUG = -W3 -Zi -Od + DEBUG= + + MODEL = L + CC=cl -nologo -A$(MODEL) + O=.obj + + # Disable MSC extensions with -Za so that __STDC__ is defined for MSC 6.00A + # MSC 5.1 defines __STDC__=0 regardless of the ANSI flag + CFLAGS = -Za $(DEFS) $(DEBUG) + + #LIBS = /NOD:$(MODEL)libce $(MODEL)libcer.lib + LIBS = + + OBJ2=getid$O popen$O + + AWKOBJS = main$O eval$O builtin$O msg$O iop$O io$O field$O array$O \ + node$O version$O missing$O re$O + ALLOBJS = $(AWKOBJS) awktab$O + GNUOBJS= getopt$O getopt1$O regex$O dfa$O + + .SUFFIXES: $O .c .y + + .c$O: + $(CC) $(CFLAGS) -DGAWK -c $< + + all: gawk.exe + + gawk.exe: $(ALLOBJS) $(GNUOBJS) $(OBJ2) + link @names.lnk, $@,,$(LIBS) /NOE /st:30000; + + + $(AWKOBJS): awk.h config.h + dfa$O: awk.h config.h dfa.h + regex$O: awk.h config.h regex.h + main$O: patchlev.h + + # A bug in ndmake requires the following rule + awktab$O: awk.h awktab.c + $(CC) $(CFLAGS) -DGAWK -c awktab.c + + awktab.c: awk.y + bison -o $@ awk.y + + clean: + rm -f *.o *.obj core awk.output gmon.out make.out y.output + + .PHONY: test + test: + @echo Both dmake and GNU make require modifications to test/Makefile, + @echo but here we go... + cd test && $(MAKE) -k diff -crN gawk-2.15.2/pc/Makefile.os2 gawk-2.15.3/pc/Makefile.os2 *** gawk-2.15.2/pc/Makefile.os2 Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/pc/Makefile.os2 Tue Oct 19 21:56:26 1993 *************** *** 0 **** --- 1,125 ---- + # Makefile for gawk (GNU awk) 17 Sep 1993 + # + # - for GNU gcc (emx 0.8g kit) [executables for OS/2 2.x or DOS (32-bit)] + # - for Microsoft C 6.00A [executables for OS/2 or MSDOS (16-bit)] + # - for Microsoft C 5.1 [executable for OS/2 or DOS (16-bit)] + + # To use, enter "make -f Makefile.os2" (this makefile depends on its + # name being "Makefile.os2"). + # + # Tested with dmake 3.8 and GNU make 3.68 under OS/2 + + default: + @echo "Enter $(MAKE) -f Makefile.os2 target " + @echo " where 'target' is chosen from " + @echo " msc OS/2 exe [Microsoft C 6.00a] " + @echo " mscbnd OS/2 and DOS exe [Microsoft C 6.00a] " + @echo " mscdos DOS exe [Microsoft C 6.00a] " + @echo " msc51bnd OS/2 and DOS exe [Microsoft C 5.1] " + @echo " emx OS/2 32-bit exe [EMX/gcc; uses emxlibc.dll] " + @echo " emxbnd OS/2 and DOS 32-bit exe [EMX/gcc] " + + + # stdargv, glob, and director are from Stewartson's sh. These provide + # globbing and enhanced argument-passing. MSC setargv.obj is a + # more limited alternative (and it will permit a bound version). + + #STDARGV = stdargv.obj glob.obj director.obj + STDARGV = setargv.obj + + msc: + $(MAKE) -f Makefile.os2 all \ + CC="cl -nologo -AL" O=".obj" \ + CFLAGS="-D__STDC__ -DOS2 -UMSDOS" \ + OBJ2="" \ + LFLAGS="-Lp" \ + LFLAGS2="$(STDARGV) gawk.def -link /NOE /st:30000" + + mscbnd: + $(MAKE) -f Makefile.os2 all \ + CC="cl -nologo -AL" O=".obj" \ + CFLAGS="-D__STDC__ -DOS2" \ + OBJ2="popen.obj" \ + LFLAGS="-Lp" \ + LFLAGS2="setargv.obj gawk.def -link /NOE /st:30000" \ + BIND="bind gawk /n DOSMAKEPIPE DOSCWAIT" + + msc-debug: + $(MAKE) -f Makefile.os2 all \ + CC="cl -nologo -AL" O=".obj" \ + CFLAGS="-DOS2 -D__STDC__ -DDEBUG -DFUNC_TRACE -DMEMDEBUG -Zi -Od" \ + OBJ2="popen.obj" \ + LFLAGS="-Lp" \ + LFLAGS2="$(STDARGV) gawk.def -link /CO /NOE /st:30000" + + mscdos: + $(MAKE) -f Makefile.os2 all \ + CC="cl -nologo -AL" O=".obj" \ + CFLAGS="-D__STDC__" \ + OBJ2="popen.obj" \ + LFLAGS="-Lr" \ + LFLAGS2="$(STDARGV) -link /NOE /st:30000" + + msc51bnd: + $(MAKE) -f Makefile.os2 all \ + CC="cl -AL" O=".obj" \ + CFLAGS="-DOS2 -D_MSC_VER=510" \ + OBJ2="popen.obj" \ + LFLAGS="-Lp -Fb" \ + LFLAGS2="setargv.obj gawk.def -link /NOE /NOI /st:30000" + + emx: + $(MAKE) -f Makefile.os2 all \ + CC="gcc -Zomf -Zmtd -O -s" O=".obj" \ + CFLAGS="-DOS2" \ + LFLAGS="" \ + LFLAGS2="gawk-32.def" + + emx-debug: + $(MAKE) -f Makefile.os2 all \ + CC="gcc -g" O=".o" \ + CFLAGS="-DOS2" \ + LFLAGS="" \ + LFLAGS2="gawk-32.def" + + emxbnd: + $(MAKE) -f Makefile.os2 all \ + CC="gcc -O -s" O=".o" \ + CFLAGS="-DOS2 -DMSDOS" \ + OBJ2="popen.o" \ + LFLAGS="" \ + LFLAGS2="gawk-32.def" + + AWKOBJS = main$O eval$O builtin$O msg$O iop$O io$O field$O array$O \ + node$O version$O missing$O re$O + ALLOBJS = $(AWKOBJS) awktab$O getid$O + GNUOBJS= getopt$O getopt1$O regex$O dfa$O + + .SUFFIXES: $O .c .y + + .c$O: + $(CC) $(CFLAGS) -DGAWK -c $< + + all: gawk.exe + + gawk.exe: $(ALLOBJS) $(GNUOBJS) $(OBJ2) + $(CC) -o $@ $(LFLAGS) $(ALLOBJS) $(GNUOBJS) $(OBJ2) $(LFLAGS2) + $(BIND) + + $(AWKOBJS): awk.h config.h + dfa$O: awk.h config.h dfa.h + regex$O: awk.h config.h regex.h + main$O: patchlevel.h + awktab$O: awk.h awktab.c + + awktab.c: awk.y + bison -o $@ awk.y + + clean: + rm -f *.o *.obj core awk.output gmon.out make.out y.output + + .PHONY: test + test: + @echo Both dmake and GNU make require modifications to test/Makefile, + @echo but here we go... + cd test && $(MAKE) -k diff -crN gawk-2.15.2/pc/config.h gawk-2.15.3/pc/config.h *** gawk-2.15.2/pc/config.h Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/pc/config.h Sun Nov 7 10:37:33 1993 *************** *** 0 **** --- 1,280 ---- + /* + * config.h -- configuration definitions for gawk. + * + * OS/2 or MS-DOS systems using emx/gcc or MSC + */ + + /* + * Copyright (C) 1991, 1992 the Free Software Foundation, Inc. + * + * This file is part of GAWK, the GNU implementation of the + * AWK Progamming Language. + * + * GAWK is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * GAWK is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GAWK; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + /* + * This file isolates configuration dependencies for gnu awk. + * You should know something about your system, perhaps by having + * a manual handy, when you edit this file. You should copy config.h-dist + * to config.h, and edit config.h. Do not modify config.h-dist, so that + * it will be easy to apply any patches that may be distributed. + * + * The general idea is that systems conforming to the various standards + * should need to do the least amount of changing. Definining the various + * items in ths file usually means that your system is missing that + * particular feature. + * + * The order of preference in standard conformance is ANSI C, POSIX, + * and the SVID. + * + * If you have no clue as to what's going on with your system, try + * compiling gawk without editing this file and see what shows up + * missing in the link stage. From there, you can probably figure out + * which defines to turn on. + */ + + /**************************/ + /* Miscellanious features */ + /**************************/ + + /* + * BLKSIZE_MISSING + * + * Check your /usr/include/sys/stat.h file. If the stat structure + * does not have a member named st_blksize, define this. (This will + * most likely be the case on most System V systems prior to V.4.) + */ + #define BLKSIZE_MISSING 1 + + /* + * SIGTYPE + * + * The return type of the routines passed to the signal function. + * Modern systems use `void', older systems use `int'. + * If left undefined, it will default to void. + */ + /* #define SIGTYPE int */ + + /* + * SIZE_T_MISSING + * + * If your system has no typedef for size_t, define this to get a default + */ + /* #define SIZE_T_MISSING 1 */ + + /* + * CHAR_UNSIGNED + * + * If your machine uses unsigned characters (IBM RT and RS/6000 and others) + * then define this for use in regex.c + */ + /* #define CHAR_UNSIGNED 1 */ + + /* + * HAVE_UNDERSCORE_SETJMP + * + * Check in your /usr/include/setjmp.h file. If there are routines + * there named _setjmp and _longjmp, then you should define this. + * Typically only systems derived from Berkeley Unix have this. + */ + /* #define HAVE_UNDERSCORE_SETJMP 1 */ + + /***********************************************/ + /* Missing library subroutines or system calls */ + /***********************************************/ + + /* + * MEMCMP_MISSING + * MEMCPY_MISSING + * MEMSET_MISSING + * + * These three routines are for manipulating blocks of memory. Most + * likely they will either all three be present or all three be missing, + * so they're grouped together. + */ + /* #define MEMCMP_MISSING 1 */ + /* #define MEMCPY_MISSING 1 */ + /* #define MEMSET_MISSING 1 */ + + /* + * RANDOM_MISSING + * + * Your system does not have the random(3) suite of random number + * generating routines. These are different than the old rand(3) + * routines! + */ + #define RANDOM_MISSING 1 + + /* + * STRCASE_MISSING + * + * Your system does not have the strcasemp() and strncasecmp() + * routines that originated in Berkeley Unix. + */ + /* #define STRCASE_MISSING 1 */ + #define strcasecmp stricmp + #define strncasecmp strnicmp + + /* + * STRCHR_MISSING + * + * Your system does not have the strchr() and strrchr() functions. + */ + /* #define STRCHR_MISSING 1 */ + + /* + * STRERROR_MISSING + * + * Your system lacks the ANSI C strerror() routine for returning the + * strings associated with errno values. + */ + /* #define STRERROR_MISSING 1 */ + + /* + * STRTOD_MISSING + * + * Your system does not have the strtod() routine for converting + * strings to double precision floating point values. + */ + /* #define STRTOD_MISSING 1 */ + + /* + * STRFTIME_MISSING + * + * Your system lacks the ANSI C strftime() routine for formatting + * broken down time values. + */ + #define STRFTIME_MISSING 1 + + /* + * TZSET_MISSING + * + * If you have a 4.2 BSD vintage system, then the strftime() routine + * supplied in the missing directory won't be enough, because it relies on the + * tzset() routine from System V / Posix. Fortunately, there is an + * emulation for tzset() too that should do the trick. If you don't + * have tzset(), define this. + */ + /* #define TZSET_MISSING 1 */ + + /* + * TZNAME_MISSING + * + * Some systems do not support the external variables tzname and daylight. + * If this is the case *and* strftime() is missing, define this. + */ + /* #define TZNAME_MISSING 1 */ + + /* + * STDC_HEADERS + * + * If your system does have ANSI compliant header files that + * provide prototypes for library routines, then define this. + */ + #define STDC_HEADERS 1 + + /* + * NO_TOKEN_PASTING + * + * If your compiler define's __STDC__ but does not support token + * pasting (tok##tok), then define this. + */ + /* #define NO_TOKEN_PASTING 1 */ + + /*****************************************************************/ + /* Stuff related to the Standard I/O Library. */ + /*****************************************************************/ + /* Much of this is (still, unfortunately) black magic in nature. */ + /* You may have to use some or all of these together to get gawk */ + /* to work correctly. */ + /*****************************************************************/ + + /* + * NON_STD_SPRINTF + * + * Look in your /usr/include/stdio.h file. If the return type of the + * sprintf() function is NOT `int', define this. + */ + /* #define NON_STD_SPRINTF 1 */ + + /* + * VPRINTF_MISSING + * + * Define this if your system lacks vprintf() and the other routines + * that go with it. This will trigger an attempt to use _doprnt(). + * If you don't have that, this attempt will fail and you are on your own. + */ + /* #define VPRINTF_MISSING 1 */ + + /* + * Casts from size_t to int and back. These will become unnecessary + * at some point in the future, but for now are required where the + * two types are a different representation. + */ + /* #define SZTC */ + /* #define INTC */ + + /* + * SYSTEM_MISSING + * + * Define this if your library does not provide a system function + * or you are not entirely happy with it and would rather use + * a provided replacement (atari only). + */ + /* #define SYSTEM_MISSING 1 */ + + /* + * FMOD_MISSING + * + * Define this if your system lacks the fmod() function and modf() will + * be used instead. + */ + /* #define FMOD_MISSING 1 */ + + + /*******************************/ + /* Gawk configuration options. */ + /*******************************/ + + /* + * DEFPATH + * + * The default search path for the -f option of gawk. It is used + * if the AWKPATH environment variable is undefined. The default + * definition is provided here. Most likely you should not change + * this. + */ + + /* #define DEFPATH ".:/usr/lib/awk:/usr/local/lib/awk" */ + /* #define ENVSEP ':' */ + #define ENVSEP ';' + + /* + * alloca already has a prototype defined - don't redefine it + */ + /* #define ALLOCA_PROTO 1 */ + + /* + * srandom already has a prototype defined - don't redefine it + */ + /* #define SRANDOM_PROTO 1 */ + + /* + * getpgrp() in sysvr4 and POSIX takes no argument + */ + /* #define GETPGRP_NOARG 0 */ + + /* anything that follows is for system-specific short-term kludges */ diff -crN gawk-2.15.2/pc/gawk-32.def gawk-2.15.3/pc/gawk-32.def *** gawk-2.15.2/pc/gawk-32.def Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/pc/gawk-32.def Wed Aug 18 08:58:36 1993 *************** *** 0 **** --- 1,3 ---- + NAME gawk WINDOWCOMPAT NEWFILES + DESCRIPTION 'GNU awk for OS/2' + STACKSIZE 0x100000 diff -crN gawk-2.15.2/pc/gawk.def gawk-2.15.3/pc/gawk.def *** gawk-2.15.2/pc/gawk.def Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/pc/gawk.def Wed Aug 18 08:58:42 1993 *************** *** 0 **** --- 1,2 ---- + NAME gawk WINDOWCOMPAT NEWFILES + DESCRIPTION 'GNU awk for OS/2' diff -crN gawk-2.15.2/pc/getid.c gawk-2.15.3/pc/getid.c *** gawk-2.15.2/pc/getid.c Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/pc/getid.c Tue Oct 19 21:52:26 1993 *************** *** 0 **** --- 1,69 ---- + #ifdef _MSC_VER + + #ifdef OS2 + # define INCL_DOSPROCESS + # include + # if _MSC_VER == 510 + # define DosGetPID DosGetPid + # endif + #else + # include + #endif + + #ifdef OS2 + int getpid(void) + { + PIDINFO PidInfo; + + DosGetPID(&PidInfo); + return(PidInfo.pid); + } + #endif + + int getppid(void) + { + #ifdef OS2 + PIDINFO PidInfo; + + DosGetPID(&PidInfo); + return(PidInfo.pidParent); + #else + return(0); + #endif + } + + unsigned int getuid (void) + { + return (0); /* root! */ + } + + + unsigned int geteuid (void) + { + return (0); + } + + + unsigned int getgid (void) + { + return (0); + } + + + unsigned int getegid (void) + { + return (0); + } + + + char *getlogin (void) + { + return ("root"); + } + + #endif + + int getpgrp(void) + { + return (0); + } diff -crN gawk-2.15.2/pc/makegawk.bat gawk-2.15.3/pc/makegawk.bat *** gawk-2.15.2/pc/makegawk.bat Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/pc/makegawk.bat Fri Sep 17 10:37:48 1993 *************** *** 0 **** --- 1,65 ---- + REM Simple brute force command file for building gawk under msdos + REM + REM *** This has only been tested using MSC 5.1 and MSC 6.00A *** + REM + REM Written by Arnold Robbins, May 1991 + REM Modified by Scott Deifik, July, 1992, Sep 1993 + REM Based on earlier makefile for dos + REM + REM Copyright (C) 1986, 1988, 1989, 1991 the Free Software Foundation, Inc. + REM + REM This file is part of GAWK, the GNU implementation of the + REM AWK Progamming Language. + REM + REM GAWK is free software; you can redistribute it and/or modify + REM it under the terms of the GNU General Public License as published by + REM the Free Software Foundation; either version 2 of the License, or + REM (at your option) any later version. + REM + REM GAWK is distributed in the hope that it will be useful, + REM but WITHOUT ANY WARRANTY; without even the implied warranty of + REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + REM GNU General Public License for more details. + REM + REM You should have received a copy of the GNU General Public License + REM along with GAWK; see the file COPYING. If not, write to + REM the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + REM + REM compile debug flags: -DDEBUG -DFUNC_TRACE -DMEMDEBUG -Zi -Od + REM + + set CFLAGS=-D_MSC_VER + + rem MSC 5.1 should use: + rem set CFLAGS=-D_MSC_VER=510 + + rem MSC 6.00A predefines _MSC_VER + rem set CFLAGS= + + rem -Za sets ANSI flag so that __STDC__ is defined in MSC 6.00A + rem (MSC 5.1 sets __STDC__=0 regardless of ANSI switch) + + cl -Za -c -AL %CFLAGS% -DGAWK array.c + cl -Za -c -AL %CFLAGS% -DGAWK awktab.c + cl -Za -c -AL %CFLAGS% -DGAWK builtin.c + cl -Za -c -AL %CFLAGS% -DGAWK dfa.c + cl -Za -c -AL %CFLAGS% -DGAWK eval.c + cl -Za -c -AL %CFLAGS% -DGAWK field.c + cl -Za -c -AL %CFLAGS% -DGAWK getid.c + cl -Za -c -AL %CFLAGS% -DGAWK getopt.c + cl -Za -c -AL %CFLAGS% -DGAWK getopt1.c + cl -Za -c -AL %CFLAGS% -DGAWK io.c + cl -Za -c -AL %CFLAGS% -DGAWK iop.c + cl -Za -c -AL %CFLAGS% -DGAWK main.c + cl -Za -c -AL %CFLAGS% -DGAWK missing.c + cl -Za -c -AL %CFLAGS% -DGAWK msg.c + cl -Za -c -AL %CFLAGS% -DGAWK node.c + cl -Za -c -AL %CFLAGS% -DGAWK popen.c + cl -Za -c -AL %CFLAGS% -DGAWK re.c + REM You can ignore the warnings you will get + cl -Za -c -AL %CFLAGS% -DGAWK regex.c + cl -Za -c -AL %CFLAGS% -DGAWK version.c + REM + REM link debug flags: /CO /NOE /NOI /st:30000 + REM + link @names.lnk,gawk.exe /NOE /NOI /st:30000; diff -crN gawk-2.15.2/pc/mkconf.cmd gawk-2.15.3/pc/mkconf.cmd *** gawk-2.15.2/pc/mkconf.cmd Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/pc/mkconf.cmd Thu Jun 27 20:13:56 1991 *************** *** 0 **** --- 1,31 ---- + extproc sh + + #! /bin/sh + # + # mkconf -- produce a config.h from a known configuration + + case "$#" in + 1) ;; + *) echo "Usage: mkconf system_type" >&2 + echo "Known systems: `cd config; echo ;ls -C`" >&2 + exit 2 + ;; + esac + + if [ -f config/$1 ]; then + sh ./mungeconf.cmd config/$1 config.h-dist >config.h + sed -n '/^#echo /s///p' config/$1 + sed -n '/^MAKE_.*/s//s,^##&## ,,/p' config/$1 >sedscr + if [ -s sedscr ] + then + sed -f sedscr Makefile-dist >Makefile + else + cp Makefile-dist Makefile + fi + cmd /c del sedscr + else + echo "\`$1' is not a known configuration." + echo "Either construct one based on the examples in the config directory," + echo "or copy config.h-dist to config.h and edit it." + exit 1 + fi diff -crN gawk-2.15.2/pc/mungeconf.cmd gawk-2.15.3/pc/mungeconf.cmd *** gawk-2.15.2/pc/mungeconf.cmd Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/pc/mungeconf.cmd Thu Jun 27 20:13:56 1991 *************** *** 0 **** --- 1,15 ---- + extproc sh + + #! /bin/sh + + case $# in + 2) ;; + *) echo "Usage: mungeconf sysfile distfile" >&2 ; exit 2 ;; + esac + + sed '/^#/d; /^MAKE_*/d' $1 | + sed '1s:.*:s~__SYSTEM__~&~: + 2,$s:^\([^ ]*\)[ ].*:s~^/\\* #define[ ]*\1.*~#define &~:' >sedscr + sed -f sedscr $2 + + cmd /c del sedscr diff -crN gawk-2.15.2/pc/names.lnk gawk-2.15.3/pc/names.lnk *** gawk-2.15.2/pc/names.lnk Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/pc/names.lnk Thu Sep 16 21:37:50 1993 *************** *** 0 **** --- 1,20 ---- + array.obj+ + awktab.obj+ + builtin.obj+ + dfa.obj+ + eval.obj+ + field.obj+ + getid.obj+ + getopt.obj+ + getopt1.obj+ + io.obj+ + iop.obj+ + main.obj+ + missing.obj+ + msg.obj+ + node.obj+ + popen.obj+ + re.obj+ + version.obj+ + regex.obj+ + setargv.obj diff -crN gawk-2.15.2/pc/names2.lnk gawk-2.15.3/pc/names2.lnk *** gawk-2.15.2/pc/names2.lnk Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/pc/names2.lnk Tue Oct 19 22:10:00 1993 *************** *** 0 **** --- 1,19 ---- + main.o + eval.o + builtin.o + msg.o + iop.o + io.o + field.o + array.o + node.o + version.o + missing.o + re.o + awktab.o + getopt.o + getopt1.o + regex.o + dfa.o + getid.o + popen.o diff -crN gawk-2.15.2/pc/popen.c gawk-2.15.3/pc/popen.c *** gawk-2.15.2/pc/popen.c Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/pc/popen.c Fri Sep 17 11:49:28 1993 *************** *** 0 **** --- 1,112 ---- + #include "popen.h" + #include + #include + #include + #include + + #ifdef OS2 + #ifdef _MSC_VER + #define popen(c,m) _popen(c,m) + #define pclose(f) _pclose(f) + #endif + #endif + + #ifndef _NFILE + #define _NFILE 40 + #endif + + static char template[] = "piXXXXXX"; + typedef enum { unopened = 0, reading, writing } pipemode; + static + struct { + char *command; + char *name; + pipemode pmode; + } pipes[_NFILE]; + + FILE * + os_popen( char *command, char *mode ) { + FILE *current; + char *name; + int cur; + pipemode curmode; + + #if defined(OS2) && (_MSC_VER != 510) + if (_osmode == OS2_MODE) + return(popen(command, mode)); + #endif + + /* + ** decide on mode. + */ + if(strcmp(mode,"r") == 0) + curmode = reading; + else if(strcmp(mode,"w") == 0) + curmode = writing; + else + return NULL; + /* + ** get a name to use. + */ + if((name = tempnam(".","pip"))==NULL) + return NULL; + /* + ** If we're reading, just call system to get a file filled with + ** output. + */ + if(curmode == reading) { + char cmd[256]; + sprintf(cmd,"%s > %s",command,name); + system(cmd); + if((current = fopen(name,"r")) == NULL) + return NULL; + } else { + if((current = fopen(name,"w")) == NULL) + return NULL; + } + cur = fileno(current); + pipes[cur].name = name; + pipes[cur].pmode = curmode; + pipes[cur].command = strdup(command); + return current; + } + + int + os_pclose( FILE * current) { + int cur = fileno(current),rval; + + #if defined(OS2) && (_MSC_VER != 510) + if (_osmode == OS2_MODE) + return(pclose(current)); + #endif + + /* + ** check for an open file. + */ + if(pipes[cur].pmode == unopened) + return -1; + if(pipes[cur].pmode == reading) { + /* + ** input pipes are just files we're done with. + */ + rval = fclose(current); + unlink(pipes[cur].name); + } else { + /* + ** output pipes are temporary files we have + ** to cram down the throats of programs. + */ + char command[256]; + fclose(current); + sprintf(command,"%s < %s",pipes[cur].command,pipes[cur].name); + rval = system(command); + unlink(pipes[cur].name); + } + /* + ** clean up current pipe. + */ + pipes[cur].pmode = unopened; + free(pipes[cur].name); + free(pipes[cur].command); + return rval; + } diff -crN gawk-2.15.2/pc/popen.h gawk-2.15.3/pc/popen.h *** gawk-2.15.2/pc/popen.h Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/pc/popen.h Fri Aug 20 13:53:26 1993 *************** *** 0 **** --- 1,9 ---- + /* + ** popen.h -- prototypes for pipe functions + */ + #if !defined(FILE) + #include + #endif + + extern FILE *os_popen( char *, char * ); + extern int os_pclose( FILE * ); diff -crN gawk-2.15.2/re.c gawk-2.15.3/re.c *** gawk-2.15.2/re.c Tue May 4 22:26:35 1993 --- gawk-2.15.3/re.c Tue Nov 2 06:30:54 1993 *************** *** 99,105 **** else rp->pat.translate = NULL; len = dest - temp; ! if ((err = re_compile_pattern(temp, (size_t) len, &(rp->pat))) != NULL) fatal("%s: /%s/", err, temp); if (dfa && !ignorecase) { regcompile(temp, len, &(rp->dfareg), 1); --- 99,105 ---- else rp->pat.translate = NULL; len = dest - temp; ! if ((err = re_compile_pattern(temp, len, &(rp->pat))) != NULL) fatal("%s: /%s/", err, temp); if (dfa && !ignorecase) { regcompile(temp, len, &(rp->dfareg), 1); diff -crN gawk-2.15.2/regex.c gawk-2.15.3/regex.c *** gawk-2.15.2/regex.c Sun Oct 11 13:45:34 1992 --- gawk-2.15.3/regex.c Sun Oct 17 22:06:10 1993 *************** *** 334,349 **** *b++ = (char) (ch); \ } ! /* Extend the buffer by twice its current size via reallociation and reset the pointers that pointed into the old allocation to point to the correct places in the new allocation. If extending the buffer ! results in it being larger than 1 << 16, then flag memory exhausted. */ #define EXTEND_BUFFER \ { char *old_buffer = bufp->buffer; \ ! if (bufp->allocated == (1L<<16)) goto too_big; \ bufp->allocated *= 2; \ ! if (bufp->allocated > (1L<<16)) bufp->allocated = (1L<<16); \ ! bufp->buffer = (char *) realloc (bufp->buffer, bufp->allocated); \ if (bufp->buffer == 0) \ goto memory_exhausted; \ b = (b - old_buffer) + bufp->buffer; \ --- 334,361 ---- *b++ = (char) (ch); \ } ! /* Extend the buffer by twice its current size via reallocation and reset the pointers that pointed into the old allocation to point to the correct places in the new allocation. If extending the buffer ! results in it being larger than EXTEND_BUFFER_MAX, then flag memory ! exhausted. */ ! #ifdef _MSC_VER ! /* Microsoft C 16-bit versions limit malloc to approx 65512 bytes. ! The REALLOC define eliminates a flurry of conversion warnings, ! but is not required. */ ! #define EXTEND_BUFFER_MAX 65500L ! #define REALLOC(p,s) realloc(p, (size_t) (s)) ! #else ! #define EXTEND_BUFFER_MAX (1L << 16) ! #define REALLOC realloc ! #endif #define EXTEND_BUFFER \ { char *old_buffer = bufp->buffer; \ ! if (bufp->allocated == EXTEND_BUFFER_MAX) goto too_big; \ bufp->allocated *= 2; \ ! if (bufp->allocated > EXTEND_BUFFER_MAX) \ ! bufp->allocated = EXTEND_BUFFER_MAX; \ ! bufp->buffer = (char *) REALLOC (bufp->buffer, bufp->allocated); \ if (bufp->buffer == 0) \ goto memory_exhausted; \ b = (b - old_buffer) + bufp->buffer; \ diff -crN gawk-2.15.2/support/texinfo.tex gawk-2.15.3/support/texinfo.tex *** gawk-2.15.2/support/texinfo.tex Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/support/texinfo.tex Tue Sep 28 16:01:07 1993 *************** *** 0 **** --- 1,4053 ---- + %% TeX macros to handle texinfo files + + % Copyright (C) 1985, 86, 88, 90, 91, 92, 1993 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 + %published by the Free Software Foundation; either version 2, or (at + %your option) any later version. + + %This texinfo.tex 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 texinfo.tex file; see the file COPYING. If not, write + %to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, + %USA. + + + %In other words, you are welcome to use, share and improve this program. + %You are forbidden to forbid anyone else to use, share and improve + %what you give them. Help stamp out software-hoarding! + + \def\texinfoversion{2.115} + \message{Loading texinfo package [Version \texinfoversion]:} + + % Print the version number if in a .fmt file. + \everyjob{\message{[Texinfo version \texinfoversion]}\message{}} + + % Save some parts of plain tex whose names we will redefine. + + \let\ptexlbrace=\{ + \let\ptexrbrace=\} + \let\ptexdots=\dots + \let\ptexdot=\. + \let\ptexstar=\* + \let\ptexend=\end + \let\ptexbullet=\bullet + \let\ptexb=\b + \let\ptexc=\c + \let\ptexi=\i + \let\ptext=\t + \let\ptexl=\l + \let\ptexL=\L + + \def\tie{\penalty 10000\ } % Save plain tex definition of ~. + + \message{Basics,} + \chardef\other=12 + + % If this character appears in an error message or help string, it + % starts a new line in the output. + \newlinechar = `^^J + + % Ignore a token. + % + \def\gobble#1{} + + \hyphenation{ap-pen-dix} + \hyphenation{mini-buf-fer mini-buf-fers} + \hyphenation{eshell} + + % Margin to add to right of even pages, to left of odd pages. + \newdimen \bindingoffset \bindingoffset=0pt + \newdimen \normaloffset \normaloffset=\hoffset + \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, + % since that produces some useless output on the terminal. + % + \def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% + \def\loggingall{\tracingcommands2 \tracingstats2 + \tracingpages1 \tracingoutput1 \tracinglostchars1 + \tracingmacros2 \tracingparagraphs1 \tracingrestores1 + \showboxbreadth\maxdimen\showboxdepth\maxdimen + }% + + %---------------------Begin change----------------------- + % + %%%% For @cropmarks command. + % Dimensions to add cropmarks at corners Added by P. A. MacKay, 12 Nov. 1986 + % + \newdimen\cornerlong \newdimen\cornerthick + \newdimen \topandbottommargin + \newdimen \outerhsize \newdimen \outervsize + \cornerlong=1pc\cornerthick=.3pt % These set size of cropmarks + \outerhsize=7in + %\outervsize=9.5in + % Alternative @smallbook page size is 9.25in + \outervsize=9.25in + \topandbottommargin=.75in + % + %---------------------End change----------------------- + + % \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} + + %%%% For @cropmarks command %%%% + + % Here is a modification of the main output routine for Near East Publications + % This provides right-angle cropmarks at all four corners. + % The contents of the page are centerlined into the cropmarks, + % and any desired binding offset is added as an \hskip on either + % site of the centerlined box. (P. A. MacKay, 12 November, 1986) + % + \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 + \vbox{\line{\ewtop\hfill\ewtop}} + \nointerlineskip + \line{\vbox{\moveleft\cornerthick\nstop} + \hfill + \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 + \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} + % + % Do @cropmarks to get crop marks + \def\cropmarks{\let\onepageout=\croppageout } + + \def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} + {\catcode`\@ =11 + \gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi + \dimen@=\dp#1 \unvbox#1 + \ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi + \ifr@ggedbottom \kern-\dimen@ \vfil \fi} + } + + % + % Here are the rules for the cropmarks. Note that they are + % offset so that the space between them is truly \outerhsize or \outervsize + % (P. A. MacKay, 12 November, 1986) + % + \def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} + \def\nstop{\vbox + {\hrule height\cornerthick depth\cornerlong width\cornerthick}} + \def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} + \def\nsbot{\vbox + {\hrule height\cornerlong depth\cornerthick width\cornerthick}} + + % Parse an argument, then pass it to #1. The argument is the rest of + % the input line (except we remove a trailing comment). #1 should be a + % macro which expects an ordinary undelimited TeX argument. + % + \def\parsearg#1{% + \let\next = #1% + \begingroup + \obeylines + \futurelet\temp\parseargx + } + + % If the next token is an obeyed space (from an @example environment or + % the like), remove it and recurse. Otherwise, we're done. + \def\parseargx{% + % \obeyedspace is defined far below, after the definition of \sepspaces. + \ifx\obeyedspace\temp + \expandafter\parseargdiscardspace + \else + \expandafter\parseargline + \fi + } + + % Remove a single space (as the delimiter token to the macro call). + {\obeyspaces % + \gdef\parseargdiscardspace {\futurelet\temp\parseargx}} + + {\obeylines % + \gdef\parseargline#1^^M{% + \endgroup % End of the group started in \parsearg. + % + % First remove any @c comment, then any @comment. + % Result of each macro is put in \toks0. + \argremovec #1\c\relax % + \expandafter\argremovecomment \the\toks0 \comment\relax % + % + % Call the caller's macro, saved as \next in \parsearg. + \expandafter\next\expandafter{\the\toks0}% + }% + } + + % Since all \c{,omment} does is throw away the argument, we can let TeX + % do that for us. The \relax here is matched by the \relax in the call + % in \parseargline; it could be more or less anything, its purpose is + % just to delimit the argument to the \c. + \def\argremovec#1\c#2\relax{\toks0 = {#1}} + \def\argremovecomment#1\comment#2\relax{\toks0 = {#1}} + + % \argremovec{,omment} might leave us with trailing spaces, though; e.g., + % @end itemize @c foo + % will have two active spaces as part of the argument with the + % `itemize'. Here we remove all active spaces from #1, and assign the + % result to \toks0. + % + % This loses if there are any *other* active characters besides spaces + % in the argument -- _ ^ +, for example -- since they get expanded. + % Fortunately, Texinfo does not define any such commands. (If it ever + % does, the catcode of the characters in questionwill have to be changed + % here.) But this means we cannot call \removeactivespaces as part of + % \argremovec{,omment}, since @c uses \parsearg, and thus the argument + % that \parsearg gets might well have any character at all in it. + % + \def\removeactivespaces#1{% + \begingroup + \ignoreactivespaces + \edef\temp{#1}% + \global\toks0 = \expandafter{\temp}% + \endgroup + } + + % Change the active space to expand to nothing. + % + \begingroup + \obeyspaces + \gdef\ignoreactivespaces{\obeyspaces\let =\empty} + \endgroup + + + \def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} + + %% These are used to keep @begin/@end levels from running away + %% Call \inENV within environments (after a \begingroup) + \newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi} + \def\ENVcheck{% + \ifENV\errmessage{Still within an environment. Type Return to continue.} + \endgroup\fi} % This is not perfect, but it should reduce lossage + + % @begin foo is the same as @foo, for now. + \newhelp\EMsimple{Type to continue.} + + \outer\def\begin{\parsearg\beginxxx} + + \def\beginxxx #1{% + \expandafter\ifx\csname #1\endcsname\relax + {\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else + \csname #1\endcsname\fi} + + % @end foo executes the definition of \Efoo. + % + \def\end{\parsearg\endxxx} + \def\endxxx #1{% + \removeactivespaces{#1}% + \edef\endthing{\the\toks0}% + % + \expandafter\ifx\csname E\endthing\endcsname\relax + \expandafter\ifx\csname \endthing\endcsname\relax + % There's no \foo, i.e., no ``environment'' foo. + \errhelp = \EMsimple + \errmessage{Undefined command `@end \endthing'}% + \else + \unmatchedenderror\endthing + \fi + \else + % Everything's ok; the right environment has been started. + \csname E\endthing\endcsname + \fi + } + + % There is an environment #1, but it hasn't been started. Give an error. + % + \def\unmatchedenderror#1{% + \errhelp = \EMsimple + \errmessage{This `@end #1' doesn't have a matching `@#1'}% + } + + % Define the control sequence \E#1 to give an unmatched @end error. + % + \def\defineunmatchedend#1{% + \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}% + } + + + % Single-spacing is done by various environments (specifically, in + % \nonfillstart and \quotations). + \newskip\singlespaceskip \singlespaceskip = \baselineskip + \def\singlespace{% + % Why was this kern here? It messes up equalizing space above and below + % environments. --karl, 6may93 + %{\advance \baselineskip by -\singlespaceskip + %\kern \baselineskip}% + \baselineskip=\singlespaceskip + } + + %% Simple single-character @ commands + + % @@ prints an @ + % Kludge this until the fonts are right (grr). + \def\@{{\tt \char '100}} + + % This is turned off because it was never documented + % and you can use @w{...} around a quote to suppress ligatures. + %% Define @` and @' to be the same as ` and ' + %% but suppressing ligatures. + %\def\`{{`}} + %\def\'{{'}} + + % Used to generate quoted braces. + + \def\mylbrace {{\tt \char '173}} + \def\myrbrace {{\tt \char '175}} + \let\{=\mylbrace + \let\}=\myrbrace + + % @: forces normal size whitespace following. + \def\:{\spacefactor=1000 } + + % @* forces a line break. + \def\*{\hfil\break\hbox{}\ignorespaces} + + % @. is an end-of-sentence period. + \def\.{.\spacefactor=3000 } + + % @w prevents a word break. Without the \leavevmode, @w at the + % beginning of a paragraph, when TeX is still in vertical mode, would + % produce a whole line of output instead of starting the paragraph. + \def\w#1{\leavevmode\hbox{#1}} + + % @group ... @end group forces ... to be all on one page, by enclosing + % it in a TeX vbox. We use \vtop instead of \vbox to construct the box + % to keep its height that of a normal line. According to the rules for + % \topskip (p.114 of the TeXbook), the glue inserted is + % max (\topskip - \ht (first item), 0). If that height is large, + % therefore, no glue is inserted, and the space between the headline and + % the text is small, which looks bad. + % + \def\group{\begingroup + \ifnum\catcode13=\active \else + \errhelp = \groupinvalidhelp + \errmessage{@group invalid in context where filling is enabled}% + \fi + % + % The \vtop we start below produces a box with normal height and large + % depth; thus, TeX puts \baselineskip glue before it, and (when the + % next line of text is done) \lineskip glue after it. (See p.82 of + % the TeXbook.) Thus, space below is not quite equal to space + % above. But it's pretty close. + \def\Egroup{% + \egroup % End the \vtop. + \endgroup % End the \group. + }% + % + \vtop\bgroup + % We have to put a strut on the last line in case the @group is in + % the midst of an example, rather than completely enclosing it. + % Otherwise, the interline space between the last line of the group + % and the first line afterwards is too small. But we can't put the + % strut in \Egroup, since there it would be on a line by itself. + % Hence this just inserts a strut at the beginning of each line. + \everypar = {\strut}% + % + % Since we have a strut on every line, we don't need any of TeX's + % normal interline spacing. + \offinterlineskip + % + % OK, but now we have to do something about blank + % lines in the input in @example-like environments, which normally + % just turn into \lisppar, which will insert no space now that we've + % turned off the interline space. Simplest is to make them be an + % empty paragraph. + \ifx\par\lisppar + \edef\par{\leavevmode \par}% + % + % Reset ^^M's definition to new definition of \par. + \obeylines + \fi + % + % We do @comment here in case we are called inside an environment, + % such as @example, where each end-of-line in the input causes an + % end-of-line in the output. We don't want the end-of-line after + % the `@group' to put extra space in the output. Since @group + % should appear on a line by itself (according to the Texinfo + % manual), we don't worry about eating any user text. + \comment + } + % + % TeX puts in an \escapechar (i.e., `@') at the beginning of the help + % message, so this ends up printing `@group can only ...'. + % + \newhelp\groupinvalidhelp{% + group can only be used in environments such as @example,^^J% + where each line of input produces a line of output.} + + % @need space-in-mils + % forces a page break if there is not space-in-mils remaining. + + \newdimen\mil \mil=0.001in + + \def\need{\parsearg\needx} + + % Old definition--didn't work. + %\def\needx #1{\par % + %% This method tries to make TeX break the page naturally + %% if the depth of the box does not fit. + %{\baselineskip=0pt% + %\vtop to #1\mil{\vfil}\kern -#1\mil\penalty 10000 + %\prevdepth=-1000pt + %}} + + \def\needx#1{% + % Go into vertical mode, so we don't make a big box in the middle of a + % paragraph. + \par + % + % Don't add any leading before our big empty box, but allow a page + % break, since the best break might be right here. + \allowbreak + \nointerlineskip + \vtop to #1\mil{\vfil}% + % + % TeX does not even consider page breaks if a penalty added to the + % main vertical list is 10000 or more. But in order to see if the + % empty box we just added fits on the page, we must make it consider + % page breaks. On the other hand, we don't want to actually break the + % page after the empty box. So we use a penalty of 9999. + % + % There is an extremely small chance that TeX will actually break the + % page at this \penalty, if there are no other feasible breakpoints in + % sight. (If the user is using lots of big @group commands, which + % almost-but-not-quite fill up a page, TeX will have a hard time doing + % good page breaking, for example.) However, I could not construct an + % example where a page broke at this \penalty; if it happens in a real + % document, then we can reconsider our strategy. + \penalty9999 + % + % Back up by the size of the box, whether we did a page break or not. + \kern -#1\mil + % + % Do not allow a page break right after this kern. + \nobreak + } + + % @br forces paragraph break + + \let\br = \par + + % @dots{} output some dots + + \def\dots{$\ldots$} + + % @page forces the start of a new page + + \def\page{\par\vfill\supereject} + + % @exdent text.... + % outputs text on separate line in roman font, starting at standard page margin + + % This records the amount of indent in the innermost environment. + % That's how much \exdent should take out. + \newskip\exdentamount + + % This defn is used inside fill environments such as @defun. + \def\exdent{\parsearg\exdentyyy} + \def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}} + + % This defn is used inside nofill environments such as @example. + \def\nofillexdent{\parsearg\nofillexdentyyy} + \def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount + \leftline{\hskip\leftskip{\rm#1}}}} + + %\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 + \endgroup} + + \def\thisfile{} + + % @center line outputs that line, centered + + \def\center{\parsearg\centerzzz} + \def\centerzzz #1{{\advance\hsize by -\leftskip + \advance\hsize by -\rightskip + \centerline{#1}}} + + % @sp n outputs n lines of vertical space + + \def\sp{\parsearg\spxxx} + \def\spxxx #1{\par \vskip #1\baselineskip} + + % @comment ...line which is ignored... + % @c is the same as @comment + % @ignore ... @end ignore is another way to write a comment + + \def\comment{\catcode 64=\other \catcode 123=\other \catcode 125=\other% + \parsearg \commentxxx} + + \def\commentxxx #1{\catcode 64=0 \catcode 123=1 \catcode 125=2 } + + \let\c=\comment + + % Prevent errors for section commands. + % Used in @ignore and in failing conditionals. + \def\ignoresections{% + \let\chapter=\relax + \let\unnumbered=\relax + \let\top=\relax + \let\unnumberedsec=\relax + \let\unnumberedsection=\relax + \let\unnumberedsubsec=\relax + \let\unnumberedsubsection=\relax + \let\unnumberedsubsubsec=\relax + \let\unnumberedsubsubsection=\relax + \let\section=\relax + \let\subsec=\relax + \let\subsubsec=\relax + \let\subsection=\relax + \let\subsubsection=\relax + \let\appendix=\relax + \let\appendixsec=\relax + \let\appendixsection=\relax + \let\appendixsubsec=\relax + \let\appendixsubsection=\relax + \let\appendixsubsubsec=\relax + \let\appendixsubsubsection=\relax + \let\contents=\relax + \let\smallbook=\relax + \let\titlepage=\relax + } + + % Used in nested conditionals, where we have to parse the Texinfo source + % and so want to turn off most commands, in case they are used + % incorrectly. + % + \def\ignoremorecommands{% + \let\defcv = \relax + \let\deffn = \relax + \let\deffnx = \relax + \let\defindex = \relax + \let\defivar = \relax + \let\defmac = \relax + \let\defmethod = \relax + \let\defop = \relax + \let\defopt = \relax + \let\defspec = \relax + \let\deftp = \relax + \let\deftypefn = \relax + \let\deftypefun = \relax + \let\deftypevar = \relax + \let\deftypevr = \relax + \let\defun = \relax + \let\defvar = \relax + \let\defvr = \relax + \let\ref = \relax + \let\xref = \relax + \let\printindex = \relax + \let\pxref = \relax + \let\settitle = \relax + \let\include = \relax + \let\lowersections = \relax + \let\down = \relax + \let\raisesections = \relax + \let\up = \relax + \let\set = \relax + \let\clear = \relax + } + + % Ignore @ignore ... @end ignore. + % + \def\ignore{\doignore{ignore}} + + % Also ignore @ifinfo, @menu, and @direntry text. + % + \def\ifinfo{\doignore{ifinfo}} + \def\menu{\doignore{menu}} + \def\direntry{\doignore{direntry}} + + % Ignore text until a line `@end #1'. + % + \def\doignore#1{\begingroup + % Don't complain about control sequences we have declared \outer. + \ignoresections + % + % Define a command to swallow text until we reach `@end #1'. + \long\def\doignoretext##1\end #1{\enddoignore}% + % + % Make sure that spaces turn into tokens that match what \doignoretext wants. + \catcode32 = 10 + % + % And now expand that command. + \doignoretext + } + + % What we do to finish off ignored text. + % + \def\enddoignore{\endgroup\ignorespaces}% + + \newif\ifwarnedobs\warnedobsfalse + \def\obstexwarn{% + \ifwarnedobs\relax\else + % We need to warn folks that they may have trouble with TeX 3.0. + % This uses \immediate\write16 rather than \message to get newlines. + \immediate\write16{} + \immediate\write16{***WARNING*** for users of Unix TeX 3.0!} + \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).} + \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{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 + \fi + } + + % **In TeX 3.0, setting text in \nullfont hangs tex. For a + % workaround (which requires the file ``dummy.tfm'' to be installed), + % uncomment the following line: + %%%%%\font\nullfont=dummy\let\obstexwarn=\relax + + % Ignore text, except that we keep track of conditional commands for + % purposes of nesting, up to an `@end #1' command. + % + \def\nestedignore#1{% + \obstexwarn + % We must actually expand the ignored text to look for the @end + % command, so that nested ignore constructs work. Thus, we put the + % text into a \vbox and then do nothing with the result. To minimize + % the change of memory overflow, we follow the approach outlined on + % page 401 of the TeXbook: make the current font be a dummy font. + % + \setbox0 = \vbox\bgroup + % Don't complain about control sequences we have declared \outer. + \ignoresections + % + % Define `@end #1' to end the box, which will in turn undefine the + % @end command again. + \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}% + % + % We are going to be parsing Texinfo commands. Most cause no + % trouble when they are used incorrectly, but some commands do + % complicated argument parsing or otherwise get confused, so we + % undefine them. + % + % We can't do anything about stray @-signs, unfortunately; + % they'll produce `undefined control sequence' errors. + \ignoremorecommands + % + % Set the current font to be \nullfont, a TeX primitive, and define + % all the font commands to also use \nullfont. We don't use + % dummy.tfm, as suggested in the TeXbook, because not all sites + % might have that installed. Therefore, math mode will still + % produce output, but that should be an extremely small amount of + % stuff compared to the main input. + % + \nullfont + \let\tenrm = \nullfont \let\tenit = \nullfont \let\tensl = \nullfont + \let\tenbf = \nullfont \let\tentt = \nullfont \let\smallcaps = \nullfont + \let\tensf = \nullfont + % Similarly for index fonts (mostly for their use in + % smallexample) + \let\indrm = \nullfont \let\indit = \nullfont \let\indsl = \nullfont + \let\indbf = \nullfont \let\indtt = \nullfont \let\indsc = \nullfont + \let\indsf = \nullfont + % + % Don't complain when characters are missing from the fonts. + \tracinglostchars = 0 + % + % Don't bother to do space factor calculations. + \frenchspacing + % + % Don't report underfull hboxes. + \hbadness = 10000 + % + % Do minimal line-breaking. + \pretolerance = 10000 + % + % Do not execute instructions in @tex + \def\tex{\doignore{tex}} + } + + % @set VAR sets the variable VAR to an empty value. + % @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. + % + % 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. + % + \def\set{\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 + } + \def\setzzz#1#2 \endsetzzz{\expandafter\xdef\csname SET#1\endcsname{#2}} + + % @clear VAR clears (i.e., unsets) the variable VAR. + % + \def\clear{\parsearg\clearxxx} + \def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax} + + % @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} + + % @ifset VAR ... @end ifset reads the `...' iff VAR has been defined + % with @set. + % + \def\ifset{\parsearg\ifsetxxx} + \def\ifsetxxx #1{% + \expandafter\ifx\csname SET#1\endcsname\relax + \expandafter\ifsetfail + \else + \expandafter\ifsetsucceed + \fi + } + \def\ifsetsucceed{\conditionalsucceed{ifset}} + \def\ifsetfail{\nestedignore{ifset}} + \defineunmatchedend{ifset} + + % @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been + % defined with @set, or has been undefined with @clear. + % + \def\ifclear{\parsearg\ifclearxxx} + \def\ifclearxxx #1{% + \expandafter\ifx\csname SET#1\endcsname\relax + \expandafter\ifclearsucceed + \else + \expandafter\ifclearfail + \fi + } + \def\ifclearsucceed{\conditionalsucceed{ifclear}} + \def\ifclearfail{\nestedignore{ifclear}} + \defineunmatchedend{ifclear} + + % @iftex always succeeds; we read the text following, through @end + % iftex). But `@end iftex' should be valid only after an @iftex. + % + \def\iftex{\conditionalsucceed{iftex}} + \defineunmatchedend{iftex} + + % We can't just want to start a group at @iftex (for example) and end it + % at @end iftex, since then @set commands inside the conditional have no + % effect (they'd get reverted at the end of the group). So we must + % define \Eiftex to redefine itself to be its previous value. (We can't + % just define it to fail again with an ``unmatched end'' error, since + % the @ifset might be nested.) + % + \def\conditionalsucceed#1{% + \edef\temp{% + % Remember the current value of \E#1. + \let\nece{prevE#1} = \nece{E#1}% + % + % At the `@end #1', redefine \E#1 to be its previous value. + \def\nece{E#1}{\let\nece{E#1} = \nece{prevE#1}}% + }% + \temp + } + + % We need to expand lots of \csname's, but we don't want to expand the + % control sequences after we've constructed them. + % + \def\nece#1{\expandafter\noexpand\csname#1\endcsname} + + % @asis just yields its argument. Used with @table, for example. + % + \def\asis#1{#1} + + % @math means output in math mode. + % We don't use $'s directly in the definition of \math because control + % sequences like \math are expanded when the toc file is written. Then, + % we read the toc file back, the $'s will be normal characters (as they + % should be, according to the definition of Texinfo). So we must use a + % control sequence to switch into and out of math mode. + % + % This isn't quite enough for @math to work properly in indices, but it + % seems unlikely it will ever be needed there. + % + \let\implicitmath = $ + \def\math#1{\implicitmath #1\implicitmath} + + % @bullet and @minus need the same treatment as @math, just above. + \def\bullet{\implicitmath\ptexbullet\implicitmath} + \def\minus{\implicitmath-\implicitmath} + + \def\node{\ENVcheck\parsearg\nodezzz} + \def\nodezzz#1{\nodexxx [#1,]} + \def\nodexxx[#1,#2]{\gdef\lastnode{#1}} + \let\nwnode=\node + \let\lastnode=\relax + + \def\donoderef{\ifx\lastnode\relax\else + \expandafter\expandafter\expandafter\setref{\lastnode}\fi + \let\lastnode=\relax} + + \def\unnumbnoderef{\ifx\lastnode\relax\else + \expandafter\expandafter\expandafter\unnumbsetref{\lastnode}\fi + \let\lastnode=\relax} + + \def\appendixnoderef{\ifx\lastnode\relax\else + \expandafter\expandafter\expandafter\appendixsetref{\lastnode}\fi + \let\lastnode=\relax} + + \let\refill=\relax + + % @setfilename is done at the beginning of every texinfo file. + % So open here the files we need to have open while reading the input. + % This makes it possible to make a .fmt file for texinfo. + \def\setfilename{% + \readauxfile + \opencontents + \openindices + \fixbackslash % Turn off hack to swallow `\input texinfo'. + \global\let\setfilename=\comment % Ignore extra @setfilename cmds. + \comment % Ignore the actual filename. + } + + \outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} + + \def\inforef #1{\inforefzzz #1,,,,**} + \def\inforefzzz #1,#2,#3,#4**{See Info file \file{\ignorespaces #3{}}, + node \samp{\ignorespaces#1{}}} + + \message{fonts,} + + % Font-change commands. + + % Texinfo supports the sans serif font style, which plain TeX does not. + % So we set up a \sf analogous to plain's \rm, etc. + \newfam\sffam + \def\sf{\fam=\sffam \tensf} + \let\li = \sf % Sometimes we call it \li, not \sf. + + %% Try out Computer Modern fonts at \magstephalf + \let\mainmagstep=\magstephalf + + \ifx\bigger\relax + \let\mainmagstep=\magstep1 + \font\textrm=cmr12 + \font\texttt=cmtt12 + \else + \font\textrm=cmr10 scaled \mainmagstep + \font\texttt=cmtt10 scaled \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. + \font\textbf=cmb10 scaled \mainmagstep + \font\textit=cmti10 scaled \mainmagstep + \font\textsl=cmsl10 scaled \mainmagstep + \font\textsf=cmss10 scaled \mainmagstep + \font\textsc=cmcsc10 scaled \mainmagstep + \font\texti=cmmi10 scaled \mainmagstep + \font\textsy=cmsy10 scaled \mainmagstep + + % A few fonts for @defun, etc. + \font\defbf=cmbx10 scaled \magstep1 %was 1314 + \font\deftt=cmtt10 scaled \magstep1 + \def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf} + + % Fonts for indices and small examples. + % 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. + \font\ninett=cmtt9 + \font\indrm=cmr9 + \font\indit=cmsl9 + \let\indsl=\indit + \let\indtt=\ninett + \let\indsf=\indrm + \let\indbf=\indrm + \let\indsc=\indrm + \font\indi=cmmi9 + \font\indsy=cmsy9 + + % Fonts for headings + \font\chaprm=cmbx12 scaled \magstep2 + \font\chapit=cmti12 scaled \magstep2 + \font\chapsl=cmsl12 scaled \magstep2 + \font\chaptt=cmtt12 scaled \magstep2 + \font\chapsf=cmss12 scaled \magstep2 + \let\chapbf=\chaprm + \font\chapsc=cmcsc10 scaled\magstep3 + \font\chapi=cmmi12 scaled \magstep2 + \font\chapsy=cmsy10 scaled \magstep3 + + \font\secrm=cmbx12 scaled \magstep1 + \font\secit=cmti12 scaled \magstep1 + \font\secsl=cmsl12 scaled \magstep1 + \font\sectt=cmtt12 scaled \magstep1 + \font\secsf=cmss12 scaled \magstep1 + \font\secbf=cmbx12 scaled \magstep1 + \font\secsc=cmcsc10 scaled\magstep2 + \font\seci=cmmi12 scaled \magstep1 + \font\secsy=cmsy10 scaled \magstep2 + + % \font\ssecrm=cmbx10 scaled \magstep1 % This size an font looked bad. + % \font\ssecit=cmti10 scaled \magstep1 % The letters were too crowded. + % \font\ssecsl=cmsl10 scaled \magstep1 + % \font\ssectt=cmtt10 scaled \magstep1 + % \font\ssecsf=cmss10 scaled \magstep1 + + %\font\ssecrm=cmb10 scaled 1315 % Note the use of cmb rather than cmbx. + %\font\ssecit=cmti10 scaled 1315 % Also, the size is a little larger than + %\font\ssecsl=cmsl10 scaled 1315 % being scaled magstep1. + %\font\ssectt=cmtt10 scaled 1315 + %\font\ssecsf=cmss10 scaled 1315 + + %\let\ssecbf=\ssecrm + + \font\ssecrm=cmbx12 scaled \magstephalf + \font\ssecit=cmti12 scaled \magstephalf + \font\ssecsl=cmsl12 scaled \magstephalf + \font\ssectt=cmtt12 scaled \magstephalf + \font\ssecsf=cmss12 scaled \magstephalf + \font\ssecbf=cmbx12 scaled \magstephalf + \font\ssecsc=cmcsc10 scaled \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: + \font\titlerm = cmbx12 scaled \magstep3 + \let\authorrm = \secrm + + % In order for the font changes to affect most math symbols and letters, + % we have to define the \textfont of the standard families. Since + % texinfo doesn't allow for producing subscripts and superscripts, we + % don't bother to reset \scriptfont and \scriptscriptfont (which would + % also require loading a lot more fonts). + % + \def\resetmathfonts{% + \textfont0 = \tenrm \textfont1 = \teni \textfont2 = \tensy + \textfont\itfam = \tenit \textfont\slfam = \tensl \textfont\bffam = \tenbf + \textfont\ttfam = \tentt \textfont\sffam = \tensf + } + + + % 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. + \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 + \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} + \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} + \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} + \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} + + % Set up the default fonts, so we can use them for creating boxes. + % + \textfonts + + % Count depth in font-changes, for error checks + \newcount\fontdepth \fontdepth=0 + + % Fonts for short table of contents. + \font\shortcontrm=cmr12 + \font\shortcontbf=cmbx12 + \font\shortcontsl=cmsl12 + + %% Add scribe-like font environments, plus @l for inline lisp (usually sans + %% serif) and @ii for TeX italic + + % \smartitalic{ARG} outputs arg in italics, followed by an italic correction + % unless the following character is such as not to need one. + \def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else\/\fi\fi\fi} + \def\smartitalic#1{{\sl #1}\futurelet\next\smartitalicx} + + \let\i=\smartitalic + \let\var=\smartitalic + \let\dfn=\smartitalic + \let\emph=\smartitalic + \let\cite=\smartitalic + + \def\b#1{{\bf #1}} + \let\strong=\b + + % We can't just use \exhyphenpenalty, because that only has effect at + % the end of a paragraph. Restore normal hyphenation at the end of the + % group within which \nohyphenation is presumably called. + % + \def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} + \def\restorehyphenation{\hyphenchar\font = `- } + + \def\t#1{% + {\tt \nohyphenation \rawbackslash \frenchspacing #1}% + \null + } + \let\ttfont = \t + %\def\samp #1{`{\tt \rawbackslash \frenchspacing #1}'\null} + \def\samp #1{`\tclose{#1}'\null} + \def\key #1{{\tt \nohyphenation \uppercase{#1}}\null} + \def\ctrl #1{{\tt \rawbackslash \hat}#1} + + \let\file=\samp + + % @code is a modification of @t, + % which makes spaces the same size as normal in the surrounding text. + \def\tclose#1{% + {% + % Change normal interword space to be same as for the current font. + \spaceskip = \fontdimen2\font + % + % Switch to typewriter. + \tt + % + % But `\ ' produces the large typewriter interword space. + \def\ {{\spaceskip = 0pt{} }}% + % + % Turn off hyphenation. + \nohyphenation + % + \rawbackslash + \frenchspacing + #1% + }% + \null + } + + % We *must* turn on hyphenation at `-' and `_' in \code. + % Otherwise, it is too hard to avoid overful hboxes + % in the Emacs manual, the Library manual, etc. + + % 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. + % -- rms. + { + \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} + } + \def\realdash{-} + \def\realunder{_} + \def\codedash{-\discretionary{}{}{}} + \def\codeunder{\normalunderscore\discretionary{}{}{}} + \def\codex #1{\tclose{#1}\endgroup} + + %\let\exp=\tclose %Was temporary + + % @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} + + % 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 + % @dmn{}pt. + % + \def\dmn#1{\thinspace #1} + + \def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par} + + \def\l#1{{\li #1}\null} % + + \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 + + \message{page headings,} + + \newskip\titlepagetopglue \titlepagetopglue = 1.5in + \newskip\titlepagebottomglue \titlepagebottomglue = 2pc + + % First the title page. Must do @settitle before @titlepage. + \def\titlefont#1{{\titlerm #1}} + + \newif\ifseenauthor + \newif\iffinishedtitlepage + + \def\shorttitlepage{\parsearg\shorttitlepagezzz} + \def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% + \endgroup\page\hbox{}\page} + + \def\titlepage{\begingroup \parindent=0pt \textfonts + \let\subtitlerm=\tenrm + % I deinstalled the following change because \cmr12 is undefined. + % This change was not in the ChangeLog anyway. --rms. + % \let\subtitlerm=\cmr12 + \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}% + % + \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines}% + % + % Leave some space at the very top of the page. + \vglue\titlepagetopglue + % + % 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}% + % No rule at page bottom unless we print one at the top with @title. + \finishedtitlepagetrue + % + % Now you can put text using @subtitle. + \def\subtitle{\parsearg\subtitlezzz}% + \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}% + % + % @author should come last, but may come many times. + \def\author{\parsearg\authorzzz}% + \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi + {\authorfont \leftline{##1}}}% + % + % Most title ``pages'' are actually two pages long, with space + % at the top of the second. We don't want the ragged left on the second. + \let\oldpage = \page + \def\page{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + \oldpage + \let\page = \oldpage + \hbox{}}% + % \def\page{\oldpage \hbox{}} + } + + \def\Etitlepage{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + % It is important to do the page break before ending the group, + % because the headline and footline are only empty inside the group. + % If we use the new definition of \page, we always get a blank page + % after the title page, which we certainly don't want. + \oldpage + \endgroup + \HEADINGSon + } + + \def\finishtitlepage{% + \vskip4pt \hrule height 2pt width \hsize + \vskip\titlepagebottomglue + \finishedtitlepagetrue + } + + %%% Set up page headings and footings. + + \let\thispage=\folio + + \newtoks \evenheadline % Token sequence for heading line of even pages + \newtoks \oddheadline % Token sequence for heading line of odd pages + \newtoks \evenfootline % Token sequence for footing line of even pages + \newtoks \oddfootline % Token sequence for footing line of odd pages + + % Now make Tex use those variables + \headline={{\textfonts\rm \ifodd\pageno \the\oddheadline + \else \the\evenheadline \fi}} + \footline={{\textfonts\rm \ifodd\pageno \the\oddfootline + \else \the\evenfootline \fi}\HEADINGShook} + \let\HEADINGShook=\relax + + % Commands to set those variables. + % For example, this is what @headings on does + % @evenheading @thistitle|@thispage|@thischapter + % @oddheading @thischapter|@thispage|@thistitle + % @evenfooting @thisfile|| + % @oddfooting ||@thisfile + + \def\evenheading{\parsearg\evenheadingxxx} + \def\oddheading{\parsearg\oddheadingxxx} + \def\everyheading{\parsearg\everyheadingxxx} + + \def\evenfooting{\parsearg\evenfootingxxx} + \def\oddfooting{\parsearg\oddfootingxxx} + \def\everyfooting{\parsearg\everyfootingxxx} + + {\catcode`\@=0 % + + \gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish} + \gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{% + \global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + + \gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish} + \gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{% + \global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + + \gdef\everyheadingxxx #1{\everyheadingyyy #1@|@|@|@|\finish} + \gdef\everyheadingyyy #1@|#2@|#3@|#4\finish{% + \global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}} + \global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + + \gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish} + \gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{% + \global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + + \gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish} + \gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{% + \global\oddfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + + \gdef\everyfootingxxx #1{\everyfootingyyy #1@|@|@|@|\finish} + \gdef\everyfootingyyy #1@|#2@|#3@|#4\finish{% + \global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}} + \global\oddfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + % + }% 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 singleafter turns on single-sided headings after this page. + % By default, they are off. + + \def\headings #1 {\csname HEADINGS#1\endcsname} + + \def\HEADINGSoff{ + \global\evenheadline={\hfil} \global\evenfootline={\hfil} + \global\oddheadline={\hfil} \global\oddfootline={\hfil}} + \HEADINGSoff + % When we turn headings on, set the page number to 1. + % For double-sided printing, put current file name in lower left corner, + % chapter name on inside top of right hand pages, document + % 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}} + } + % 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}} + } + \def\HEADINGSon{\HEADINGSdouble} + + \def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} + \let\HEADINGSdoubleafter=\HEADINGSafter + \def\HEADINGSdoublex{% + \global\evenfootline={\hfil} + \global\oddfootline={\hfil} + \global\evenheadline={\line{\folio\hfil\thistitle}} + \global\oddheadline={\line{\thischapter\hfil\folio}} + } + + \def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} + \def\HEADINGSsinglex{% + \global\evenfootline={\hfil} + \global\oddfootline={\hfil} + \global\evenheadline={\line{\thischapter\hfil\folio}} + \global\oddheadline={\line{\thischapter\hfil\folio}} + } + + % Subroutines used in generating headings + % Produces Day Month Year style of output. + \def\today{\number\day\space + \ifcase\month\or + January\or February\or March\or April\or May\or June\or + July\or August\or September\or October\or November\or December\fi + \space\number\year} + + % Use this if you want the Month Day, Year style of output. + %\def\today{\ifcase\month\or + %January\or February\or March\or April\or May\or June\or + %July\or August\or September\or October\or November\or December\fi + %\space\number\day, \number\year} + + % @settitle line... specifies the title of the document, for headings + % It generates no output of its own + + \def\thistitle{No Title} + \def\settitle{\parsearg\settitlezzz} + \def\settitlezzz #1{\gdef\thistitle{#1}} + + \message{tables,} + + % @tabs -- simple alignment + + % These don't work. For one thing, \+ is defined as outer. + % So these macros cannot even be defined. + + %\def\tabs{\parsearg\tabszzz} + %\def\tabszzz #1{\settabs\+#1\cr} + %\def\tabline{\parsearg\tablinezzz} + %\def\tablinezzz #1{\+#1\cr} + %\def\&{&} + + % Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x). + + % default indentation of table text + \newdimen\tableindent \tableindent=.8in + % default indentation of @itemize and @enumerate text + \newdimen\itemindent \itemindent=.3in + % margin between end of table item and start of table text. + \newdimen\itemmargin \itemmargin=.1in + + % used internally for \itemindent minus \itemmargin + \newdimen\itemmax + + % Note @table, @vtable, and @vtable define @item, @itemx, etc., with + % these defs. + % They also define \itemindex + % to index the item name in whatever manner is desired (perhaps none). + + \newif\ifitemxneedsnegativevskip + + \def\itemxpar{\par\ifitemxneedsnegativevskip\vskip-\parskip\nobreak\fi} + + \def\internalBitem{\smallbreak \parsearg\itemzzz} + \def\internalBitemx{\itemxpar \parsearg\itemzzz} + + \def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz} + \def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz} + + \def\internalBkitem{\smallbreak \parsearg\kitemzzz} + \def\internalBkitemx{\itemxpar \parsearg\kitemzzz} + + \def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}% + \itemzzz {#1}} + + \def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}% + \itemzzz {#1}} + + \def\itemzzz #1{\begingroup % + \advance\hsize by -\rightskip + \advance\hsize by -\tableindent + \setbox0=\hbox{\itemfont{#1}}% + \itemindex{#1}% + \nobreak % This prevents a break before @itemx. + % + % Be sure we are not still in the middle of a paragraph. + %{\parskip = 0in + %\par + %}% + % + % If the item text does not fit in the space we have, put it on a line + % by itself, and do not allow a page break either before or after that + % line. We do not start a paragraph here because then if the next + % command is, e.g., @kindex, the whatsit would get put into the + % horizontal list on a line by itself, resulting in extra blank space. + \ifdim \wd0>\itemmax + % + % Make this a paragraph so we get the \parskip glue and wrapping, + % but leave it ragged-right. + \begingroup + \advance\leftskip by-\tableindent + \advance\hsize by\tableindent + \advance\rightskip by0pt plus1fil + \leavevmode\unhbox0\par + \endgroup + % + % We're going to be starting a paragraph, but we don't want the + % \parskip glue -- logically it's part of the @item we just started. + \nobreak \vskip-\parskip + % + % Stop a page break at the \parskip glue coming up. Unfortunately + % we can't prevent a possible page break at the following + % \baselineskip glue. + \nobreak + \endgroup + \itemxneedsnegativevskipfalse + \else + % The item text fits into the space. Start a paragraph, so that the + % following text (if any) will end up on the same line. Since that + % text will be indented by \tableindent, we make the item text be in + % a zero-width box. + \noindent + \rlap{\hskip -\tableindent\box0}\ignorespaces% + \endgroup% + \itemxneedsnegativevskiptrue% + \fi + } + + \def\item{\errmessage{@item while not in a table}} + \def\itemx{\errmessage{@itemx while not in a table}} + \def\kitem{\errmessage{@kitem while not in a table}} + \def\kitemx{\errmessage{@kitemx while not in a table}} + \def\xitem{\errmessage{@xitem while not in a table}} + \def\xitemx{\errmessage{@xitemx while not in a table}} + + %% Contains a kludge to get @end[description] to work + \def\description{\tablez{\dontindex}{1}{}{}{}{}} + + \def\table{\begingroup\inENV\obeylines\obeyspaces\tablex} + {\obeylines\obeyspaces% + \gdef\tablex #1^^M{% + \tabley\dontindex#1 \endtabley}} + + \def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex} + {\obeylines\obeyspaces% + \gdef\ftablex #1^^M{% + \tabley\fnitemindex#1 \endtabley + \def\Eftable{\endgraf\afterenvbreak\endgroup}% + \let\Etable=\relax}} + + \def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex} + {\obeylines\obeyspaces% + \gdef\vtablex #1^^M{% + \tabley\vritemindex#1 \endtabley + \def\Evtable{\endgraf\afterenvbreak\endgroup}% + \let\Etable=\relax}} + + \def\dontindex #1{} + \def\fnitemindex #1{\doind {fn}{\code{#1}}}% + \def\vritemindex #1{\doind {vr}{\code{#1}}}% + + {\obeyspaces % + \gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup% + \tablez{#1}{#2}{#3}{#4}{#5}{#6}}} + + \def\tablez #1#2#3#4#5#6{% + \aboveenvbreak % + \begingroup % + \def\Edescription{\Etable}% Neccessary kludge. + \let\itemindex=#1% + \ifnum 0#3>0 \advance \leftskip by #3\mil \fi % + \ifnum 0#4>0 \tableindent=#4\mil \fi % + \ifnum 0#5>0 \advance \rightskip by #5\mil \fi % + \def\itemfont{#2}% + \itemmax=\tableindent % + \advance \itemmax by -\itemmargin % + \advance \leftskip by \tableindent % + \exdentamount=\tableindent + \parindent = 0pt + \parskip = \smallskipamount + \ifdim \parskip=0pt \parskip=2pt \fi% + \def\Etable{\endgraf\afterenvbreak\endgroup}% + \let\item = \internalBitem % + \let\itemx = \internalBitemx % + \let\kitem = \internalBkitem % + \let\kitemx = \internalBkitemx % + \let\xitem = \internalBxitem % + \let\xitemx = \internalBxitemx % + } + + % This is the counter used by @enumerate, which is really @itemize + + \newcount \itemno + + \def\itemize{\parsearg\itemizezzz} + + \def\itemizezzz #1{% + \begingroup % ended by the @end itemsize + \itemizey {#1}{\Eitemize} + } + + \def\itemizey #1#2{% + \aboveenvbreak % + \itemmax=\itemindent % + \advance \itemmax by -\itemmargin % + \advance \leftskip by \itemindent % + \exdentamount=\itemindent + \parindent = 0pt % + \parskip = \smallskipamount % + \ifdim \parskip=0pt \parskip=2pt \fi% + \def#2{\endgraf\afterenvbreak\endgroup}% + \def\itemcontents{#1}% + \let\item=\itemizeitem} + + % Set sfcode to normal for the chars that usually have another value. + % These are `.?!:;,' + \def\frenchspacing{\sfcode46=1000 \sfcode63=1000 \sfcode33=1000 + \sfcode58=1000 \sfcode59=1000 \sfcode44=1000 } + + % \splitoff TOKENS\endmark defines \first to be the first token in + % TOKENS, and \rest to be the remainder. + % + \def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% + + % Allow an optional argument of an uppercase letter, lowercase letter, + % or number, to specify the first label in the enumerated list. No + % argument is the same as `1'. + % + \def\enumerate{\parsearg\enumeratezzz} + \def\enumeratezzz #1{\enumeratey #1 \endenumeratey} + \def\enumeratey #1 #2\endenumeratey{% + \begingroup % ended by the @end enumerate + % + % If we were given no argument, pretend we were given `1'. + \def\thearg{#1}% + \ifx\thearg\empty \def\thearg{1}\fi + % + % Detect if the argument is a single token. If so, it might be a + % letter. Otherwise, the only valid thing it can be is a number. + % (We will always have one token, because of the test we just made. + % This is a good thing, since \splitoff doesn't work given nothing at + % all -- the first parameter is undelimited.) + \expandafter\splitoff\thearg\endmark + \ifx\rest\empty + % Only one token in the argument. It could still be anything. + % A ``lowercase letter'' is one whose \lccode is nonzero. + % An ``uppercase letter'' is one whose \lccode is both nonzero, and + % not equal to itself. + % Otherwise, we assume it's a number. + % + % We need the \relax at the end of the \ifnum lines to stop TeX from + % continuing to look for a . + % + \ifnum\lccode\expandafter`\thearg=0\relax + \numericenumerate % a number (we hope) + \else + % It's a letter. + \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax + \lowercaseenumerate % lowercase letter + \else + \uppercaseenumerate % uppercase letter + \fi + \fi + \else + % Multiple tokens in the argument. We hope it's a number. + \numericenumerate + \fi + } + + % An @enumerate whose labels are integers. The starting integer is + % given in \thearg. + % + \def\numericenumerate{% + \itemno = \thearg + \startenumeration{\the\itemno}% + } + + % The starting (lowercase) letter is in \thearg. + \def\lowercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more lowercase letters in @enumerate; get a bigger + alphabet}% + \fi + \char\lccode\itemno + }% + } + + % The starting (uppercase) letter is in \thearg. + \def\uppercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more uppercase letters in @enumerate; get a bigger + alphabet} + \fi + \char\uccode\itemno + }% + } + + % Call itemizey, adding a period to the first argument and supplying the + % common last two arguments. Also subtract one from the initial value in + % \itemno, since @item increments \itemno. + % + \def\startenumeration#1{% + \advance\itemno by -1 + \itemizey{#1.}\Eenumerate\flushcr + } + + % @alphaenumerate and @capsenumerate are abbreviations for giving an arg + % to @enumerate. + % + \def\alphaenumerate{\enumerate{a}} + \def\capsenumerate{\enumerate{A}} + \def\Ealphaenumerate{\Eenumerate} + \def\Ecapsenumerate{\Eenumerate} + + % Definition of @item while inside @itemize. + + \def\itemizeitem{% + \advance\itemno by 1 + {\let\par=\endgraf \smallbreak}% + \ifhmode \errmessage{\in hmode at itemizeitem}\fi + {\parskip=0in \hskip 0pt + \hbox to 0pt{\hss \itemcontents\hskip \itemmargin}% + \vadjust{\penalty 1200}}% + \flushcr} + + \message{indexing,} + % Index generation facilities + + % Define \newwrite to be identical to plain tex's \newwrite + % except not \outer, so it can be used within \newindex. + {\catcode`\@=11 + \gdef\newwrite{\alloc@7\write\chardef\sixt@@n}} + + % \newindex {foo} defines an index named foo. + % 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 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 + \noexpand\doindex {#1}} + } + + % @defindex foo == \newindex{foo} + + \def\defindex{\parsearg\newindex} + + % Define @defcodeindex, like @defindex except put all entries in @code. + + \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 + \noexpand\docodeindex {#1}} + } + + \def\defcodeindex{\parsearg\newcodeindex} + + % @synindex foo bar makes index foo feed into index bar. + % Do this instead of @defindex foo if you don't want it as a separate index. + \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 + \noexpand\doindex {#2}}% + } + + % @syncodeindex foo bar similar, but put all entries made for index foo + % inside @code. + \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 + \noexpand\docodeindex {#2}}% + } + + % Define \doindex, the driver for all \fooindex macros. + % Argument #1 is generated by the calling \fooindex macro, + % and it is "foo", the name of the index. + + % \doindex just uses \parsearg; it calls \doind for the actual work. + % This is because \doind is more useful to call from other macros. + + % There is also \dosubind {index}{topic}{subtopic} + % which makes an entry in a two-level index such as the operation index. + + \def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} + \def\singleindexer #1{\doind{\indexname}{#1}} + + % like the previous two, but they put @code around the argument. + \def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} + \def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} + + \def\indexdummies{% + \def\_{{\realbackslash _}}% + \def\w{\realbackslash w }% + \def\bf{\realbackslash bf }% + \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\TeX{\realbackslash TeX}% + \def\dots{\realbackslash dots }% + \def\copyright{\realbackslash copyright }% + \def\tclose##1{\realbackslash tclose {##1}}% + \def\code##1{\realbackslash code {##1}}% + \def\samp##1{\realbackslash samp {##1}}% + \def\t##1{\realbackslash r {##1}}% + \def\r##1{\realbackslash r {##1}}% + \def\i##1{\realbackslash i {##1}}% + \def\b##1{\realbackslash b {##1}}% + \def\cite##1{\realbackslash cite {##1}}% + \def\key##1{\realbackslash key {##1}}% + \def\file##1{\realbackslash file {##1}}% + \def\var##1{\realbackslash var {##1}}% + \def\kbd##1{\realbackslash kbd {##1}}% + \def\dfn##1{\realbackslash dfn {##1}}% + \def\emph##1{\realbackslash emph {##1}}% + } + + % \indexnofonts no-ops all font-change commands. + % This is used when outputting the strings to sort the index by. + \def\indexdummyfont#1{#1} + \def\indexdummytex{TeX} + \def\indexdummydots{...} + + \def\indexnofonts{% + \let\w=\indexdummyfont + \let\t=\indexdummyfont + \let\r=\indexdummyfont + \let\i=\indexdummyfont + \let\b=\indexdummyfont + \let\emph=\indexdummyfont + \let\strong=\indexdummyfont + \let\cite=\indexdummyfont + \let\sc=\indexdummyfont + %Don't no-op \tt, since it isn't a user-level command + % and is used in the definitions of the active chars like <, >, |... + %\let\tt=\indexdummyfont + \let\tclose=\indexdummyfont + \let\code=\indexdummyfont + \let\file=\indexdummyfont + \let\samp=\indexdummyfont + \let\kbd=\indexdummyfont + \let\key=\indexdummyfont + \let\var=\indexdummyfont + \let\TeX=\indexdummytex + \let\dots=\indexdummydots + } + + % To define \realbackslash, we must make \ not be an escape. + % We must first make another character (@) an escape + % so we do not become unable to do a definition. + + {\catcode`\@=0 \catcode`\\=\other + @gdef@realbackslash{\}} + + \let\indexbackslash=0 %overridden during \printindex. + + \def\doind #1#2{% + {\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}} + + \def\dosubind #1#2#3{% + {\count10=\lastpenalty % + {\indexdummies % Must do this here, since \bf, etc expand at this stage + \escapechar=`\\% + {\let\folio=0% + \def\rawbackslashxx{\indexbackslash}% + % + % 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 #3}% + }% + % 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}{#3}}}% + \temp }% + }\penalty\count10}} + + % The index entry written in the file actually looks like + % \entry {sortstring}{page}{topic} + % or + % \entry {sortstring}{page}{topic}{subtopic} + % The texindex program reads in these files and writes files + % containing these kinds of lines: + % \initial {c} + % before the first topic whose initial is c + % \entry {topic}{pagelist} + % for a topic that is used without subtopics + % \primary {topic} + % for the beginning of a topic that is used with subtopics + % \secondary {subtopic}{pagelist} + % for each subtopic. + + % Define the user-accessible indexing commands + % @findex, @vindex, @kindex, @cindex. + + \def\findex {\fnindex} + \def\kindex {\kyindex} + \def\cindex {\cpindex} + \def\vindex {\vrindex} + \def\tindex {\tpindex} + \def\pindex {\pgindex} + + \def\cindexsub {\begingroup\obeylines\cindexsub} + {\obeylines % + \gdef\cindexsub "#1" #2^^M{\endgroup % + \dosubind{cp}{#2}{#1}}} + + % Define the macros used in formatting output of the sorted index material. + + % This is what you call to cause a particular index to get printed. + % Write + % @unnumbered Function Index + % @printindex fn + + \def\printindex{\parsearg\doprintindex} + + \def\doprintindex#1{% + \tex + \dobreak \chapheadingskip {10000} + \catcode`\%=\other\catcode`\&=\other\catcode`\#=\other + \catcode`\$=\other + \catcode`\~=\other + \indexbreaks + % + % 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 + \begindoublecolumns + % + % See if the index file exists and is nonempty. + \openin 1 \jobname.#1s + \ifeof 1 + % \enddoublecolumns gets confused if there is no text in the index, + % and it loses the chapter title and the aux file entries for the + % index. The easiest way to prevent this problem is to make sure + % there is some text. + (Index is nonexistent) + \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 + % it can discover if there is anything in it. + \read 1 to \temp + \ifeof 1 + (Index is empty) + \else + \input \jobname.#1s + \fi + \fi + \closein 1 + \enddoublecolumns + \Etex + } + + % These macros are used by the sorted index file itself. + % Change them to control the appearance of the index. + + % Same as \bigskipamount except no shrink. + % \balancecolumns gets confused if there is any shrink. + \newskip\initialskipamount \initialskipamount 12pt plus4pt + + \def\initial #1{% + {\let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt + \ifdim\lastskip<\initialskipamount + \removelastskip \penalty-200 \vskip \initialskipamount\fi + \line{\secbf#1\hfill}\kern 2pt\penalty10000}} + + % This typesets a paragraph consisting of #1, dot leaders, and then #2 + % flush to the right margin. It is used for index and table of contents + % entries. The paragraph is indented by \leftskip. + % + \def\entry #1#2{\begingroup + % + % Start a new paragraph if necessary, so our assignments below can't + % affect previous text. + \par + % + % Do not fill out the last line with white space. + \parfillskip = 0in + % + % No extra space above this paragraph. + \parskip = 0in + % + % Do not prefer a separate line ending with a hyphen to fewer lines. + \finalhyphendemerits = 0 + % + % \hangindent is only relevant when the entry text and page number + % don't both fit on one line. In that case, bob suggests starting the + % dots pretty far over on the line. Unfortunately, a large + % indentation looks wrong when the entry text itself is broken across + % lines. So we use a small indentation and put up with long leaders. + % + % \hangafter is reset to 1 (which is the value we want) at the start + % of each paragraph, so we need not do anything with that. + \hangindent=2em + % + % When the entry text needs to be broken, just fill out the first line + % with blank space. + \rightskip = 0pt plus1fil + % + % Start a ``paragraph'' for the index entry so the line breaking + % parameters we've set above will have an effect. + \noindent + % + % Insert the text of the index entry. TeX will do line-breaking on it. + #1% + % The following is kluged to not output a line of dots in the index if + % there are no page numbers. The next person who breaks this will be + % cursed by a Unix daemon. + \def\tempa{{\rm }}% + \def\tempb{#2}% + \edef\tempc{\tempa}% + \edef\tempd{\tempb}% + \ifx\tempc\tempd\ \else% + % + % If we must, put the page number on a line of its own, and fill out + % this line with blank space. (The \hfil is overwhelmed with the + % fill leaders glue in \indexdotfill if the page number does fit.) + \hfil\penalty50 + \null\nobreak\indexdotfill % Have leaders before the page number. + % + % The `\ ' here is removed by the implicit \unskip that TeX does as + % part of (the primitive) \par. Without it, a spurious underfull + % \hbox ensues. + \ #2% The page number ends the paragraph. + \fi% + \par + \endgroup} + + % Like \dotfill except takes at least 1 em. + \def\indexdotfill{\cleaders + \hbox{$\mathsurround=0pt \mkern1.5mu . \mkern1.5mu$}\hskip 1em plus 1fill} + + \def\primary #1{\line{#1\hfil}} + + \newskip\secondaryindent \secondaryindent=0.5cm + + \def\secondary #1#2{ + {\parfillskip=0in \parskip=0in + \hangindent =1in \hangafter=1 + \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 + + \newbox\partialpage + + \newdimen\doublecolumnhsize + + \def\begindoublecolumns{\begingroup + % Grab any single-column material above us. + \output = {\global\setbox\partialpage + =\vbox{\unvbox255\kern -\topskip \kern \baselineskip}}% + \eject + % + % Now switch to the double-column output routine. + \output={\doublecolumnout}% + % + % Change the page size parameters. We could do this once outside this + % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 + % format, but then we repeat the same computation. Repeating a couple + % of assignments once per index is clearly meaningless for the + % execution time, so we may as well do it once. + % + % First we halve the line length, less a little for the gutter between + % the columns. We compute the gutter based on the line length, so it + % changes automatically with the paper format. The magic constant + % below is chosen so that the gutter has the same value (well, +- < + % 1pt) as it did when we hard-coded it. + % + % We put the result in a separate register, \doublecolumhsize, so we + % can restore it in \pagesofar, after \hsize itself has (potentially) + % been clobbered. + % + \doublecolumnhsize = \hsize + \advance\doublecolumnhsize by -.04154\hsize + \divide\doublecolumnhsize by 2 + \hsize = \doublecolumnhsize + % + % 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\doublecolumnpagegoal{% + \dimen@=\vsize \advance\dimen@ by-2\ht\partialpage \global\pagegoal=\dimen@ + } + \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 + } + + \catcode `\@=\other + \message{sectioning,} + % Define chapters, sections, etc. + + \newcount \chapno + \newcount \secno \secno=0 + \newcount \subsecno \subsecno=0 + \newcount \subsubsecno \subsubsecno=0 + + % This counter is funny since it counts through charcodes of letters A, B, ... + \newcount \appendixno \appendixno = `\@ + \def\appendixletter{\char\the\appendixno} + + \newwrite \contentsfile + % This is called from \setfilename. + \def\opencontents{\openout \contentsfile = \jobname.toc} + + % Each @chapter defines this as the name of the chapter. + % page headings and footings can use it. @section does likewise + + \def\thischapter{} \def\thissection{} + \def\seccheck#1{\if \pageno<0 % + \errmessage{@#1 not allowed after generating table of contents}\fi + % + } + + \def\chapternofonts{% + \let\rawbackslash=\relax% + \let\frenchspacing=\relax% + \def\result{\realbackslash result} + \def\equiv{\realbackslash equiv} + \def\expansion{\realbackslash expansion} + \def\print{\realbackslash print} + \def\TeX{\realbackslash TeX} + \def\dots{\realbackslash dots} + \def\copyright{\realbackslash copyright} + \def\tt{\realbackslash tt} + \def\bf{\realbackslash bf } + \def\w{\realbackslash w} + \def\less{\realbackslash less} + \def\gtr{\realbackslash gtr} + \def\hat{\realbackslash hat} + \def\char{\realbackslash char} + \def\tclose##1{\realbackslash tclose {##1}} + \def\code##1{\realbackslash code {##1}} + \def\samp##1{\realbackslash samp {##1}} + \def\r##1{\realbackslash r {##1}} + \def\b##1{\realbackslash b {##1}} + \def\key##1{\realbackslash key {##1}} + \def\file##1{\realbackslash file {##1}} + \def\kbd##1{\realbackslash kbd {##1}} + % These are redefined because @smartitalic wouldn't work inside xdef. + \def\i##1{\realbackslash i {##1}} + \def\cite##1{\realbackslash cite {##1}} + \def\var##1{\realbackslash var {##1}} + \def\emph##1{\realbackslash emph {##1}} + \def\dfn##1{\realbackslash dfn {##1}} + } + + \newcount\absseclevel % used to calculate proper heading level + \newcount\secbase\secbase=0 % @raise/lowersections modify this count + + % @raisesections: treat @section as chapter, @subsection as section, etc. + \def\raisesections{\global\advance\secbase by -1} + \let\up=\raisesections % original BFox name + + % @lowersections: treat @chapter as section, @section as subsection, etc. + \def\lowersections{\global\advance\secbase by 1} + \let\down=\lowersections % original BFox name + + % Choose a numbered-heading macro + % #1 is heading level if unmodified by @raisesections or @lowersections + % #2 is text for heading + \def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 + \ifcase\absseclevel + \chapterzzz{#2} + \or + \seczzz{#2} + \or + \numberedsubseczzz{#2} + \or + \numberedsubsubseczzz{#2} + \else + \ifnum \absseclevel<0 + \chapterzzz{#2} + \else + \numberedsubsubseczzz{#2} + \fi + \fi + } + + % like \numhead, but chooses appendix heading levels + \def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 + \ifcase\absseclevel + \appendixzzz{#2} + \or + \appendixsectionzzz{#2} + \or + \appendixsubseczzz{#2} + \or + \appendixsubsubseczzz{#2} + \else + \ifnum \absseclevel<0 + \appendixzzz{#2} + \else + \appendixsubsubseczzz{#2} + \fi + \fi + } + + % like \numhead, but chooses numberless heading levels + \def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 + \ifcase\absseclevel + \unnumberedzzz{#2} + \or + \unnumberedseczzz{#2} + \or + \unnumberedsubseczzz{#2} + \or + \unnumberedsubsubseczzz{#2} + \else + \ifnum \absseclevel<0 + \unnumberedzzz{#2} + \else + \unnumberedsubsubseczzz{#2} + \fi + \fi + } + + + \def\thischaptername{No Chapter Title} + \outer\def\chapter{\parsearg\chapteryyy} + \def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz + \def\chapterzzz #1{\seccheck{chapter}% + \secno=0 \subsecno=0 \subsubsecno=0 + \global\advance \chapno by 1 \message{Chapter \the\chapno}% + \chapmacro {#1}{\the\chapno}% + \gdef\thissection{#1}% + \gdef\thischaptername{#1}% + % We don't substitute the actual chapter name into \thischapter + % because we don't want its macros evaluated now. + \xdef\thischapter{Chapter \the\chapno: \noexpand\thischaptername}% + {\chapternofonts% + \edef\temp{{\realbackslash chapentry {#1}{\the\chapno}{\noexpand\folio}}}% + \escapechar=`\\% + \write \contentsfile \temp % + \donoderef % + \global\let\section = \numberedsec + \global\let\subsection = \numberedsubsec + \global\let\subsubsection = \numberedsubsubsec + }} + + \outer\def\appendix{\parsearg\appendixyyy} + \def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz + \def\appendixzzz #1{\seccheck{appendix}% + \secno=0 \subsecno=0 \subsubsecno=0 + \global\advance \appendixno by 1 \message{Appendix \appendixletter}% + \chapmacro {#1}{Appendix \appendixletter}% + \gdef\thissection{#1}% + \gdef\thischaptername{#1}% + \xdef\thischapter{Appendix \appendixletter: \noexpand\thischaptername}% + {\chapternofonts% + \edef\temp{{\realbackslash chapentry + {#1}{Appendix \appendixletter}{\noexpand\folio}}}% + \escapechar=`\\% + \write \contentsfile \temp % + \appendixnoderef % + \global\let\section = \appendixsec + \global\let\subsection = \appendixsubsec + \global\let\subsubsection = \appendixsubsubsec + }} + + \outer\def\top{\parsearg\unnumberedyyy} + \outer\def\unnumbered{\parsearg\unnumberedyyy} + \def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz + \def\unnumberedzzz #1{\seccheck{unnumbered}% + \secno=0 \subsecno=0 \subsubsecno=0 + % + % This used to be simply \message{#1}, but TeX fully expands the + % argument to \message. Therefore, if #1 contained @-commands, TeX + % expanded them. For example, in `@unnumbered The @cite{Book}', TeX + % expanded @cite (which turns out to cause errors because \cite is meant + % to be executed, not expanded). + % + % Anyway, we don't want the fully-expanded definition of @cite to appear + % as a result of the \message, we just want `@cite' itself. We use + % \the to achieve this: TeX expands \the only once, + % simply yielding the contents of the . + \toks0 = {#1}\message{(\the\toks0)}% + % + \unnumbchapmacro {#1}% + \gdef\thischapter{#1}\gdef\thissection{#1}% + {\chapternofonts% + \edef\temp{{\realbackslash unnumbchapentry {#1}{\noexpand\folio}}}% + \escapechar=`\\% + \write \contentsfile \temp % + \unnumbnoderef % + \global\let\section = \unnumberedsec + \global\let\subsection = \unnumberedsubsec + \global\let\subsubsection = \unnumberedsubsubsec + }} + + \outer\def\numberedsec{\parsearg\secyyy} + \def\secyyy #1{\numhead1{#1}} % normally calls seczzz + \def\seczzz #1{\seccheck{section}% + \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % + \gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}% + {\chapternofonts% + \edef\temp{{\realbackslash secentry % + {#1}{\the\chapno}{\the\secno}{\noexpand\folio}}}% + \escapechar=`\\% + \write \contentsfile \temp % + \donoderef % + \penalty 10000 % + }} + + \outer\def\appenixsection{\parsearg\appendixsecyyy} + \outer\def\appendixsec{\parsearg\appendixsecyyy} + \def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz + \def\appendixsectionzzz #1{\seccheck{appendixsection}% + \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % + \gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}% + {\chapternofonts% + \edef\temp{{\realbackslash secentry % + {#1}{\appendixletter}{\the\secno}{\noexpand\folio}}}% + \escapechar=`\\% + \write \contentsfile \temp % + \appendixnoderef % + \penalty 10000 % + }} + + \outer\def\unnumberedsec{\parsearg\unnumberedsecyyy} + \def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz + \def\unnumberedseczzz #1{\seccheck{unnumberedsec}% + \plainsecheading {#1}\gdef\thissection{#1}% + {\chapternofonts% + \edef\temp{{\realbackslash unnumbsecentry{#1}{\noexpand\folio}}}% + \escapechar=`\\% + \write \contentsfile \temp % + \unnumbnoderef % + \penalty 10000 % + }} + + \outer\def\numberedsubsec{\parsearg\numberedsubsecyyy} + \def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz + \def\numberedsubseczzz #1{\seccheck{subsection}% + \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % + \subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}% + {\chapternofonts% + \edef\temp{{\realbackslash subsecentry % + {#1}{\the\chapno}{\the\secno}{\the\subsecno}{\noexpand\folio}}}% + \escapechar=`\\% + \write \contentsfile \temp % + \donoderef % + \penalty 10000 % + }} + + \outer\def\appendixsubsec{\parsearg\appendixsubsecyyy} + \def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz + \def\appendixsubseczzz #1{\seccheck{appendixsubsec}% + \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % + \subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}% + {\chapternofonts% + \edef\temp{{\realbackslash subsecentry % + {#1}{\appendixletter}{\the\secno}{\the\subsecno}{\noexpand\folio}}}% + \escapechar=`\\% + \write \contentsfile \temp % + \appendixnoderef % + \penalty 10000 % + }} + + \outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy} + \def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz + \def\unnumberedsubseczzz #1{\seccheck{unnumberedsubsec}% + \plainsecheading {#1}\gdef\thissection{#1}% + {\chapternofonts% + \edef\temp{{\realbackslash unnumbsubsecentry{#1}{\noexpand\folio}}}% + \escapechar=`\\% + \write \contentsfile \temp % + \unnumbnoderef % + \penalty 10000 % + }} + + \outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy} + \def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz + \def\numberedsubsubseczzz #1{\seccheck{subsubsection}% + \gdef\thissection{#1}\global\advance \subsubsecno by 1 % + \subsubsecheading {#1} + {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}% + {\chapternofonts% + \edef\temp{{\realbackslash subsubsecentry % + {#1} + {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno} + {\noexpand\folio}}}% + \escapechar=`\\% + \write \contentsfile \temp % + \donoderef % + \penalty 10000 % + }} + + \outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy} + \def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz + \def\appendixsubsubseczzz #1{\seccheck{appendixsubsubsec}% + \gdef\thissection{#1}\global\advance \subsubsecno by 1 % + \subsubsecheading {#1} + {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}% + {\chapternofonts% + \edef\temp{{\realbackslash subsubsecentry{#1}% + {\appendixletter} + {\the\secno}{\the\subsecno}{\the\subsubsecno}{\noexpand\folio}}}% + \escapechar=`\\% + \write \contentsfile \temp % + \appendixnoderef % + \penalty 10000 % + }} + + \outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy} + \def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz + \def\unnumberedsubsubseczzz #1{\seccheck{unnumberedsubsubsec}% + \plainsecheading {#1}\gdef\thissection{#1}% + {\chapternofonts% + \edef\temp{{\realbackslash unnumbsubsubsecentry{#1}{\noexpand\folio}}}% + \escapechar=`\\% + \write \contentsfile \temp % + \unnumbnoderef % + \penalty 10000 % + }} + + % These are variants which are not "outer", so they can appear in @ifinfo. + % Actually, they should now be obsolete; ordinary section commands should work. + \def\infotop{\parsearg\unnumberedzzz} + \def\infounnumbered{\parsearg\unnumberedzzz} + \def\infounnumberedsec{\parsearg\unnumberedseczzz} + \def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz} + \def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz} + + \def\infoappendix{\parsearg\appendixzzz} + \def\infoappendixsec{\parsearg\appendixseczzz} + \def\infoappendixsubsec{\parsearg\appendixsubseczzz} + \def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz} + + \def\infochapter{\parsearg\chapterzzz} + \def\infosection{\parsearg\sectionzzz} + \def\infosubsection{\parsearg\subsectionzzz} + \def\infosubsubsection{\parsearg\subsubsectionzzz} + + % These macros control what the section commands do, according + % to what kind of chapter we are in (ordinary, appendix, or unnumbered). + % Define them by default for a numbered chapter. + \global\let\section = \numberedsec + \global\let\subsection = \numberedsubsec + \global\let\subsubsection = \numberedsubsubsec + + % Define @majorheading, @heading and @subheading + + % 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. + % 3) Likewise, headings look best if no \parindent is used, and + % if justification is not attempted. Hence \raggedright. + + + \def\majorheading{\parsearg\majorheadingzzz} + \def\majorheadingzzz #1{% + {\advance\chapheadingskip by 10pt \chapbreak }% + {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}\bigskip \par\penalty 200} + + \def\chapheading{\parsearg\chapheadingzzz} + \def\chapheadingzzz #1{\chapbreak % + {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}\bigskip \par\penalty 200} + + \def\heading{\parsearg\secheadingi} + + \def\subheading{\parsearg\subsecheadingi} + + \def\subsubheading{\parsearg\subsubsecheadingi} + + % These macros generate a chapter, section, etc. heading only + % (including whitespace, linebreaking, etc. around it), + % given all the information in convenient, parsed form. + + %%% Args are the skip and penalty (usually negative) + \def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} + + \def\setchapterstyle #1 {\csname CHAPF#1\endcsname} + + %%% 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 + + \def\chapbreak{\dobreak \chapheadingskip {-4000}} + \def\chappager{\par\vfill\supereject} + \def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi} + + \def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} + + \def\CHAPPAGoff{ + \global\let\pchapsepmacro=\chapbreak + \global\let\pagealignmacro=\chappager} + + \def\CHAPPAGon{ + \global\let\pchapsepmacro=\chappager + \global\let\pagealignmacro=\chappager + \global\def\HEADINGSon{\HEADINGSsingle}} + + \def\CHAPPAGodd{ + \global\let\pchapsepmacro=\chapoddpage + \global\let\pagealignmacro=\chapoddpage + \global\def\HEADINGSon{\HEADINGSdouble}} + + \CHAPPAGon + + \def\CHAPFplain{ + \global\let\chapmacro=\chfplain + \global\let\unnumbchapmacro=\unnchfplain} + + \def\chfplain #1#2{% + \pchapsepmacro + {% + \chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #2\enspace #1}% + }% + \bigskip + \penalty5000 + } + + \def\unnchfplain #1{% + \pchapsepmacro % + {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}\bigskip \par\penalty 10000 % + } + \CHAPFplain % The default + + \def\unnchfopen #1{% + \chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}\bigskip \par\penalty 10000 % + } + + \def\chfopen #1#2{\chapoddpage {\chapfonts + \vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% + \par\penalty 5000 % + } + + \def\CHAPFopen{ + \global\let\chapmacro=\chfopen + \global\let\unnumbchapmacro=\unnchfopen} + + % Parameter controlling skip before section headings. + + \newskip \subsecheadingskip \subsecheadingskip = 17pt plus 8pt minus 4pt + \def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}} + + \newskip \secheadingskip \secheadingskip = 21pt plus 8pt minus 4pt + \def\secheadingbreak{\dobreak \secheadingskip {-1000}} + + % @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} + + + \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 + \immediate\closeout \contentsfile + \ifnum \pageno>0 + \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. + \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 + \raggedbottom % Worry more about breakpoints than the bottom. + \advance\hsize by -\contentsrightmargin % Don't use the full line length. + } + + + % Normal (long) toc. + \outer\def\contents{% + \startcontents{Table of Contents}% + \input \jobname.toc + \endgroup + \vfill \eject + } + + % And just the chapters. + \outer\def\summarycontents{% + \startcontents{Short Contents}% + % + \let\chapentry = \shortchapentry + \let\unnumbchapentry = \shortunnumberedentry + % We want a true roman here for the page numbers. + \secfonts + \let\rm=\shortcontrm \let\bf=\shortcontbf \let\sl=\shortcontsl + \rm + \advance\baselineskip by 1pt % Open it up a little. + \def\secentry ##1##2##3##4{} + \def\unnumbsecentry ##1##2{} + \def\subsecentry ##1##2##3##4##5{} + \def\unnumbsubsecentry ##1##2{} + \def\subsubsecentry ##1##2##3##4##5##6{} + \def\unnumbsubsubsecentry ##1##2{} + \input \jobname.toc + \endgroup + \vfill \eject + } + \let\shortcontents = \summarycontents + + % These macros generate individual entries in the table of contents. + % The first argument is the chapter or section name. + % The last argument is the page number. + % The arguments in between are the chapter number, section number, ... + + % Chapter-level things, for both the long and short contents. + \def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}} + + % See comments in \dochapentry re vbox and related settings + \def\shortchapentry#1#2#3{% + \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno{#3}}% + } + + % Typeset the label for a chapter or appendix for the short contents. + % The arg is, e.g. `Appendix A' for an appendix, or `3' for a chapter. + % We could simplify the code here by writing out an \appendixentry + % command in the toc file for appendices, instead of using \chapentry + % for both, but it doesn't seem worth it. + \setbox0 = \hbox{\shortcontrm Appendix } + \newdimen\shortappendixwidth \shortappendixwidth = \wd0 + + \def\shortchaplabel#1{% + % We typeset #1 in a box of constant width, regardless of the text of + % #1, so the chapter titles will come out aligned. + \setbox0 = \hbox{#1}% + \dimen0 = \ifdim\wd0 > \shortappendixwidth \shortappendixwidth \else 0pt \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.) + \advance\dimen0 by 1.1em + \hbox to \dimen0{#1\hfil}% + } + + \def\unnumbchapentry#1#2{\dochapentry{#1}{#2}} + \def\shortunnumberedentry#1#2{\tocentry{#1}{\doshortpageno{#2}}} + + % Sections. + \def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}} + \def\unnumbsecentry#1#2{\dosecentry{#1}{#2}} + + % Subsections. + \def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}} + \def\unnumbsubsecentry#1#2{\dosubsecentry{#1}{#2}} + + % And subsubsections. + \def\subsubsecentry#1#2#3#4#5#6{% + \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 at all possible; hence the \penalty. + \def\dochapentry#1#2{% + \penalty-300 \vskip\baselineskip + \begingroup + \chapentryfonts + \tocentry{#1}{\dopageno{#2}}% + \endgroup + \nobreak\vskip .25\baselineskip + } + + \def\dosecentry#1#2{\begingroup + \secentryfonts \leftskip=\tocindent + \tocentry{#1}{\dopageno{#2}}% + \endgroup} + + \def\dosubsecentry#1#2{\begingroup + \subsecentryfonts \leftskip=2\tocindent + \tocentry{#1}{\dopageno{#2}}% + \endgroup} + + \def\dosubsubsecentry#1#2{\begingroup + \subsubsecentryfonts \leftskip=3\tocindent + \tocentry{#1}{\dopageno{#2}}% + \endgroup} + + % Final typesetting of a toc entry; we use the same \entry macro as for + % the index entries, but we want to suppress hyphenation here. (We + % can't do that in the \entry macro, since index entries might consist + % of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) + % + \def\tocentry#1#2{\begingroup + \hyphenpenalty = 10000 + \entry{#1}{#2}% + \endgroup} + + % Space between chapter (or whatever) number and the title. + \def\labelspace{\hskip1em \relax} + + \def\dopageno#1{{\rm #1}} + \def\doshortpageno#1{{\rm #1}} + + \def\chapentryfonts{\secfonts \rm} + \def\secentryfonts{\textfonts} + \let\subsecentryfonts = \textfonts + \let\subsubsecentryfonts = \textfonts + + + \message{environments,} + + % Since these characters are used in examples, it should be an even number of + % \tt widths. Each \tt character is 1en, so two makes it 1em. + % Furthermore, these definitions must come after we define our fonts. + \newbox\dblarrowbox \newbox\longdblarrowbox + \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} + %\global\setbox\pushcharbox = \hbox to 1em{\hfil$\dashv$\hfil} + %\global\setbox\equivbox = \hbox to 1em{\hfil$\ptexequiv$\hfil} + % Adapted from the manmac format (p.420 of TeXbook) + %\global\setbox\bullbox = \hbox to 1em{\kern.15em\vrule height .75ex width .85ex + % depth .1ex\hfil} + %} + + \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. + {\tentt \global\dimen0 = 3em}% Width of the box. + \dimen2 = .55pt % Thickness of rules + % The text. (`r' is open on the right, `e' somewhat less so on the left.) + \setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt} + + \global\setbox\errorbox=\hbox to \dimen0{\hfil + \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. + \advance\hsize by -2\dimen2 % Rules. + \vbox{ + \hrule height\dimen2 + \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. + \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. + \kern3pt\vrule width\dimen2}% Space to right. + \hrule height\dimen2} + \hfil} + + % The @error{} command. + \def\error{\leavevmode\lower.7ex\copy\errorbox} + + % @tex ... @end tex escapes into raw Tex temporarily. + % One exception: @ is still an escape character, so that @end tex works. + % But \@ or @@ will get a plain tex @ character. + + \def\tex{\begingroup + \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 + \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 + \catcode `\^=7 \catcode `\_=8 \catcode `\~=13 \let~=\tie + \catcode `\%=14 + \catcode 43=12 + \catcode`\"=12 + \catcode`\==12 + \catcode`\|=12 + \catcode`\<=12 + \catcode`\>=12 + \escapechar=`\\ + % + \let\{=\ptexlbrace + \let\}=\ptexrbrace + \let\.=\ptexdot + \let\*=\ptexstar + \let\dots=\ptexdots + \def\@{@}% + \let\bullet=\ptexbullet + \let\b=\ptexb \let\c=\ptexc \let\i=\ptexi \let\t=\ptext \let\l=\ptexl + \let\L=\ptexL + % + \let\Etex=\endgroup} + + % Define @lisp ... @endlisp. + % @lisp does a \begingroup so it can rebind things, + % including the definition of @endlisp (which normally is erroneous). + + % Amount to narrow the margins by for @lisp. + \newskip\lispnarrowing \lispnarrowing=0.4in + + % This is the definition that ^^M gets inside @lisp, @example, and other + % such environments. \null is better than a space, since it doesn't + % have any width. + \def\lisppar{\null\endgraf} + + % Make each space character in the input produce a normal interword + % space in the output. Don't allow a line break at this space, as this + % is used only in environments like @example, where each line of input + % should produce a line of output anyway. + % + {\obeyspaces % + \gdef\sepspaces{\obeyspaces\let =\tie}} + + % Define \obeyedspace to be our active space, whatever it is. This is + % for use in \parsearg. + {\sepspaces% + \global\let\obeyedspace= } + + % This space is always present above and below environments. + \newskip\envskipamount \envskipamount = 0pt + + % Make spacing and below environment symmetrical. We use \parskip here + % to help in doing that, since in @example-like environments \parskip + % is reset to zero; thus the \afterenvbreak inserts no space -- but the + % start of the next paragraph will insert \parskip + % + \def\aboveenvbreak{{\advance\envskipamount by \parskip + \endgraf \ifdim\lastskip<\envskipamount + \removelastskip \penalty-50 \vskip\envskipamount \fi}} + + \let\afterenvbreak = \aboveenvbreak + + % \nonarrowing is a flag. If "set", @lisp etc don't narrow margins. + \let\nonarrowing=\relax + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % \cartouche: draw rectangle w/rounded corners around argument + \font\circle=lcircle10 + \newdimen\circthick + \newdimen\cartouter\newdimen\cartinner + \newskip\normbskip\newskip\normpskip\newskip\normlskip + \circthick=\fontdimen8\circle + % + \def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth + \def\ctr{{\hskip 6pt\circle\char'010}} + \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}} + \def\cartbot{\hbox to \cartouter{\hskip\lskip + \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 + \def\Ecartouche{% + \endgroup + \kern3pt + \egroup + \kern3pt\vrule + \hskip\rskip + \egroup + \cartbot + \egroup + \endgroup + }} + + + % This macro is called at the beginning of all the @example variants, + % inside a group. + \def\nonfillstart{% + \aboveenvbreak + \inENV % This group ends at the end of the body + \hfuzz = 12pt % Don't be fussy + \sepspaces % Make spaces be word-separators rather than space tokens. + \singlespace + \let\par = \lisppar % don't ignore blank lines + \obeylines % each line of input is a line of output + \parskip = 0pt + \parindent = 0pt + \emergencystretch = 0pt % don't try to avoid overfull boxes + % @cartouche defines \nonarrowing to inhibit narrowing + % at next level down. + \ifx\nonarrowing\relax + \advance \leftskip by \lispnarrowing + \exdentamount=\lispnarrowing + \let\exdent=\nofillexdent + \let\nonarrowing=\relax + \fi + } + + % To ending an @example-like environment, we first end the paragraph + % (via \afterenvbreak's vertical glue), and then the group. That way we + % keep the zero \parskip that the environments set -- \parskip glue + % will be inserted at the beginning of the next paragraph in the + % document, after the environment. + % + \def\nonfillfinish{\afterenvbreak\endgroup}% + + % This macro is + \def\lisp{\begingroup + \nonfillstart + \let\Elisp = \nonfillfinish + \tt + \rawbackslash % have \ input char produce \ char from current font + \gobble + } + + % Define the \E... control sequence only if we are inside the + % environment, so the error checking in \end will work. + % + % We must call \lisp last in the definition, since it reads the + % return following the @example (or whatever) command. + % + \def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp} + \def\smallexample{\begingroup \def\Esmallexample{\nonfillfinish\endgroup}\lisp} + \def\smalllisp{\begingroup \def\Esmalllisp{\nonfillfinish\endgroup}\lisp} + + % @smallexample and @smalllisp. This is not used unless the @smallbook + % command is given. Originally contributed by Pavel@xerox. + % + \def\smalllispx{\begingroup + \nonfillstart + \let\Esmalllisp = \nonfillfinish + \let\Esmallexample = \nonfillfinish + % + % Smaller interline space and fonts for small examples. + \baselineskip 10pt + \indexfonts \tt + \rawbackslash % output the \ character from the current font + \gobble + } + + % This is @display; same as @lisp except use roman font. + % + \def\display{\begingroup + \nonfillstart + \let\Edisplay = \nonfillfinish + \gobble + } + + % This is @format; same as @display except don't narrow margins. + % + \def\format{\begingroup + \let\nonarrowing = t + \nonfillstart + \let\Eformat = \nonfillfinish + \gobble + } + + % @flushleft (same as @format) and @flushright. + % + \def\flushleft{\begingroup + \let\nonarrowing = t + \nonfillstart + \let\Eflushleft = \nonfillfinish + \gobble + } + \def\flushright{\begingroup + \let\nonarrowing = t + \nonfillstart + \let\Eflushright = \nonfillfinish + \advance\leftskip by 0pt plus 1fill + \gobble} + + % @quotation does normal linebreaking and narrows the margins. + % + \def\quotation{% + \begingroup\inENV %This group ends at the end of the @quotation body + {\parskip=0pt % because we will skip by \parskip too, later + \aboveenvbreak}% + \singlespace + \parindent=0pt + \let\Equotation = \nonfillfinish + % @cartouche defines \nonarrowing to inhibit narrowing + % at next level down. + \ifx\nonarrowing\relax + \advance \leftskip by \lispnarrowing + \advance \rightskip by \lispnarrowing + \exdentamount=\lispnarrowing + \let\nonarrowing=\relax + \fi} + + \message{defuns,} + % Define formatter for defuns + % First, allow user to change definition object font (\df) internally + \def\setdeffont #1 {\csname DEF#1\endcsname} + + \newskip\defbodyindent \defbodyindent=.4in + \newskip\defargsindent \defargsindent=50pt + \newskip\deftypemargin \deftypemargin=12pt + \newskip\deflastargmargin \deflastargmargin=18pt + + \newcount\parencount + % define \functionparens, which makes ( and ) and & do special things. + % \functionparens affects the group it is contained in. + \def\activeparens{% + \catcode`\(=\active \catcode`\)=\active \catcode`\&=\active + \catcode`\[=\active \catcode`\]=\active} + + % Make control sequences which act like normal parenthesis chars. + \let\lparen = ( \let\rparen = ) + + {\activeparens % Now, smart parens don't turn on until &foo (see \amprm) + + % Be sure that we always have a definition for `(', etc. For example, + % if the fn name has parens in it, \boldbrax will not be in effect yet, + % so TeX would otherwise complain about undefined control sequence. + \global\let(=\lparen \global\let)=\rparen + \global\let[=\lbrack \global\let]=\rbrack + + \gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } + \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} + + % Definitions of (, ) and & used in args for functions. + % This is the definition of ( outside of all parentheses. + \gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested % + \global\advance\parencount by 1 } + % + % This is the definition of ( when already inside a level of parens. + \gdef\opnested{\char`\(\global\advance\parencount by 1 } + % + \gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0. + % also in that case restore the outer-level definition of (. + \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi + \global\advance \parencount by -1 } + % If we encounter &foo, then turn on ()-hacking afterwards + \gdef\amprm#1 {{\rm\}\let(=\oprm \let)=\clrm\ } + % + \gdef\normalparens{\boldbrax\let&=\ampnr} + } % End of definition inside \activeparens + %% These parens (in \boldbrax) actually are a little bolder than the + %% contained text. This is especially needed for [ and ] + \def\opnr{{\sf\char`\(}} \def\clnr{{\sf\char`\)}} \def\ampnr{\&} + \def\lbrb{{\bf\char`\[}} \def\rbrb{{\bf\char`\]}} + + % First, defname, which formats the header line itself. + % #1 should be the function name. + % #2 should be the type of definition, such as "Function". + + \def\defname #1#2{% + % Get the values of \leftskip and \rightskip as they were + % outside the @def... + \dimen2=\leftskip + \advance\dimen2 by -\defbodyindent + \dimen3=\rightskip + \advance\dimen3 by -\defbodyindent + \noindent % + \setbox0=\hbox{\hskip \deflastargmargin{\rm #2}\hskip \deftypemargin}% + \dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line + \dimen1=\hsize \advance \dimen1 by -\defargsindent %size for continuations + \parshape 2 0in \dimen0 \defargsindent \dimen1 % + % Now output arg 2 ("Function" or some such) + % ending at \deftypemargin from the right margin, + % but stuck inside a box of width 0 so it does not interfere with linebreaking + {% Adjust \hsize to exclude the ambient margins, + % so that \rightline will obey them. + \advance \hsize by -\dimen2 \advance \hsize by -\dimen3 + \rlap{\rightline{{\rm #2}\hskip \deftypemargin}}}% + % Make all lines underfull and no complaints: + \tolerance=10000 \hbadness=10000 + \advance\leftskip by -\defbodyindent + \exdentamount=\defbodyindent + {\df #1}\enskip % Generate function name + } + + % Actually process the body of a definition + % #1 should be the terminating control sequence, such as \Edefun. + % #2 should be the "another name" control sequence, such as \defunx. + % #3 should be the control sequence that actually processes the header, + % such as \defunheader. + + \def\defparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody + \medbreak % + % Define the end token that this defining construct specifies + % so that it will exit this group. + \def#1{\endgraf\endgroup\medbreak}% + \def#2{\begingroup\obeylines\activeparens\spacesplit#3}% + \parindent=0in + \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent + \exdentamount=\defbodyindent + \begingroup % + \catcode 61=\active % 61 is `=' + \obeylines\activeparens\spacesplit#3} + + \def\defmethparsebody #1#2#3#4 {\begingroup\inENV % + \medbreak % + % Define the end token that this defining construct specifies + % so that it will exit this group. + \def#1{\endgraf\endgroup\medbreak}% + \def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}% + \parindent=0in + \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent + \exdentamount=\defbodyindent + \begingroup\obeylines\activeparens\spacesplit{#3{#4}}} + + \def\defopparsebody #1#2#3#4#5 {\begingroup\inENV % + \medbreak % + % Define the end token that this defining construct specifies + % so that it will exit this group. + \def#1{\endgraf\endgroup\medbreak}% + \def#2##1 ##2 {\def#4{##1}% + \begingroup\obeylines\activeparens\spacesplit{#3{##2}}}% + \parindent=0in + \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent + \exdentamount=\defbodyindent + \begingroup\obeylines\activeparens\spacesplit{#3{#5}}} + + % These parsing functions are similar to the preceding ones + % except that they do not make parens into active characters. + % These are used for "variables" since they have no arguments. + + \def\defvarparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody + \medbreak % + % Define the end token that this defining construct specifies + % so that it will exit this group. + \def#1{\endgraf\endgroup\medbreak}% + \def#2{\begingroup\obeylines\spacesplit#3}% + \parindent=0in + \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent + \exdentamount=\defbodyindent + \begingroup % + \catcode 61=\active % + \obeylines\spacesplit#3} + + % This is used for \def{tp,vr}parsebody. It could probably be used for + % some of the others, too, with some judicious conditionals. + % + \def\parsebodycommon#1#2#3{% + \begingroup\inENV % + \medbreak % + % Define the end token that this defining construct specifies + % so that it will exit this group. + \def#1{\endgraf\endgroup\medbreak}% + \def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}% + \parindent=0in + \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent + \exdentamount=\defbodyindent + \begingroup\obeylines + } + + \def\defvrparsebody#1#2#3#4 {% + \parsebodycommon{#1}{#2}{#3}% + \spacesplit{#3{#4}}% + } + + % This loses on `@deftp {Data Type} {struct termios}' -- it thinks the + % type is just `struct', because we lose the braces in `{struct + % termios}' when \spacesplit reads its undelimited argument. Sigh. + % \let\deftpparsebody=\defvrparsebody + % + % So, to get around this, we put \empty in with the type name. That + % way, TeX won't find exactly `{...}' as an undelimited argument, and + % won't strip off the braces. + % + \def\deftpparsebody #1#2#3#4 {% + \parsebodycommon{#1}{#2}{#3}% + \spacesplit{\parsetpheaderline{#3{#4}}}\empty + } + + % 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. + % + \def\removeemptybraces\empty#1\relax{\def\tptemp{#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}% + }% + + \def\defopvarparsebody #1#2#3#4#5 {\begingroup\inENV % + \medbreak % + % Define the end token that this defining construct specifies + % so that it will exit this group. + \def#1{\endgraf\endgroup\medbreak}% + \def#2##1 ##2 {\def#4{##1}% + \begingroup\obeylines\spacesplit{#3{##2}}}% + \parindent=0in + \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent + \exdentamount=\defbodyindent + \begingroup\obeylines\spacesplit{#3{#5}}} + + % Split up #2 at the first space token. + % call #1 with two arguments: + % the first is all of #2 before the space token, + % the second is all of #2 after that space token. + % If #2 contains no space token, all of it is passed as the first arg + % and the second is passed as empty. + + {\obeylines + \gdef\spacesplit#1#2^^M{\endgroup\spacesplitfoo{#1}#2 \relax\spacesplitfoo}% + \long\gdef\spacesplitfoo#1#2 #3#4\spacesplitfoo{% + \ifx\relax #3% + #1{#2}{}\else #1{#2}{#3#4}\fi}} + + % So much for the things common to all kinds of definitions. + + % Define @defun. + + % First, define the processing that is wanted for arguments of \defun + % Use this to expand the args and terminate the paragraph they make up + + \def\defunargs #1{\functionparens \sl + % Expand, preventing hyphenation at `-' chars. + % Note that groups don't affect changes in \hyphenchar. + \hyphenchar\tensl=0 + #1% + \hyphenchar\tensl=45 + \ifnum\parencount=0 \else \errmessage{unbalanced parens in @def arguments}\fi% + \interlinepenalty=10000 + \advance\rightskip by 0pt plus 1fil + \endgraf\penalty 10000\vskip -\parskip\penalty 10000% + } + + \def\deftypefunargs #1{% + % Expand, preventing hyphenation at `-' chars. + % Note that groups don't affect changes in \hyphenchar. + \functionparens + \code{#1}% + \interlinepenalty=10000 + \advance\rightskip by 0pt plus 1fil + \endgraf\penalty 10000\vskip -\parskip\penalty 10000% + } + + % Do complete processing of one @defun or @defunx line already parsed. + + % @deffn Command forward-char nchars + + \def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader} + + \def\deffnheader #1#2#3{\doind {fn}{\code{#2}}% + \begingroup\defname {#2}{#1}\defunargs{#3}\endgroup % + \catcode 61=\other % Turn off change made in \defparsebody + } + + % @defun == @deffn Function + + \def\defun{\defparsebody\Edefun\defunx\defunheader} + + \def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index + \begingroup\defname {#1}{Function}% + \defunargs {#2}\endgroup % + \catcode 61=\other % Turn off change made in \defparsebody + } + + % @deftypefun int foobar (int @var{foo}, float @var{bar}) + + \def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader} + + % #1 is the data type. #2 is the name and args. + \def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax} + % #1 is the data type, #2 the name, #3 the args. + \def\deftypefunheaderx #1#2 #3\relax{% + \doind {fn}{\code{#2}}% Make entry in function index + \begingroup\defname {\code{#1} #2}{Function}% + \deftypefunargs {#3}\endgroup % + \catcode 61=\other % Turn off change made in \defparsebody + } + + % @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar}) + + \def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader} + + % #1 is the classification. #2 is the data type. #3 is the name and args. + \def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax} + % #1 is the classification, #2 the data type, #3 the name, #4 the args. + \def\deftypefnheaderx #1#2#3 #4\relax{% + \doind {fn}{\code{#3}}% Make entry in function index + \begingroup + \normalparens % notably, turn off `&' magic, which prevents + % at least some C++ text from working + \defname {\code{#2} #3}{#1}% + \deftypefunargs {#4}\endgroup % + \catcode 61=\other % Turn off change made in \defparsebody + } + + % @defmac == @deffn Macro + + \def\defmac{\defparsebody\Edefmac\defmacx\defmacheader} + + \def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index + \begingroup\defname {#1}{Macro}% + \defunargs {#2}\endgroup % + \catcode 61=\other % Turn off change made in \defparsebody + } + + % @defspec == @deffn Special Form + + \def\defspec{\defparsebody\Edefspec\defspecx\defspecheader} + + \def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index + \begingroup\defname {#1}{Special Form}% + \defunargs {#2}\endgroup % + \catcode 61=\other % Turn off change made in \defparsebody + } + + % This definition is run if you use @defunx + % anywhere other than immediately after a @defun or @defunx. + + \def\deffnx #1 {\errmessage{@deffnx in invalid context}} + \def\defunx #1 {\errmessage{@defunx in invalid context}} + \def\defmacx #1 {\errmessage{@defmacx in invalid context}} + \def\defspecx #1 {\errmessage{@defspecx in invalid context}} + \def\deftypefnx #1 {\errmessage{@deftypefnx in invalid context}} + \def\deftypeunx #1 {\errmessage{@deftypeunx in invalid context}} + + % @defmethod, and so on + + % @defop {Funny Method} foo-class frobnicate argument + + \def\defop #1 {\def\defoptype{#1}% + \defopparsebody\Edefop\defopx\defopheader\defoptype} + + \def\defopheader #1#2#3{% + \dosubind {fn}{\code{#2}}{on #1}% Make entry in function index + \begingroup\defname {#2}{\defoptype{} on #1}% + \defunargs {#3}\endgroup % + } + + % @defmethod == @defop Method + + \def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader} + + \def\defmethodheader #1#2#3{% + \dosubind {fn}{\code{#2}}{on #1}% entry in function index + \begingroup\defname {#2}{Method on #1}% + \defunargs {#3}\endgroup % + } + + % @defcv {Class Option} foo-class foo-flag + + \def\defcv #1 {\def\defcvtype{#1}% + \defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype} + + \def\defcvarheader #1#2#3{% + \dosubind {vr}{\code{#2}}{of #1}% Make entry in var index + \begingroup\defname {#2}{\defcvtype{} of #1}% + \defvarargs {#3}\endgroup % + } + + % @defivar == @defcv {Instance Variable} + + \def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader} + + \def\defivarheader #1#2#3{% + \dosubind {vr}{\code{#2}}{of #1}% Make entry in var index + \begingroup\defname {#2}{Instance Variable of #1}% + \defvarargs {#3}\endgroup % + } + + % These definitions are run if you use @defmethodx, etc., + % anywhere other than immediately after a @defmethod, etc. + + \def\defopx #1 {\errmessage{@defopx in invalid context}} + \def\defmethodx #1 {\errmessage{@defmethodx in invalid context}} + \def\defcvx #1 {\errmessage{@defcvx in invalid context}} + \def\defivarx #1 {\errmessage{@defivarx in invalid context}} + + % Now @defvar + + % First, define the processing that is wanted for arguments of @defvar. + % This is actually simple: just print them in roman. + % This must expand the args and terminate the paragraph they make up + \def\defvarargs #1{\normalparens #1% + \interlinepenalty=10000 + \endgraf\penalty 10000\vskip -\parskip\penalty 10000} + + % @defvr Counter foo-count + + \def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader} + + \def\defvrheader #1#2#3{\doind {vr}{\code{#2}}% + \begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup} + + % @defvar == @defvr Variable + + \def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader} + + \def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index + \begingroup\defname {#1}{Variable}% + \defvarargs {#2}\endgroup % + } + + % @defopt == @defvr {User Option} + + \def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader} + + \def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index + \begingroup\defname {#1}{User Option}% + \defvarargs {#2}\endgroup % + } + + % @deftypevar int foobar + + \def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader} + + % #1 is the data type. #2 is the name. + \def\deftypevarheader #1#2{% + \doind {vr}{\code{#2}}% Make entry in variables index + \begingroup\defname {\code{#1} #2}{Variable}% + \interlinepenalty=10000 + \endgraf\penalty 10000\vskip -\parskip\penalty 10000 + \endgroup} + + % @deftypevr {Global Flag} int enable + + \def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader} + + \def\deftypevrheader #1#2#3{\doind {vr}{\code{#3}}% + \begingroup\defname {\code{#2} #3}{#1} + \interlinepenalty=10000 + \endgraf\penalty 10000\vskip -\parskip\penalty 10000 + \endgroup} + + % This definition is run if you use @defvarx + % anywhere other than immediately after a @defvar or @defvarx. + + \def\defvrx #1 {\errmessage{@defvrx in invalid context}} + \def\defvarx #1 {\errmessage{@defvarx in invalid context}} + \def\defoptx #1 {\errmessage{@defoptx in invalid context}} + \def\deftypevarx #1 {\errmessage{@deftypevarx in invalid context}} + \def\deftypevrx #1 {\errmessage{@deftypevrx in invalid context}} + + % Now define @deftp + % Args are printed in bold, a slight difference from @defvar. + + \def\deftpargs #1{\bf \defvarargs{#1}} + + % @deftp Class window height width ... + + \def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader} + + \def\deftpheader #1#2#3{\doind {tp}{\code{#2}}% + \begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup} + + % This definition is run if you use @deftpx, etc + % anywhere other than immediately after a @deftp, etc. + + \def\deftpx #1 {\errmessage{@deftpx in invalid context}} + + \message{cross reference,} + % Define cross-reference macros + \newwrite \auxfile + + \newif\ifhavexrefs % True if xref values are known. + \newif\ifwarnedxrefs % True if we warned once that they aren't known. + + % \setref{foo} defines a cross-reference point named foo. + + \def\setref#1{% + \dosetq{#1-title}{Ytitle}% + \dosetq{#1-pg}{Ypagenumber}% + \dosetq{#1-snt}{Ysectionnumberandtype}} + + \def\unnumbsetref#1{% + \dosetq{#1-title}{Ytitle}% + \dosetq{#1-pg}{Ypagenumber}% + \dosetq{#1-snt}{Ynothing}} + + \def\appendixsetref#1{% + \dosetq{#1-title}{Ytitle}% + \dosetq{#1-pg}{Ypagenumber}% + \dosetq{#1-snt}{Yappendixletterandtype}} + + % \xref, \pxref, and \ref generate cross-references to specified points. + % For \xrefX, #1 is the node name, #2 the name of the Info + % cross-reference, #3 the printed node name, #4 the name of the Info + % file, #5 the name of the printed manual. All but the node name can be + % omitted. + % + \def\pxref#1{see \xrefX[#1,,,,,,,]} + \def\xref#1{See \xrefX[#1,,,,,,,]} + \def\ref#1{\xrefX[#1,,,,,,,]} + \def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup% + \def\printedmanual{\ignorespaces #5}% + \def\printednodename{\ignorespaces #3}% + % + \setbox1=\hbox{\printedmanual}% + \setbox0=\hbox{\printednodename}% + \ifdim \wd0=0pt% + % No printed node name was explicitly given. + \ifx SETxref-automatic-section-title % + % This line should make the actual chapter or section title appear inside + % the square brackets. Use the real section title if we have it. + \ifdim \wd1>0pt% + % It is in another manual, so we don't have it. + \def\printednodename{\ignorespaces #1} \else% + % We know the real title if we have the xref values. + \ifhavexrefs \def\printednodename{\refx{#1-title}}% + % Otherwise just copy the Info node name. + \else \def\printednodename{\ignorespaces #1} \fi% + \fi\def\printednodename{#1-title}% + \else% This line just uses the node name. + \def\printednodename{\ignorespaces #1}% + \fi% ends \ifx SETxref-automatic-section-title + \fi% ends \ifdim \wd0 + % + % + % If we use \unhbox0 and \unhbox1 to print the node names, TeX does + % not insert empty discretionaries after hyphens, which means that it + % will not find a line break at a hyphen in a node names. Since some + % manuals are best written with fairly long node names, containing + % hyphens, this is a loss. Therefore, we simply give the text of + % the node name again, so it is as if TeX is seeing it for the first + % time. + \ifdim \wd1>0pt + section ``\printednodename'' in \cite{\printedmanual}% + \else% + \turnoffactive% + \refx{#1-snt}{} [\printednodename], page\tie\refx{#1-pg}{}% + \fi + \endgroup} + + % \dosetq is the interface for calls from other macros + + % Use \turnoffactive so that punctuation chars such as underscore + % work in node names. + \def\dosetq #1#2{{\let\folio=0 \turnoffactive% + \edef\next{\write\auxfile{\internalsetq {#1}{#2}}}% + \next}} + + % \internalsetq {foo}{page} expands into + % CHARACTERS 'xrdef {foo}{...expansion of \Ypage...} + % When the aux file is read, ' is the escape character + + \def\internalsetq #1#2{'xrdef {#1}{\csname #2\endcsname}} + + % Things to be expanded by \internalsetq + + \def\Ypagenumber{\folio} + + \def\Ytitle{\thissection} + + \def\Ynothing{} + + \def\Ysectionnumberandtype{% + \ifnum\secno=0 Chapter\xreftie\the\chapno % + \else \ifnum \subsecno=0 Section\xreftie\the\chapno.\the\secno % + \else \ifnum \subsubsecno=0 % + Section\xreftie\the\chapno.\the\secno.\the\subsecno % + \else % + Section\xreftie\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno % + \fi \fi \fi } + + \def\Yappendixletterandtype{% + \ifnum\secno=0 Appendix\xreftie'char\the\appendixno{}% + \else \ifnum \subsecno=0 Section\xreftie'char\the\appendixno.\the\secno % + \else \ifnum \subsubsecno=0 % + Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno % + \else % + Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % + \fi \fi \fi } + + \gdef\xreftie{'tie} + + % Use TeX 3.0's \inputlineno to get the line number, for better error + % messages, but if we're using an old version of TeX, don't do anything. + % + \ifx\inputlineno\thisisundefined + \let\linenumber = \empty % Non-3.0. + \else + \def\linenumber{\the\inputlineno:\space} + \fi + + % Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. + % If its value is nonempty, SUFFIX is output afterward. + + \def\refx#1#2{% + \expandafter\ifx\csname X#1\endcsname\relax + % If not defined, say something at least. + $\langle$un\-de\-fined$\rangle$% + \ifhavexrefs + \message{\linenumber Undefined cross reference `#1'.}% + \else + \ifwarnedxrefs\else + \global\warnedxrefstrue + \message{Cross reference values unknown; you must run TeX again.}% + \fi + \fi + \else + % It's defined, so just use it. + \csname X#1\endcsname + \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\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 + % 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 `\\=\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} + + + % Footnotes. + + \newcount \footnoteno + + % 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. + \def\supereject{\par\penalty -20000\footnoteno =0 } + + % @footnotestyle is meaningful for info output only.. + \let\footnotestyle=\comment + + \let\ptexfootnote=\footnote + + {\catcode `\@=11 + % + % Auto-number footnotes. Otherwise like plain. + \gdef\footnote{% + \global\advance\footnoteno by \@ne + \edef\thisfootno{$^{\the\footnoteno}$}% + % + % In case the footnote comes at the end of a sentence, preserve the + % extra spacing after we do the footnote number. + \let\@sf\empty + \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi + % + % Remove inadvertent blank space before typesetting the footnote number. + \unskip + \thisfootno\@sf + \footnotezzz + }% + + % 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. + % + \long\gdef\footnotezzz#1{\insert\footins{% + % 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. + \interlinepenalty\interfootnotelinepenalty + \splittopskip\ht\strutbox % top baseline for broken footnotes + \splitmaxdepth\dp\strutbox + \floatingpenalty\@MM + \leftskip\z@skip + \rightskip\z@skip + \spaceskip\z@skip + \xspaceskip\z@skip + \parindent\defaultparindent + % + % Hang the footnote text off the number. + \hang + \textindent{\thisfootno}% + % + % Don't crash into the line above the footnote text. Since this + % expands into a box, it must come within the paragraph, lest it + % provide a place where TeX can split the footnote. + \footstrut + #1\strut}% + } + + }%end \catcode `\@=11 + + % Set the baselineskip to #1, and the lineskip and strut size + % correspondingly. There is no deep meaning behind these magic numbers + % used as factors; they just match (closely enough) what Knuth defined. + % + \def\lineskipfactor{.08333} + \def\strutheightpercent{.70833} + \def\strutdepthpercent {.29167} + % + \def\setleading#1{% + \normalbaselineskip = #1\relax + \normallineskip = \lineskipfactor\normalbaselineskip + \normalbaselines + \setbox\strutbox =\hbox{% + \vrule width0pt height\strutheightpercent\baselineskip + depth \strutdepthpercent \baselineskip + }% + } + + % @| inserts a changebar to the left of the current line. It should + % surround any changed text. This approach does *not* work if the + % change spans more than two lines of output. To handle that, we would + % have adopt a much more difficult approach (putting marks into the main + % vertical list for the beginning and end of each change). + % + \def\|{% + % \vadjust can only be used in horizontal mode. + \leavevmode + % + % Append this vertical mode material after the current line in the output. + \vadjust{% + % We want to insert a rule with the height and depth of the current + % leading; that is exactly what \strutbox is supposed to record. + \vskip-\baselineskip + % + % \vadjust-items are inserted at the left edge of the type. So + % the \llap here moves out into the left-hand margin. + \llap{% + % + % For a thicker or thinner bar, change the `1pt'. + \vrule height\baselineskip width1pt + % + % This is the space between the bar and the text. + \hskip 12pt + }% + }% + } + + % For a final copy, take out the rectangles + % that mark overfull boxes (in case you have decided + % that the text looks ok even though it passes the margin). + % + \def\finalout{\overfullrule=0pt} + + + % End of control word definitions. + + \message{and turning on texinfo input format.} + + \def\openindices{% + \newindex{cp}% + \newcodeindex{fn}% + \newcodeindex{vr}% + \newcodeindex{tp}% + \newcodeindex{ky}% + \newcodeindex{pg}% + } + + % Set some numeric style parameters, for 8.5 x 11 format. + + %\hsize = 6.5in + \newdimen\defaultparindent \defaultparindent = 15pt + \parindent = \defaultparindent + \parskip 18pt plus 1pt + \setleading{15pt} + \advance\topskip by 1.2cm + + % Prevent underfull vbox error messages. + \vbadness=10000 + + % Following George Bush, just get rid of widows and orphans. + \widowpenalty=10000 + \clubpenalty=10000 + + % Use TeX 3.0's \emergencystretch to help line breaking, but if we're + % using an old version of TeX, don't do anything. We want the amount of + % stretch added to depend on the line length, hence the dependence on + % \hsize. This makes it come to about 9pt for the 8.5x11 format. + % + \ifx\emergencystretch\thisisundefined + % Allow us to assign to \emergencystretch anyway. + \def\emergencystretch{\dimen0}% + \else + \emergencystretch = \hsize + \divide\emergencystretch by 45 + \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\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. + \def\afourpaper{ + \global\tolerance=700 + \global\hfuzz=1pt + \setleading{12pt} + \global\parskip 15pt plus 1pt + + \global\vsize= 53\baselineskip + \advance\vsize by \topskip + %\global\hsize= 5.85in % A4 wide 10pt + \global\hsize= 6.5in + \global\outerhsize=\hsize + \global\advance\outerhsize by 0.5in + \global\outervsize=\vsize + \global\advance\outervsize by 0.6in + + \global\pagewidth=\hsize + \global\pageheight=\vsize + } + + % Define macros to output various characters with catcode for normal text. + \catcode`\"=\other + \catcode`\~=\other + \catcode`\^=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\+=\other + \def\normaldoublequote{"} + \def\normaltilde{~} + \def\normalcaret{^} + \def\normalunderscore{_} + \def\normalverticalbar{|} + \def\normalless{<} + \def\normalgreater{>} + \def\normalplus{+} + + % This macro is used to make a character print one way in ttfont + % where it can probably just be output, and another way in other fonts, + % where something hairier probably needs to be done. + % + % #1 is what to print if we are indeed using \tt; #2 is what to print + % otherwise. 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, we can check that font parameter. + % + \def\ifusingtt#1#2{\ifdim \fontdimen3\the\font=0pt #1\else #2\fi} + + % Turn off all special characters except @ + % (and those which the user can use as if they were ordinary). + % Most of these we simply print from the \tt font, but for some, we can + % use math or other variants that look better in normal text. + + \catcode`\"=\active + \def\activedoublequote{{\tt \char '042}} + \let"=\activedoublequote + \catcode`\~=\active + \def~{{\tt \char '176}} + \chardef\hat=`\^ + \catcode`\^=\active + \def^{{\tt \hat}} + + \catcode`\_=\active + \def_{\ifusingtt\normalunderscore\_} + % Subroutine for the previous macro. + \def\_{\lvvmode \kern.06em \vbox{\hrule width.3em height.1ex}} + + % \lvvmode is equivalent in function to \leavevmode. + % Using \leavevmode runs into trouble when written out to + % an index file due to the expansion of \leavevmode into ``\unhbox + % \voidb@x'' ---which looks to TeX like ``\unhbox \voidb\x'' due to our + % magic tricks with @. + \def\lvvmode{\vbox to 0pt{}} + + \catcode`\|=\active + \def|{{\tt \char '174}} + \chardef \less=`\< + \catcode`\<=\active + \def<{{\tt \less}} + \chardef \gtr=`\> + \catcode`\>=\active + \def>{{\tt \gtr}} + \catcode`\+=\active + \def+{{\tt \char 43}} + %\catcode 27=\active + %\def^^[{$\diamondsuit$} + + % Used sometimes to turn off (effectively) the active characters + % even after parsing them. + \def\turnoffactive{\let"=\normaldoublequote + \let~=\normaltilde + \let^=\normalcaret + \let_=\normalunderscore + \let|=\normalverticalbar + \let<=\normalless + \let>=\normalgreater + \let+=\normalplus} + + % Set up an active definition for =, but don't enable it most of the time. + {\catcode`\==\active + \global\def={{\tt \char 61}}} + + \catcode`\@=0 + + % \rawbackslashxx output one backslash character in current font + \global\chardef\rawbackslashxx=`\\ + %{\catcode`\\=\other + %@gdef@rawbackslashxx{\}} + + % \rawbackslash redefines \ as input to do \rawbackslashxx. + {\catcode`\\=\active + @gdef@rawbackslash{@let\=@rawbackslashxx }} + + % \normalbackslash outputs one backslash in fixed width font. + \def\normalbackslash{{\tt\rawbackslashxx}} + + % Say @foo, not \foo, in error messages. + \escapechar=`\@ + + % \catcode 17=0 % Define control-q + \catcode`\\=\active + + % If a .fmt file is being used, we don't want the `\input texinfo' to show up. + % That is what \eatinput is for; after that, the `\' should revert to printing + % a backslash. + % + @gdef@eatinput input texinfo{@fixbackslash} + @global@let\ = @eatinput + + % On the other hand, perhaps the file did not have a `\input texinfo'. Then + % the first `\{ in the file would cause an error. This macro tries to fix + % that, assuming it is called before the first `\' could plausibly occur. + % + @gdef@fixbackslash{@ifx\@eatinput @let\ = @normalbackslash @fi} + + %% These look ok in all fonts, so just make them not special. The @rm below + %% makes sure that the current font starts out as the newly loaded cmr10 + @catcode`@$=@other @catcode`@%=@other @catcode`@&=@other @catcode`@#=@other + + @textfonts + @rm + + @c Local variables: + @c page-delimiter: "^\\\\message" + @c End: diff -crN gawk-2.15.2/test/Makefile gawk-2.15.3/test/Makefile *** gawk-2.15.2/test/Makefile Wed May 19 12:56:40 1993 --- gawk-2.15.3/test/Makefile Tue Nov 2 23:49:26 1993 *************** *** 6,12 **** getline fstabplus compare arrayref rs fsrs rand \ fsbs negexp asgext anchgsub splitargv awkpath nfset reparse ! gawk.extensions: fieldwdth ignrcase posix manyfiles igncfs extra: regtest inftest --- 6,13 ---- getline fstabplus compare arrayref rs fsrs rand \ fsbs negexp asgext anchgsub splitargv awkpath nfset reparse ! gawk.extensions: fieldwdth ignrcase posix manyfiles igncfs argtest \ ! badargtest extra: regtest inftest *************** *** 27,34 **** messages:: @../gawk -f messages.awk >out2 2>out3 ! cmp out1.good out1 && cmp out2.good out2 && cmp out3.good out3 && \ ! rm -f out1 out2 out3 argarray:: @TEST=test ../gawk -f argarray.awk >tmp --- 28,34 ---- messages:: @../gawk -f messages.awk >out2 2>out3 ! cmp out1.good out1 && cmp out2.good out2 && cmp out3.good out3 && rm -f out1 out2 out3 argarray:: @TEST=test ../gawk -f argarray.awk >tmp *************** *** 51,61 **** cmp longwrds.good tmp && rm -f tmp fieldwdth:: ! @echo '123456789' | ../gawk -v FIELDWIDTHS="2 3 4" '{print $$2}' >tmp cmp fieldwdth.good tmp && rm -f tmp ignrcase:: ! @echo xYz | ../gawk -v IGNORECASE=1 '{sub(/y/, ""); print}' >tmp cmp ignrcase.good tmp && rm -f tmp regtest:: --- 51,61 ---- cmp longwrds.good tmp && rm -f tmp fieldwdth:: ! @echo '123456789' | ../gawk -v FIELDWIDTHS="2 3 4" '{ print $$2}' >tmp cmp fieldwdth.good tmp && rm -f tmp ignrcase:: ! @echo xYz | ../gawk -v IGNORECASE=1 '{ sub(/y/, ""); print}' >tmp cmp ignrcase.good tmp && rm -f tmp regtest:: *************** *** 72,78 **** @mkdir junk @../gawk 'BEGIN { for (i = 1; i <= 100; i++) print i, i}' >tmp @../gawk -f manyfiles.awk tmp tmp ! @echo -n "This number better be 1 ->" @wc -l junk/* | ../gawk '$$1 != 2' | wc -l @rm -rf junk tmp --- 72,78 ---- @mkdir junk @../gawk 'BEGIN { for (i = 1; i <= 100; i++) print i, i}' >tmp @../gawk -f manyfiles.awk tmp tmp ! @echo "This number better be 1 ->" | tr -d '\012' @wc -l junk/* | ../gawk '$$1 != 2' | wc -l @rm -rf junk tmp *************** *** 85,91 **** cmp arrayref.good tmp && rm -f tmp rs:: ! @../gawk -v RS="" '{print $$1, $$2}' rs.data >tmp cmp rs.good tmp && rm -f tmp fsbs:: --- 85,91 ---- cmp arrayref.good tmp && rm -f tmp rs:: ! @../gawk -v RS="" '{ print $$1, $$2}' rs.data >tmp cmp rs.good tmp && rm -f tmp fsbs:: *************** *** 106,112 **** @../gawk -f rand.awk negexp:: ! @../gawk 'BEGIN {a = -2; print 10^a }' >tmp cmp negexp.good tmp && rm -f tmp asgext:: --- 106,112 ---- @../gawk -f rand.awk negexp:: ! @../gawk 'BEGIN { a = -2; print 10^a }' >tmp cmp negexp.good tmp && rm -f tmp asgext:: *************** *** 132,134 **** --- 132,145 ---- reparse:: @../gawk -f reparse.awk reparse.in >tmp cmp reparse.good tmp && rm -f tmp + + argtest:: + @../gawk -f argtest.awk -x -y abc >tmp + cmp argtest.good tmp && rm -f tmp + + badargtest:: + @-../gawk -f > tmp 2>&1 + cmp badargs.good tmp && rm -f tmp + + clean: + rm -f tmp diff -crN gawk-2.15.2/test/argarray.awk gawk-2.15.3/test/argarray.awk *** gawk-2.15.2/test/argarray.awk Wed May 19 12:56:41 1993 --- gawk-2.15.3/test/argarray.awk Tue Nov 2 06:16:07 1993 *************** *** 6,11 **** for (x = 0; x < ARGC; x++) print "\t", ARGV[x] print "Environment variable TEST=" ENVIRON["TEST"] ! print "and the current input file is called", FILENAME print "but this would change if we would have something to process" } --- 6,11 ---- for (x = 0; x < ARGC; x++) print "\t", ARGV[x] print "Environment variable TEST=" ENVIRON["TEST"] ! print "and the current input file is called \"" FILENAME "\"" print "but this would change if we would have something to process" } diff -crN gawk-2.15.2/test/argarray.good gawk-2.15.3/test/argarray.good *** gawk-2.15.2/test/argarray.good Wed May 19 12:56:41 1993 --- gawk-2.15.3/test/argarray.good Tue Nov 2 06:16:08 1993 *************** *** 2,6 **** which is gawk Environment variable TEST=test ! and the current input file is called - but this would change if we would have something to process --- 2,6 ---- which is gawk Environment variable TEST=test ! and the current input file is called "" but this would change if we would have something to process diff -crN gawk-2.15.2/test/argtest.awk gawk-2.15.3/test/argtest.awk *** gawk-2.15.2/test/argtest.awk Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/test/argtest.awk Tue Nov 2 06:16:08 1993 *************** *** 0 **** --- 1,4 ---- + BEGIN { + for (i = 0; i < ARGC; i++) + printf("ARGV[%d] = %s\n", i, ARGV[i]) + } diff -crN gawk-2.15.2/test/argtest.good gawk-2.15.3/test/argtest.good *** gawk-2.15.2/test/argtest.good Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/test/argtest.good Tue Nov 2 06:16:09 1993 *************** *** 0 **** --- 1,4 ---- + ARGV[0] = gawk + ARGV[1] = -x + ARGV[2] = -y + ARGV[3] = abc diff -crN gawk-2.15.2/test/badargs.good gawk-2.15.3/test/badargs.good *** gawk-2.15.2/test/badargs.good Wed Dec 31 19:00:00 1969 --- gawk-2.15.3/test/badargs.good Sun Nov 7 11:25:11 1993 *************** *** 0 **** --- 1,17 ---- + gawk: option requires an argument -- f + Gnu Awk (gawk) 2.15, patchlevel 3 + Usage: gawk [POSIX or GNU style options] -f progfile [--] file ... + gawk [POSIX or GNU style options] [--] 'program' file ... + POSIX options: GNU long options: + -f progfile --file=progfile + -F fs --field-separator=fs + -v var=val --assign=var=val + -W compat --compat + -W copyleft --copyleft + -W copyright --copyright + -W help --help + -W lint --lint + -W posix --posix + -W source=program-text --source=program-text + -W usage --usage + -W version --version diff -crN gawk-2.15.2/vms/descrip.mms gawk-2.15.3/vms/descrip.mms *** gawk-2.15.2/vms/descrip.mms Mon Nov 9 13:49:56 1992 --- gawk-2.15.3/vms/descrip.mms Thu Nov 4 06:25:52 1993 *************** *** 40,47 **** # 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" $(CCFLAGS) ! #CFLAGS = /Include=([],$(VMSDIR))/Object=[]/Define="GAWK" $(CCFLAGS) # uncomment this for GNU C #CC = gcc --- 40,47 ---- # 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 *************** *** 85,91 **** # object files AWKOBJS = main.obj,eval.obj,builtin.obj,msg.obj,iop.obj,io.obj,\ ! field.obj,array.obj,node.obj,version.obj,missing.obj,re.obj,getopt.obj ALLOBJS = $(AWKOBJS),awktab.obj --- 85,92 ---- # object files AWKOBJS = main.obj,eval.obj,builtin.obj,msg.obj,iop.obj,io.obj,\ ! field.obj,array.obj,node.obj,version.obj,missing.obj,re.obj,\ ! getopt.obj,getopt1.obj ALLOBJS = $(AWKOBJS),awktab.obj *************** *** 107,114 **** $(VMSDIR)gawk.hlp # Release of gawk ! REL=2.14 ! PATCHLVL=0 # dummy target to allow building "gawk" in addition to explicit "gawk.exe" gawk : gawk.exe --- 108,115 ---- $(VMSDIR)gawk.hlp # Release of gawk ! REL=2.15 ! PATCHLVL=3 # dummy target to allow building "gawk" in addition to explicit "gawk.exe" gawk : gawk.exe diff -crN gawk-2.15.2/vms/vms_gawk.c gawk-2.15.3/vms/vms_gawk.c *** gawk-2.15.2/vms/vms_gawk.c Tue Aug 4 21:25:35 1992 --- gawk-2.15.3/vms/vms_gawk.c Thu Oct 21 22:51:42 1993 *************** *** 49,57 **** #define ARG_SIZ 250 union arg_w_prefix { /* structure used to simplify prepending of "-" */ ! char value[3+ARG_SIZ+1]; struct { ! char prefix[3]; /* for "-? " */ char buf[ARG_SIZ]; char suffix[1]; /* room for '\0' */ } arg; --- 49,57 ---- #define ARG_SIZ 250 union arg_w_prefix { /* structure used to simplify prepending of "-" */ ! char value[2+ARG_SIZ+1]; struct { ! char prefix[2]; /* for "-?" */ char buf[ARG_SIZ]; char suffix[1]; /* room for '\0' */ } arg; *************** *** 115,123 **** *misc_argp++ = 'C'; if (Present("VERSION")) /* /version -> -V */ *misc_argp++ = 'V'; ! #else /* gawk 2.12 */ W_cnt = 0, buf.arg.buf[0] = '\0'; ! strncpy(buf.arg.prefix, "-W ", 3); chk_option("LINT","lint"); chk_option("POSIX","posix"); chk_option("STRICT","compat"); --- 115,123 ---- *misc_argp++ = 'C'; if (Present("VERSION")) /* /version -> -V */ *misc_argp++ = 'V'; ! #else /* gawk 2.12 and later */ W_cnt = 0, buf.arg.buf[0] = '\0'; ! strncpy(buf.arg.prefix, "-W", 2); chk_option("LINT","lint"); chk_option("POSIX","posix"); chk_option("STRICT","compat"); *************** *** 142,158 **** v_add_arg(++argc, misc_args); /* store it/them */ if (Present("FIELD_SEP")) { /* field separator */ ! strncpy(buf.arg.prefix, "-F ", 3); if (Get_Value("FIELD_SEP", buf.arg.buf, sizeof buf.arg.buf)) v_add_arg(++argc, strdup(buf.value)); } if (Present("VARIABLES")) { /* variables to init prior to BEGIN */ ! strncpy(buf.arg.prefix, "-v ", 3); while (Get_Value("VARIABLES", buf.arg.buf, sizeof buf.arg.buf)) v_add_arg(++argc, strdup(buf.value)); } if (Present("PROGFILE")) { /* program files, /input=file -> -f file */ ! strncpy(buf.arg.prefix, "-f ", 3); while (Get_Value("PROGFILE", buf.arg.buf, sizeof buf.arg.buf)) v_add_arg(++argc, strdup(buf.value)); v_add_arg(++argc, "--"); --- 142,158 ---- v_add_arg(++argc, misc_args); /* store it/them */ if (Present("FIELD_SEP")) { /* field separator */ ! strncpy(buf.arg.prefix, "-F", 2); if (Get_Value("FIELD_SEP", buf.arg.buf, sizeof buf.arg.buf)) v_add_arg(++argc, strdup(buf.value)); } if (Present("VARIABLES")) { /* variables to init prior to BEGIN */ ! strncpy(buf.arg.prefix, "-v", 2); while (Get_Value("VARIABLES", buf.arg.buf, sizeof buf.arg.buf)) v_add_arg(++argc, strdup(buf.value)); } if (Present("PROGFILE")) { /* program files, /input=file -> -f file */ ! strncpy(buf.arg.prefix, "-f", 2); while (Get_Value("PROGFILE", buf.arg.buf, sizeof buf.arg.buf)) v_add_arg(++argc, strdup(buf.value)); v_add_arg(++argc, "--"); *************** *** 167,173 **** v_add_arg(++argc, strdup(buf.value)); if (Present("OUTPUT")) { /* let other parser treat this as 'stdout' */ ! strncpy(buf.arg.prefix, ">$ ", 3); if (Get_Value("OUTPUT", buf.arg.buf, sizeof buf.arg.buf)) v_add_arg(++argc, strdup(buf.value)); } --- 167,173 ---- v_add_arg(++argc, strdup(buf.value)); if (Present("OUTPUT")) { /* let other parser treat this as 'stdout' */ ! strncpy(buf.arg.prefix, ">$", 2); if (Get_Value("OUTPUT", buf.arg.buf, sizeof buf.arg.buf)) v_add_arg(++argc, strdup(buf.value)); } diff -crN gawk-2.15.2/vms/vms_misc.c gawk-2.15.3/vms/vms_misc.c *** gawk-2.15.2/vms/vms_misc.c Tue Apr 27 21:10:21 1993 --- gawk-2.15.3/vms/vms_misc.c Thu Nov 4 06:25:51 1993 *************** *** 107,126 **** #ifdef open # undef open #endif /* vms_open() - open a file, possibly creating it */ int vms_open( const char *name, int mode, ... ) { - extern int creat P((const char *,int,...)); - extern int open P((const char *,int,unsigned,...)); - if (mode == (O_WRONLY|O_CREAT|O_TRUNC)) return creat(name, 0, "shr=nil", "mbc=24"); else { struct stat stb; const char *mbc, *shr = "shr=get"; ! if (stat(name, &stb) < 0) { /* assume DECnet */ mbc = "mbc=8"; } else { /* ordinary file; allow full sharing iff record format */ mbc = "mbc=12"; --- 107,126 ---- #ifdef open # undef open #endif + extern int creat P((const char *,int,...)); + extern int open P((const char *,int,unsigned,...)); + /* vms_open() - open a file, possibly creating it */ int vms_open( const char *name, int mode, ... ) { if (mode == (O_WRONLY|O_CREAT|O_TRUNC)) return creat(name, 0, "shr=nil", "mbc=24"); else { struct stat stb; const char *mbc, *shr = "shr=get"; ! if (stat((char *)name, &stb) < 0) { /* assume DECnet */ mbc = "mbc=8"; } else { /* ordinary file; allow full sharing iff record format */ mbc = "mbc=12"; *************** *** 140,148 **** FILE *file = NULL; if (STREQ(name, "/dev/null")) ! return open("NL:", mode); /* "/dev/null" => "NL:" */ else if (STREQ(name, "/dev/tty")) ! return open("TT:", mode); /* "/dev/tty" => "TT:" */ else if (strncasecmp(name, "SYS$", 4) == 0) { name += 4; /* skip "SYS$" */ if (strncasecmp(name, "INPUT", 5) == 0 && (mode & O_WRONLY) == 0) --- 140,148 ---- FILE *file = NULL; if (STREQ(name, "/dev/null")) ! return open("NL:", mode, 0); /* "/dev/null" => "NL:" */ else if (STREQ(name, "/dev/tty")) ! return open("TT:", mode, 0); /* "/dev/tty" => "TT:" */ else if (strncasecmp(name, "SYS$", 4) == 0) { name += 4; /* skip "SYS$" */ if (strncasecmp(name, "INPUT", 5) == 0 && (mode & O_WRONLY) == 0) *************** *** 168,173 **** --- 168,181 ---- void tzset() { return; + } + + /* getpgrp() -- there's no such thing as process group under VMS; + * job tree might be close enough to be useful though. + */ + int getpgrp() + { + return 0; } /*----------------------------------------------------------------------*/ diff -crN gawk-2.15.2/vms/vmsbuild.com gawk-2.15.3/vms/vmsbuild.com *** gawk-2.15.2/vms/vmsbuild.com Fri Oct 23 15:26:14 1992 --- gawk-2.15.3/vms/vmsbuild.com Thu Nov 4 06:25:52 1993 *************** *** 2,10 **** $! revised, Mar'90 $! gawk 2.13 revised, Jun'91 $! gawk 2.14 revised, Sep'92 $! ! $ REL = "2.14" !release version number ! $ PATCHLVL = "0" $! $! [ remove "/optimize=noinline" for VAX C V2.x or DEC C ] $! [ add "/standard=VAXC" for DEC C and "/g_float" for Alpha ] --- 2,11 ---- $! revised, Mar'90 $! gawk 2.13 revised, Jun'91 $! gawk 2.14 revised, Sep'92 + $! gawk 2.15 revised, Oct'93 $! ! $ REL = "2.15" !release version number ! $ PATCHLVL = "3" $! $! [ remove "/optimize=noinline" for VAX C V2.x or DEC C ] $! [ add "/standard=VAXC" for DEC C and "/g_float" for Alpha ] *************** *** 12,18 **** $ 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""" $ libs = "sys$share:vaxcrtl.exe/Shareable" $ $! uncomment for DEC C --- 13,19 ---- $ 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 *************** *** 23,29 **** $ ! define c$library [],[.vms] $! $! uncomment next two lines for GNU C ! $ ! cc := gcc/Include=([],[.vms])/Define="""GAWK""" !use GNU C rather than VAX C $ ! libs = "gnu_cc:[000000]gcclib.olb/Library,sys$library:vaxcrtl.olb/Library" $! $ if f$search("config.h").eqs."" then copy [.config]vms-conf.h []config.h --- 24,30 ---- $ ! define c$library [],[.vms] $! $! 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 f$search("config.h").eqs."" then copy [.config]vms-conf.h []config.h *************** *** 48,57 **** $ cc missing.c $ cc re.c $ cc getopt.c $ cc awktab.c $ cc regex.c $ cc dfa.c ! $ cc/define=("STACK_DIRECTION=(-1)","exit=vms_exit") alloca $ cc [.vms]vms_misc.c $ cc [.vms]vms_popen.c $ cc [.vms]vms_fwrite.c --- 49,59 ---- $ cc missing.c $ cc re.c $ cc getopt.c + $ cc getopt1.c $ cc awktab.c $ cc regex.c $ cc dfa.c ! $ cc/define=("STACK_DIRECTION=(-1)","exit=vms_exit") alloca.c $ cc [.vms]vms_misc.c $ cc [.vms]vms_popen.c $ cc [.vms]vms_fwrite.c *************** *** 64,70 **** ! GAWK -- Gnu AWK main.obj,eval.obj,builtin.obj,msg.obj,iop.obj,io.obj field.obj,array.obj,node.obj,version.obj,missing.obj ! re.obj,getopt.obj,awktab.obj,regex.obj,dfa.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 ** --- 66,72 ---- ! GAWK -- Gnu AWK main.obj,eval.obj,builtin.obj,msg.obj,iop.obj,io.obj field.obj,array.obj,node.obj,version.obj,missing.obj ! re.obj,getopt.obj,getopt1.obj,awktab.obj,regex.obj,dfa.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 ** EOF