Index: texk/configure
diff -u texk/configure:1.1.1.1 texk/configure:1.3
--- texk/configure:1.1.1.1	Fri Jul 18 17:00:50 1997
+++ texk/configure	Mon Sep  8 23:40:45 1997
@@ -905,10 +905,10 @@
   withval="$with_maketexmf_default"
   :
 else
-  enableval=yes
+  withval=yes
 fi
 
-if test $enableval = yes; then
+if test $withval = yes; then
   cat >> confdefs.h <<\EOF
 #define MAKE_TEX_MF_BY_DEFAULT 1
 EOF
@@ -919,10 +919,10 @@
   withval="$with_maketexpk_default"
   :
 else
-  enableval=yes
+  withval=yes
 fi
 
-if test $enableval = yes; then
+if test $withval = yes; then
   cat >> confdefs.h <<\EOF
 #define MAKE_TEX_PK_BY_DEFAULT 1
 EOF
@@ -933,10 +933,10 @@
   withval="$with_maketextfm_default"
   :
 else
-  enableval=yes
+  withval=yes
 fi
 
-if test $enableval = yes; then
+if test $withval = yes; then
   cat >> confdefs.h <<\EOF
 #define MAKE_TEX_TFM_BY_DEFAULT 1
 EOF
Index: texk/inst.sh
diff -u /dev/null texk/inst.sh:1.1
--- /dev/null	Wed Nov  5 23:19:06 1997
+++ texk/inst.sh	Tue Oct 28 18:45:31 1997
@@ -0,0 +1,6 @@
+#!/bin/sh -v
+RWPREFIX=/afs/.sipb.mit.edu/project/tex
+
+${MAKE-gmake} install prefix=$RWPREFIX INSTALL_PROGRAM="install -s"
+mv -f $RWPREFIX/bin/xdvi $RWPREFIX/bin/xdvi.real
+ln -sf ../../../arch/share/bin/xdvi $RWPREFIX/bin/xdvi
Index: texk/prepare.sh
diff -u /dev/null texk/prepare.sh:1.3
--- /dev/null	Wed Nov  5 23:19:06 1997
+++ texk/prepare.sh	Tue Oct 28 20:41:15 1997
@@ -0,0 +1,22 @@
+#!/bin/sh -v
+PREFIX=/mit/newtex
+
+# Remaking these would fail.
+find . -name '*.info' | xargs touch
+touch web2c/tie/tie.c
+
+case ${ATHENA_SYS-`fs sysname`} in
+    i386_*)
+	# Work around a configure bug.
+	LIBS="-L/usr/X11R6/lib"
+	export LIBS
+	;;
+    sun4*)
+	configflags="--x-libraries=/usr/openwin/lib"
+	;;
+esac
+
+./configure --prefix="$PREFIX" --without-maketexmf-default \
+    --without-maketexpk-default --without-maketextex-default \
+    --without-maketextfm-default --enable-dump-share \
+    --with-x --with-ps=gs $configflags
Index: texk/dviljk/configure
diff -u texk/dviljk/configure:1.1.1.1 texk/dviljk/configure:1.3
--- texk/dviljk/configure:1.1.1.1	Fri Jul 18 17:03:38 1997
+++ texk/dviljk/configure	Mon Sep  8 23:40:46 1997
@@ -1603,10 +1603,10 @@
   withval="$with_maketexmf_default"
   :
 else
-  enableval=yes
+  withval=yes
 fi
 
-if test $enableval = yes; then
+if test $withval = yes; then
   cat >> confdefs.h <<\EOF
 #define MAKE_TEX_MF_BY_DEFAULT 1
 EOF
@@ -1617,10 +1617,10 @@
   withval="$with_maketexpk_default"
   :
 else
-  enableval=yes
+  withval=yes
 fi
 
-if test $enableval = yes; then
+if test $withval = yes; then
   cat >> confdefs.h <<\EOF
 #define MAKE_TEX_PK_BY_DEFAULT 1
 EOF
@@ -1631,10 +1631,10 @@
   withval="$with_maketextfm_default"
   :
 else
-  enableval=yes
+  withval=yes
 fi
 
-if test $enableval = yes; then
+if test $withval = yes; then
   cat >> confdefs.h <<\EOF
 #define MAKE_TEX_TFM_BY_DEFAULT 1
 EOF
Index: texk/dvipsk/Makefile.in
diff -u texk/dvipsk/Makefile.in:1.1.1.1 texk/dvipsk/Makefile.in:1.2
--- texk/dvipsk/Makefile.in:1.1.1.1	Fri Jul 18 17:04:48 1997
+++ texk/dvipsk/Makefile.in	Mon Sep  8 22:09:41 1997
@@ -85,6 +85,7 @@
 #          $(INSTALL_DATA) $(srcdir)/config.ps $(psheaderdir)/config.ps;	\
 #        else true; fi
 # psfonts.map.
+	$(INSTALL_DATA) $(srcdir)/config.athena $(psheaderdir)/config.ps
 	if test ! -r $(psheaderdir)/psfonts.map 			\
 	   || grep 'original psfonts.map --' $(psheaderdir)/psfonts.map \
 	      >/dev/null; then	\
Index: texk/dvipsk/config.athena
diff -u /dev/null texk/dvipsk/config.athena:1.1
--- /dev/null	Wed Nov  5 23:19:25 1997
+++ texk/dvipsk/config.athena	Mon Sep  8 22:07:45 1997
@@ -0,0 +1,281 @@
+% Athena Dvips configuration file.
+
+% How to print, maybe with lp instead lpr, etc.
+o |lpr
+
+% Default resolution of this device, in dots per inch.
+D 600
+
+% Metafont mode.  (This is completely different from the -M command-line
+% option, which controls whether MakeTeXPK is invoked.)  Get
+% @url{ftp://ftp.tug.org/tex/modes.mf} for a list of mode names.  This mode
+% and the D number above must agree, or MakeTeXPK will get confused.
+M ljfour
+
+% Memory available. Download the three-line PostScript file:
+%   %! Hey, we're PostScript
+%   /Times-Roman findfont 30 scalefont setfont 144 432 moveto
+%   vmstatus exch sub 40 string cvs show pop showpage
+% to determine this number. (It will be the only thing printed.)
+%m 3500000
+% Meadow only reports 1659772; round down a bit to be safe.
+m 1600000
+
+% Correct printer offset. You can use testpage.tex from the LaTeX
+% distribution to find these numbers. Print testpage.dvi more than once.
+O 0pt,0pt
+
+% Partially download Type 1 fonts by default.  Only reason not to do
+% this is if you encounter bugs.  (Please report them to
+% @email{tex-k@@mail.tug.org} if you do.)
+j
+
+% Also look for fonts at these resolutions.
+R 300 329 360 432 518 600 622 657 720 746 864 1037 1244 1493
+
+% With a high resolution and a RISC cpu, better to compress the bitmaps.
+Z
+
+% Uncomment these if you have and want to use PostScript versions of the
+% fonts.
+%p +cmfonts.map
+%p +lafonts.map
+%p +cyrfonts.map
+%p +eufonts.map
+
+% If your printer doesn't support setpagedevice, and your default paper
+% size is A4, uncomment this.
+%@ A4size 210mm 297mm
+%@+ %%PaperSize: A4
+
+% If you want the lettersize definition that uses setpagedevice to be
+% the default, comment this out.
+@ letterSize 8.5in 11in
+
+% More paper size information.  First definition is the default.
+% These definitions were generated by the contrib/mkdvipspapers Perl 5 script,
+% by Yves.Arrouye@imag.fr.
+%
+% If your default is a4 put the a4 definition first (i.e., before the letter
+% definition). You should always keep a definition here in order to have the
+% document print on the desired paper if possible even outside your original
+% environment.
+% 
+% If your default is something else than a4, of course, put its
+% definition first!
+
+@ letter 8.5in 11in
+@+ ! %%DocumentPaperSizes: Letter
+@+ %%PaperSize: Letter
+@+ %%BeginPaperSize: Letter
+@+ /setpagedevice where {
+@+   pop 1 dict dup /PageSize [ 612 792 ] put setpagedevice
+@+ } {
+@+   statusdict /lettertray known {
+@+     statusdict begin lettertray end
+@+     /letter where { pop letter } if
+@+   } {
+@+     /letter where {
+@+       pop letter
+@+     } {
+@+       statusdict /setpage known {
+@+         statusdict begin
+@+           612 792 0 setpage
+@+         end
+@+       } if
+@+     } ifelse
+@+   } ifelse
+@+ } ifelse
+@+ %%EndPaperSize
+
+@ a4 210mm 297mm
+@+ ! %%DocumentPaperSizes: a4
+@+ %%PaperSize: a4
+@+ %%BeginPaperSize: a4
+@+ /setpagedevice where {
+@+   pop 1 dict dup /PageSize [ 595 842 ] put setpagedevice
+@+ } {
+@+   statusdict /a4tray known {
+@+     statusdict begin a4tray end
+@+     /a4 where { pop a4 } if
+@+   } {
+@+     /a4 where {
+@+       pop a4
+@+     } {
+@+       statusdict /setpage known {
+@+         statusdict begin
+@+           595 842 0 setpage
+@+         end
+@+       } if
+@+     } ifelse
+@+   } ifelse
+@+ } ifelse
+@+ %%EndPaperSize
+
+@ 11x17 11in 17in
+@+ ! %%DocumentPaperSizes: 11x17
+@+ %%PaperSize: 11x17
+@+ %%BeginPaperSize: 11x17
+@+ /setpagedevice where {
+@+   pop 1 dict dup /PageSize [ 792 1224 ] put setpagedevice
+@+ } {
+@+   statusdict /11x17tray known {
+@+     statusdict begin 11x17tray end
+@+     /11x17 where { pop 11x17 } if
+@+   } {
+@+     /11x17 where {
+@+       pop 11x17
+@+     } {
+@+       statusdict /setpage known {
+@+         statusdict begin
+@+           792 1224 0 setpage
+@+         end
+@+       } if
+@+     } ifelse
+@+   } ifelse
+@+ } ifelse
+@+ %%EndPaperSize
+
+@ a3 297mm 420mm
+@+ ! %%DocumentPaperSizes: a3
+@+ %%PaperSize: a3
+@+ %%BeginPaperSize: a3
+@+ /setpagedevice where {
+@+   pop 1 dict dup /PageSize [ 842 1190 ] put setpagedevice
+@+ } {
+@+   statusdict /a3tray known {
+@+     statusdict begin a3tray end
+@+     /a3 where { pop a3 } if
+@+   } {
+@+     /a3 where {
+@+       pop a3
+@+     } {
+@+       statusdict /setpage known {
+@+         statusdict begin
+@+           842 1190 0 setpage
+@+         end
+@+       } if
+@+     } ifelse
+@+   } ifelse
+@+ } ifelse
+@+ %%EndPaperSize
+
+@ b5 177mm 250mm
+@+ ! %%DocumentPaperSizes: b5
+@+ %%PaperSize: b5
+@+ %%BeginPaperSize: b5
+@+ /setpagedevice where {
+@+   pop 1 dict dup /PageSize [ 502 709 ] put setpagedevice
+@+ } {
+@+   statusdict /b5tray known {
+@+     statusdict begin b5tray end
+@+     /ab5 where { pop ab5 } if
+@+   } {
+@+     /ab5 where {
+@+       pop ab5
+@+     } {
+@+       statusdict /setpage known {
+@+         statusdict begin
+@+           502 709 0 setpage
+@+         end
+@+       } if
+@+     } ifelse
+@+   } ifelse
+@+ } ifelse
+@+ %%EndPaperSize
+
+@ ledger 11in 17in
+@+ ! %%DocumentPaperSizes: Ledger
+@+ %%PaperSize: Ledger
+@+ %%BeginPaperSize: Ledger
+@+ /setpagedevice where {
+@+   pop 1 dict dup /PageSize [ 792 1224 exch ] put setpagedevice
+@+ } {
+@+   statusdict /ledgertray known {
+@+     statusdict begin ledgertray end
+@+     /ledger where { pop ledger } if
+@+   } {
+@+     /ledger where {
+@+       pop ledger
+@+     } {
+@+       statusdict /setpage known {
+@+         statusdict begin
+@+           792 1224 1 setpage
+@+         end
+@+       } if
+@+     } ifelse
+@+   } ifelse
+@+ } ifelse
+@+ %%EndPaperSize
+
+@ legal 8.5in 14in
+@+ ! %%DocumentPaperSizes: Legal
+@+ %%PaperSize: Legal
+@+ %%BeginPaperSize: Legal
+@+ /setpagedevice where {
+@+   pop 1 dict dup /PageSize [ 612 1008 ] put setpagedevice
+@+ } {
+@+   statusdict /legaltray known {
+@+     statusdict begin legaltray end
+@+     /legal where { pop legal } if
+@+   } {
+@+     /legal where {
+@+       pop legal
+@+     } {
+@+       statusdict /setpage known {
+@+         statusdict begin
+@+           612 1008 0 setpage
+@+         end
+@+       } if
+@+     } ifelse
+@+   } ifelse
+@+ } ifelse
+@+ %%EndPaperSize
+
+@ note 7.5in 10in
+@+ ! %%DocumentPaperSizes: Note
+@+ %%PaperSize: Note
+@+ %%BeginPaperSize: Note
+@+ /setpagedevice where {
+@+   pop 1 dict dup /PageSize [ 540 720 ] put setpagedevice
+@+ } {
+@+   statusdict /notetray known {
+@+     statusdict begin notetray end
+@+     /note where { pop note } if
+@+   } {
+@+     /note where {
+@+       pop note
+@+     } {
+@+       statusdict /setpage known {
+@+         statusdict begin
+@+           540 720 0 setpage
+@+         end
+@+       } if
+@+     } ifelse
+@+   } ifelse
+@+ } ifelse
+@+ %%EndPaperSize
+
+@ tabloid 11in 17in
+@+ ! %%DocumentPaperSizes: Tabloid
+@+ %%PaperSize: Tabloid
+@+ %%BeginPaperSize: Tabloid
+@+ /setpagedevice where {
+@+   pop 1 dict dup /PageSize [ 792 1224 ] put setpagedevice
+@+ } {
+@+   statusdict /11x17tray known {
+@+     statusdict begin 11x17tray end
+@+     /11x17 where { pop 11x17 } if
+@+   } {
+@+     /11x17 where {
+@+       pop 11x17
+@+     } {
+@+       statusdict /setpage known {
+@+         statusdict begin
+@+           792 1224 0 setpage
+@+         end
+@+       } if
+@+     } ifelse
+@+   } ifelse
+@+ } ifelse
+@+ %%EndPaperSize
Index: texk/dvipsk/configure
diff -u texk/dvipsk/configure:1.1.1.1 texk/dvipsk/configure:1.3
--- texk/dvipsk/configure:1.1.1.1	Fri Jul 18 17:04:59 1997
+++ texk/dvipsk/configure	Mon Sep  8 23:40:48 1997
@@ -1603,10 +1603,10 @@
   withval="$with_maketexmf_default"
   :
 else
-  enableval=yes
+  withval=yes
 fi
 
-if test $enableval = yes; then
+if test $withval = yes; then
   cat >> confdefs.h <<\EOF
 #define MAKE_TEX_MF_BY_DEFAULT 1
 EOF
@@ -1617,10 +1617,10 @@
   withval="$with_maketexpk_default"
   :
 else
-  enableval=yes
+  withval=yes
 fi
 
-if test $enableval = yes; then
+if test $withval = yes; then
   cat >> confdefs.h <<\EOF
 #define MAKE_TEX_PK_BY_DEFAULT 1
 EOF
@@ -1631,10 +1631,10 @@
   withval="$with_maketextfm_default"
   :
 else
-  enableval=yes
+  withval=yes
 fi
 
-if test $enableval = yes; then
+if test $withval = yes; then
   cat >> confdefs.h <<\EOF
 #define MAKE_TEX_TFM_BY_DEFAULT 1
 EOF
Index: texk/dvipsk/psfonts.map
diff -u texk/dvipsk/psfonts.map:1.1.1.1 texk/dvipsk/psfonts.map:1.4
--- texk/dvipsk/psfonts.map:1.1.1.1	Fri Jul 18 17:05:07 1997
+++ texk/dvipsk/psfonts.map	Fri Oct 31 02:24:55 1997
@@ -83,6 +83,11 @@
 rbchb	 CharterBT-Bold			<bchb.pfb
 rbchbi	 CharterBT-BoldItalic		<bchbi.pfb
 
+bchr8a	 CharterBT-Roman		<bchr.pfb
+bchri8a	 CharterBT-Italic		<bchri.pfb
+bchb8a	 CharterBT-Bold			<bchb.pfb
+bchbi8a	 CharterBT-BoldItalic		<bchbi.pfb
+
 % NimbusRoman is actually Times, and NimbusSans is Helvetica.
 ruaqrrc	 URWAntiquaT-RegularCondensed	<uaqrrc.pfa
 rugqb	 URWGroteskT-Bold		<ugqb.pfa
@@ -232,8 +237,8 @@
 rcshx	 CgShannonExBd			<cshx.pfa
 
 %  The same for 8r (new base encoding).
-bchbo8r CharterBT-Bold ".167 SlantFont " <bchb.pfa
-bchro8r CharterBT-Roman ".167 SlantFont " <bchr.pfa
+bchbo8r CharterBT-Bold ".167 SlantFont " <bchb.pfb
+bchro8r CharterBT-Roman ".167 SlantFont " <bchr.pfb
 pbkdo8r Bookman-Demi ".167 SlantFont"
 pbklo8r Bookman-Light ".167 SlantFont"
 pncbo8r NewCenturySchlbk-Bold ".167 SlantFont"
@@ -261,6 +266,10 @@
 phvron8r	 Helvetica-Oblique	".82 ExtendFont"	"TeXBase1Encoding ReEncodeFont" <8r.enc
 phvbrn8r	 Helvetica-Bold		".82 ExtendFont"	"TeXBase1Encoding ReEncodeFont" <8r.enc
 phvbon8r	 Helvetica-BoldOblique	".82 ExtendFont"	"TeXBase1Encoding ReEncodeFont" <8r.enc
+phvr8rn	 Helvetica		".82 ExtendFont"	"TeXBase1Encoding ReEncodeFont" <8r.enc
+phvro8rn	 Helvetica-Oblique	".82 ExtendFont"	"TeXBase1Encoding ReEncodeFont" <8r.enc
+phvb8rn	 Helvetica-Bold		".82 ExtendFont"	"TeXBase1Encoding ReEncodeFont" <8r.enc
+phvbo8rn	 Helvetica-BoldOblique	".82 ExtendFont"	"TeXBase1Encoding ReEncodeFont" <8r.enc
 pncr8r	 NewCenturySchlbk-Roman	"TeXBase1Encoding ReEncodeFont" <8r.enc
 pncri8r	 NewCenturySchlbk-Italic	"TeXBase1Encoding ReEncodeFont" <8r.enc
 pncb8r	 NewCenturySchlbk-Bold	"TeXBase1Encoding ReEncodeFont" <8r.enc
@@ -437,10 +446,10 @@
 putbo0 Utopia-Bold ".167 SlantFont " <putb.pfa
 bchr0	 CharterBT-Roman		<bchr.pfb
 bchri0	 CharterBT-Italic		<bchri.pfb
-bchro0 CharterBT-Roman ".167 SlantFont " <bchr.pfa
+bchro0 CharterBT-Roman ".167 SlantFont " <bchr.pfb
 bchb0	 CharterBT-Bold			<bchb.pfb
 bchbi0	 CharterBT-BoldItalic		<bchbi.pfb
-bchbo0 CharterBT-Bold ".167 SlantFont " <bchb.pfa
+bchbo0 CharterBT-Bold ".167 SlantFont " <bchb.pfb
 uaqrrc0	 URWAntiquaT-RegularCondensed	<uaqrrc.pfa
 ugqb0	 URWGroteskT-Bold		<ugqb.pfa
 unmr0	 NimbusRomanNo9L-Regular	<unmr.pfa
Index: texk/kpathsea/Makefile.in
diff -u texk/kpathsea/Makefile.in:1.1.1.1 texk/kpathsea/Makefile.in:1.2
--- texk/kpathsea/Makefile.in:1.1.1.1	Fri Jul 18 17:02:57 1997
+++ texk/kpathsea/Makefile.in	Tue Oct 14 15:06:32 1997
@@ -142,7 +142,7 @@
 
 install-data: texmf.cnf kpathsea.info
 	$(SHELL) $(top_srcdir)/../mkdirchain $(texmf) $(infodir) $(web2cdir)
-	if grep 'original texmf.cnf --' $(web2cdir)/texmf.cnf >/dev/null 2>&1 \
+	if grep 'newtex texmf.cnf --' $(web2cdir)/texmf.cnf >/dev/null 2>&1 \
 	   || test ! -r $(web2cdir)/texmf.cnf; then \
 	  $(INSTALL_DATA) texmf.cnf $(web2cdir)/texmf.cnf; \
 	else true; fi
Index: texk/kpathsea/acconfig.h
diff -u texk/kpathsea/acconfig.h:1.1.1.1 texk/kpathsea/acconfig.h:1.2
--- texk/kpathsea/acconfig.h:1.1.1.1	Fri Jul 18 17:02:58 1997
+++ texk/kpathsea/acconfig.h	Tue Sep  9 00:09:41 1997
@@ -56,7 +56,7 @@
 #undef NO_DUMP_SHARE
 
 /* web2c: Default editor for interactive `e' option. */
-#define EDITOR "vi +%d %s"
+#define EDITOR "emacs +%d %s"
 
 /* web2c: Window system support for Metafont. */
 #undef HP2627WIN
Index: texk/kpathsea/configure
diff -u texk/kpathsea/configure:1.1.1.1 texk/kpathsea/configure:1.3
--- texk/kpathsea/configure:1.1.1.1	Fri Jul 18 17:03:13 1997
+++ texk/kpathsea/configure	Mon Sep  8 23:40:48 1997
@@ -1603,10 +1603,10 @@
   withval="$with_maketexmf_default"
   :
 else
-  enableval=yes
+  withval=yes
 fi
 
-if test $enableval = yes; then
+if test $withval = yes; then
   cat >> confdefs.h <<\EOF
 #define MAKE_TEX_MF_BY_DEFAULT 1
 EOF
@@ -1617,10 +1617,10 @@
   withval="$with_maketexpk_default"
   :
 else
-  enableval=yes
+  withval=yes
 fi
 
-if test $enableval = yes; then
+if test $withval = yes; then
   cat >> confdefs.h <<\EOF
 #define MAKE_TEX_PK_BY_DEFAULT 1
 EOF
@@ -1631,10 +1631,10 @@
   withval="$with_maketextfm_default"
   :
 else
-  enableval=yes
+  withval=yes
 fi
 
-if test $enableval = yes; then
+if test $withval = yes; then
   cat >> confdefs.h <<\EOF
 #define MAKE_TEX_TFM_BY_DEFAULT 1
 EOF
Index: texk/kpathsea/elt-dirs.c
diff -u texk/kpathsea/elt-dirs.c:1.1.1.1 texk/kpathsea/elt-dirs.c:1.2
--- texk/kpathsea/elt-dirs.c:1.1.1.1	Fri Jul 18 17:03:06 1997
+++ texk/kpathsea/elt-dirs.c	Tue Sep 23 19:33:38 1997
@@ -155,9 +155,8 @@
        example, POST might be `pk/ljfour', and they might have a
        directory `$TEXMF/fonts/pk/ljfour' that we should find.  */
     fn_str_grow (&name, post);
-    if (dir_p (FN_STRING (name)))
-      dir_list_add (str_list_ptr, FN_STRING (name));
-      fn_shrink_to (&name, elt_length);
+    expand_elt (str_list_ptr, FN_STRING (name), elt_length);
+    fn_shrink_to (&name, elt_length);
   }
   proceed = 1;
   while (proceed) {
@@ -170,16 +169,6 @@
 	/* It's a directory, so append the separator.  */
 	fn_str_grow (&name, DIR_SEP_STRING);
 
-	if (*post != 0) { 
-	  fn_str_grow (&name, post);
-	  /* Unfortunately we can't check if the new element is
-	     a leaf directory, because we don't have a directory
-	     name here, we just have a path spec. This means we
-	     may descend into a leaf directory cm/pk, if the
-	     spec is ...fonts//pk//.  */
-	  expand_elt (str_list_ptr, FN_STRING (name), potential_len);
-	  fn_shrink_to (&name, potential_len);
-	}
 	do_subdir (str_list_ptr, FN_STRING (name),
 		   potential_len, post);
       }
@@ -208,8 +197,7 @@
          example, POST might be `pk/ljfour', and they might have a
          directory `$TEXMF/fonts/pk/ljfour' that we should find.  */
       fn_str_grow (&name, post);
-      if (dir_p (FN_STRING (name)))
-        dir_list_add (str_list_ptr, FN_STRING (name));
+      expand_elt (str_list_ptr, FN_STRING (name), elt_length);
       fn_shrink_to (&name, elt_length);
     }
 
@@ -233,18 +221,6 @@
               /* It's a directory, so append the separator.  */
               fn_str_grow (&name, DIR_SEP_STRING);
               
-              if (*post != 0)
-                { 
-                  fn_str_grow (&name, post);
-                  /* Unfortunately we can't check if the new element is
-                     a leaf directory, because we don't have a directory
-                     name here, we just have a path spec. This means we
-                     may descend into a leaf directory cm/pk, if the
-                     spec is ...fonts//pk//.  */
-                  expand_elt (str_list_ptr, FN_STRING (name), potential_len);
-                  fn_shrink_to (&name, potential_len);
-                }
-              
               /* Should we recurse?  To see if the subdirectory is a
                  leaf, check if it has two links (one for . and one for
                  ..).  This means that symbolic links to directories do
@@ -295,8 +271,7 @@
 expand_elt P3C(str_llist_type *, str_list_ptr,  const_string, elt,
                unsigned, start)
 {
-  boolean found_special = false;
-  const_string dir = elt + start;
+  const_string dir = elt + start, post;
   
   while (*dir != 0)
     {
@@ -306,12 +281,9 @@
           if (IS_DIR_SEP (dir[1]))
             {
               unsigned slash_count;
-              for (slash_count = 1; IS_DIR_SEP (dir[slash_count + 1]);
-                   slash_count++) ;
-              do_subdir (str_list_ptr, elt, dir - elt + 1,
-                         dir + 1 + slash_count);
-              found_special = true;
-              dir += slash_count; /* Don't find this // again.  */
+	      for (post = dir + 1; IS_DIR_SEP (*post); post++) ;
+              do_subdir (str_list_ptr, elt, dir - elt + 1, post);
+	      return;
             }
 
           /* No special stuff at this slash.  Keep going.  */
@@ -320,9 +292,8 @@
       dir++;
     }
   
-  if (!found_special)
-    /* When we reach the end of ELT, it will be a normal filename.  */
-    checked_dir_list_add (str_list_ptr, elt);
+  /* When we reach the end of ELT, it will be a normal filename.  */
+  checked_dir_list_add (str_list_ptr, elt);
 }
 
 /* Here is the entry point.  Returns directory list for ELT.  */
Index: texk/kpathsea/tex-file.c
diff -u texk/kpathsea/tex-file.c:1.1.1.1 texk/kpathsea/tex-file.c:1.2
--- texk/kpathsea/tex-file.c:1.1.1.1	Fri Jul 18 17:03:10 1997
+++ texk/kpathsea/tex-file.c	Tue Oct 21 23:13:29 1997
@@ -527,8 +527,9 @@
   boolean name_has_suffix_already = false;
   string ret = NULL;
 
-  /* A null or empty NAME is surely a mistake.  */
-  assert (name && *name);
+  /* A null NAME is surely a mistake.  (Empty names are OK: the tools
+     package includes a file named ".tex".) */
+  assert (name);
   
   if (FMT_INFO.path == NULL)
     kpse_init_format (format);
Index: texk/kpathsea/texmf.cnf.in
diff -u texk/kpathsea/texmf.cnf.in:1.1.1.1 texk/kpathsea/texmf.cnf.in:1.7
--- texk/kpathsea/texmf.cnf.in:1.1.1.1	Fri Jul 18 17:02:58 1997
+++ texk/kpathsea/texmf.cnf.in	Tue Oct 21 23:34:49 1997
@@ -1,4 +1,4 @@
-% original texmf.cnf -- runtime path configuration file for kpathsea.
+% Athena newtex texmf.cnf -- runtime path configuration file for kpathsea.
 % (If you change or delete `original' on the previous line, the
 % distribution won't install its version over yours.)
 % Public domain.
@@ -54,10 +54,15 @@
 % Also set TEXMFDBS to /usr/local/mytex:/usr/local/othertex,
 %  and set TEXMFMAIN to whichever is the main tree (with ./web2c, etc.),
 %  and set TEXMFLS_R to the tree where you want generated files to go
-% 
+%
+% The fallback srvd corresponds to a current Athena platform.
+srvd = {/srvd,/afs/athena.mit.edu/system/sun4x_55/srvd}
+% Grr.  This makes it very hard to set TEXMFMAIN properly.
+% TEXMF = {@texmf@,/afs/sipb.mit.edu/project/tex/share/texmf}
 TEXMF = @texmf@
+oldTEXMF = {$srvd/usr/athena/lib,/mit/tex/lib}
 % Change this if you have multiple trees or MakeTeX* will fail:
-TEXMFMAIN = $TEXMF
+TEXMFMAIN = @texmf@
 % (this is the default) TEXMFLS_R = $TEXMFMAIN
 % (this is the default) TEXMFCNF_DIR = $TEXMFMAIN
 
@@ -66,8 +71,11 @@
 TEXMFDBS = $TEXMF
 
 % The TeX inputs and fonts directories.
+% $oldTEXMF/tex/macros is listed separately because its directory structure
+% is different from the current one.
 texdir = @texinputdir@
-fontdir = @fontdir@
+oldtexdir = $oldTEXMF/tex/macros
+fontdir = {@fontdir@,$oldTEXMF/tex/fonts}
 
 % To avoid searching the filesystem, use the commented-out definitions here.
 %dbtex = !!$texdir
@@ -77,17 +85,26 @@
 
 % TeX input files -- i.e., anything to be found by \input or \openin,
 % including .sty, .eps, etc. 
-TEXINPUTS = .:$dbtex//
+% This shouldn't be here, because earlier entries override later ones.
+% TEXINPUTS = .:$dbtex//
 
 % LaTeX 2e specific macros are stored in latex/, macros that can only be
 % used with 2.09 in latex209/.  In addition, we look in the directory
 % latex2, useful for macros that were written for 2.09 and do not
 % mention 2e at all, but can be used with 2e.
-latex209_inputs = .:$dbtex/latex209//:$dbtex/latex//:$dbtex/generic//
-latex2e_inputs = .:$dbtex/latex//:$dbtex/latex209//:$dbtex/generic//
+latex209_inputs = .:$dbtex/latex209//:$dbtex/latex2//:$dbtex/latex//:$dbtex/generic//:$dbtex//:$oldtexdir/latex//:$oldtexdir/other//:$oldtexdir//
+latex2e_inputs = .:$dbtex/latex//:$dbtex/latex2//:$dbtex/latex209//:$dbtex/generic//:$dbtex//:$oldtexdir/other//:$oldtexdir/latex//:$oldtexdir//
 TEXINPUTS.latex209 = $latex209_inputs
+TEXINPUTS.etex_latex209 = $latex209_inputs
+TEXINPUTS.slitex = $latex209_inputs
+TEXINPUTS.etex_slitex = $latex209_inputs
+TEXINPUTS.amslatex = $latex209_inputs
+TEXINPUTS.etex_amslatex = $latex209_inputs
 TEXINPUTS.latex2e = $latex2e_inputs
-TEXINPUTS.latex = $latex2e_inputs
+TEXINPUTS.etex_latex2e = $latex2e_inputs
+% Athena still favors 2.09 :-(
+TEXINPUTS.latex = $latex209_inputs
+TEXINPUTS.etex_latex = $latex209_inputs
 
 % Fontinst needs to read afm files.
 TEXINPUTS.fontinst = .:$dbtex//:$dbfonts//afm//
@@ -95,33 +112,42 @@
 % Plain TeX.  Have the command tex check all directories as a last
 % resort, we may have plain-compatible stuff anywhere.
 plain_inputs = $dbtex/plain//:$dbtex/generic//
-TEXINPUTS.tex = .:$plain_inputs:$dbtex//
+TEXINPUTS.tex = .:$plain_inputs:$dbtex//:$oldtexdir//
+TEXINPUTS.etex = .:$plain_inputs:$dbtex//:$oldtexdir//
 % other plain-based formats
-TEXINPUTS.amstex = .:$dbtex/amstex//:$plain_inputs
-TEXINPUTS.ftex = .:$dbtex/formate//:$plain_inputs
-TEXINPUTS.texinfo = .:$dbtex/texinfo//:$plain_inputs
+TEXINPUTS.amstex = .:$dbtex/amstex//:$plain_inputs:$oldtexdir//
+TEXINPUTS.etex_amstex = .:$dbtex/amstex//:$plain_inputs:$oldtexdir//
+TEXINPUTS.ftex = .:$dbtex/formate//:$plain_inputs:$oldtexdir//
+TEXINPUTS.eplain = .:$dbtex/eplain//:$plain_inputs:$oldtexdir//
+TEXINPUTS.etex_eplain = .:$dbtex/eplain//:$plain_inputs:$oldtexdir//
+
+% TeXinfo, and nothing else, uses @ to introduce contro sequences.
+TEXINPUTS.texinfo = .:$dbtex/texinfo//
+TEXINPUTS.etex_texinfo = .:$dbtex/texinfo//
 
 % INITEX. May as well make this separate so it can search on disk;
 % initex is seldom run, and might be used directly after files have been
 % added, when ls-R may not up be to date.
-TEXINPUTS.initex = .:$texdir//
+TEXINPUTS.initex = .:$texdir//:$oldtexdir//
 
 % Earlier entries override later ones, so put this last.
-TEXINPUTS = .:$dbtex//
+TEXINPUTS = .:$dbtex//:$oldtexdir//
 
 % Metafont, MetaPost inputs.
-MFINPUTS = .:@mfinputdir@//:{$dbfonts,$VARTEXFONTS}//source//
+MFINPUTS = .:@mfinputdir@//:{$dbfonts,$VARTEXFONTS}//source//:$oldTEXMF/mf//
 MPINPUTS = .:@mpinputdir@//
 
 % Dump files (fmt/base/mem) for vir{tex,mf,mp} to read (see
 % web2c/INSTALL), and string pools (.pool) for ini{tex,mf,mp}.  It is
 % silly that we have six paths and directories here (they all resolve to
 % a single place by default), but historically ...
-TEXFORMATS = .:@fmtdir@
-MFBASES = .:@basedir@
+% Old bases and formats will almost certainly not work, but we list them
+% just in case.
+TEXFORMATS = .:@fmtdir@:$oldTEXMF/tex/formats
+MFBASES = .:@basedir@:$oldTEXMF/mf/bases
 MPMEMS = .:@memdir@
-TEXPOOL = .:@texpooldir@
-MFPOOL = .:@mfpooldir@
+TEXPOOL = .:@texpooldir@:$oldTEXMF/tex
+MFPOOL = .:@mfpooldir@:$oldTEXMF/mf
 MPPOOL = .:@mppooldir@
 
 % If you have a read-only central font directory and therefore need to
@@ -151,17 +177,17 @@
 
 % For texfonts.map and included map files used by MakeTeXPK.
 % See ftp://ftp.tug.org/tex/fontname.tar.gz.
-TEXFONTMAPS = .:$TEXMF/fontname
+TEXFONTMAPS = .:$TEXMF/fontname:$oldTEXMF/fonts
 
 % BibTeX bibliographies and style files.
-BIBINPUTS = .:$TEXMF/bibtex/bib//
-BSTINPUTS = .:$TEXMF/bibtex/bst//
+BIBINPUTS = .:$TEXMF/bibtex/bib//:$oldtexdir/bib//:$oldtexdir/other//
+BSTINPUTS = .:$TEXMF/bibtex/bst//:$oldtexdir/bib//:$oldtexdir/other//
 
 % MFT style files.
 MFTINPUTS = .:$TEXMF/mft//
 
 % PostScript headers, prologues (.pro), encodings (.enc) and fonts.
-TEXPSHEADERS = .:@psheaderdir@//:$dbfonts//type1//
+TEXPSHEADERS = .:@psheaderdir@//:$dbfonts//type1//:$oldTEXMF/ps//
 
 % PostScript Type 1 outline fonts.
 T1FONTS = .:$dbfonts//type1//
@@ -170,7 +196,7 @@
 AFMFONTS = .:$dbfonts//afm//
 
 % Dvips' config.* files (this name should not start with `TEX'!).
-TEXCONFIG = .:@dvipsdir@//
+TEXCONFIG = .:@dvipsdir@//:$oldTEXMF/ps//
 
 % Makeindex style (.ist) files.
 INDEXSTYLE = .:$TEXMF/makeindex//
@@ -182,12 +208,14 @@
 % For xdvi to find mime.types and .mailcap, if they do not exist in
 % $HOME.  These are single directories, not paths.
 % (But the default mime.types, at least, may well suffice.)
-MIMELIBDIR = $prefix/etc
-MAILCAPLIBDIR = $prefix/etc
+% Don't depend on mime's or infoagent's being attached.
+% (Perhaps we should just put copies in the newtex locker?)
+MIMELIBDIR = /afs/athena.mit.edu/project/mime/etc
+MAILCAPLIBDIR = /afs/athena.mit.edu/software/infoagents/share/Netscape
 
 % TeX documentation and source files, for use with kpsewhich.
 TEXDOCS = .:$TEXMF/doc//
-TEXSOURCES = .:$TEXMF/source//
+TEXSOURCES = .:$TEXMF/source//:/afs/sipb.mit.edu/project/tex-dev//
 
 % Omega-related fonts and other files.
 OFMFONTS = .:{$dbfonts,$VARTEXFONTS}//ofm//
@@ -247,11 +275,13 @@
 % These values are ignored if the script names are changed; e.g., if you
 % set DVIPSMAKEPK to `foo', what counts is the value of the environment
 % variable/config value `FOO', not the `MAKETEXPK' value.
-% 
-% MAKETEXTEX = 0
-% MAKETEXPK = 0
-% MAKETEXMF = 0
-% MAKETEXTFM = 0
+%
+% Dynamic font generation doesn't work very well with Athena,
+% so we disable it. 
+MAKETEXTEX = 0
+MAKETEXPK = 0
+MAKETEXMF = 0
+MAKETEXTFM = 0
 
 % What MetaPost runs to make MPX files.  This is passed an option -troff
 % if MP is in troff mode.  Set to `0' to disable this feature.
@@ -337,3 +367,4 @@
 error_line = 79
 half_error_line = 50
 max_print_line = 79
+% Uhh...Uhh...
Index: texk/kpathsea/withenable.ac
diff -u texk/kpathsea/withenable.ac:1.1.1.1 texk/kpathsea/withenable.ac:1.2
--- texk/kpathsea/withenable.ac:1.1.1.1	Fri Jul 18 17:03:22 1997
+++ texk/kpathsea/withenable.ac	Mon Sep  8 23:30:41 1997
@@ -2,19 +2,19 @@
 
 AC_ARG_WITH(maketexmf-default,
 [  --without-maketexmf-default  do not run MakeTeXMF if MF source missing],
-  , enableval=yes)
-if test $enableval = yes; then
+  , withval=yes)
+if test $withval = yes; then
   AC_DEFINE(MAKE_TEX_MF_BY_DEFAULT)
 fi
 AC_ARG_WITH(maketexpk-default,
 [  --without-maketexpk-default  do not run MakeTeXPK if PK font missing],
-  , enableval=yes)
-if test $enableval = yes; then
+  , withval=yes)
+if test $withval = yes; then
   AC_DEFINE(MAKE_TEX_PK_BY_DEFAULT)
 fi
 AC_ARG_WITH(maketextfm-default,
 [  --without-maketextfm-default do not run MakeTeXTFM if TFM file missing],
-   , enableval=yes)
-if test $enableval = yes; then
+   , withval=yes)
+if test $withval = yes; then
   AC_DEFINE(MAKE_TEX_TFM_BY_DEFAULT)
 fi
Index: texk/make/paths.make
diff -u texk/make/paths.make:1.1.1.1 texk/make/paths.make:1.2
--- texk/make/paths.make:1.1.1.1	Fri Jul 18 17:03:23 1997
+++ texk/make/paths.make	Sun Aug 31 21:03:40 1997
@@ -16,7 +16,8 @@
 bindir = @bindir@
 
 # Architecture-independent executables.
-scriptdir = $(bindir)
+# scriptdir = $(bindir)
+scriptdir = $(prefix)/arch/share/bin
 
 # Architecture-dependent files, such as lib*.a files.
 libdir = @libdir@
@@ -61,6 +62,7 @@
 fontdir = $(texmf)/fonts
 
 # Memory dumps (.fmt/.base/.mem).
+# Be sure to change this if you run configure with --disable-dump-share!
 fmtdir = $(web2cdir)
 basedir = $(fmtdir)
 memdir = $(fmtdir)
Index: texk/web2c/Makefile.in
diff -u texk/web2c/Makefile.in:1.1.1.1 texk/web2c/Makefile.in:1.13
--- texk/web2c/Makefile.in:1.1.1.1	Fri Jul 18 17:01:50 1997
+++ texk/web2c/Makefile.in	Wed Oct 22 00:56:52 1997
@@ -5,10 +5,19 @@
 # install-fmts/install-bases/install-mems will install. plain.* is
 # created automatically (as a link).  See the Formats node in
 # doc/web2c.texi for details on the fmts.
-fmts = latex.fmt # amstex.fmt eplain.fmt texinfo.fmt
-bases = # I do not recommend building cmmf.base.
+#fmts = latex.fmt # amstex.fmt eplain.fmt texinfo.fmt
+LATEX = latex209
+fmts = latex209.fmt latex2e.fmt latex.fmt slitex.fmt amstex.fmt amslatex.fmt \
+	texinfo.fmt eplain.fmt \
+	etex.fmt etex_latex209.fmt etex_latex2e.fmt etex_latex.fmt \
+	etex_slitex.fmt etex_amstex.fmt etex_amslatex.fmt etex_texinfo.fmt \
+	etex_eplain.fmt
+bases = cmmf.base # Not recommended, but we keep it for compatibility.
 mems =  # mfplain.mem is probably not generally useful.
 
+# This should be tex.ch for TeX and tex-merged.ch for e-TeX.
+TEXCH = tex-merged.ch
+
 # The name of the file that defines your local devices for Metafont.
 # (Only relevant during `make bases'.)  I recommend `modes.mf', which
 # defines all known modes, plus useful definitions for all fonts.  It's
@@ -21,7 +30,7 @@
 LN = @LN_S@
 
 # Used for triptrap.
-DIFF = diff
+DIFF = ./triptrapdiff.pl
 DIFFFLAGS =
 
 .SUFFIXES: # get rid of .p.o
@@ -98,9 +107,12 @@
 mpware = mpware/dmp mpware/makempx mpware/mpto mpware/newer
 mpware_sources = mpware/dmp.c mpware/makempx.in mpware/mpto.c mpware/newer.c
 
+tie = tie/tie
+tie_sources = tie/tie.c
+
 #  
 default all: programs formats doc/web2c.info
-programs: $(programs) $(mpware)
+programs: $(programs) $(mpware) $(tie)
 
 # Rules to link each program. I wish we could use a suffix rule for
 # this, since it's so repetitive, but null suffixes don't work. And old
@@ -150,6 +162,9 @@
 $(mpware): $(mpware_sources)
 	cd mpware && $(MAKE) $(common_makeargs)
 
+$(tie): $(tie_sources)
+	cd tie && $(MAKE) $(common_makeargs)
+
 # Additional dependencies for retangling.
 bibtex.p dvicopy.p dvitomp.p dvitype.p gftopk.p gftodvi.p gftype.p \
   mf.p mft.p mp.p patgen.p \
@@ -170,12 +185,14 @@
 pktype.p: pktype.web pktype.ch
 pltotf.p: pltotf.web pltotf.ch
 pooltype.p: pooltype.web pooltype.ch
-tex.p tex.pool: tex.web tex.ch
 tftopl.p: tftopl.web tftopl.ch
 vftovp.p: vftovp.web vftovp.ch
 vptovf.p: vptovf.web vptovf.ch
 weave.p: weave.web weave.ch
 
+tex.p tex.pool: tex.web $(TEXCH)
+	$(shared_env) ./tangle $(srcdir)/tex.web $(srcdir)/$(TEXCH)
+
 # Additional dependencies for reconverting to C.
 $(other_c): $(web2c_aux) $(web2c_programs)
 bibtex.c: web2c/cvtbib.sed
@@ -190,6 +207,10 @@
 $(tex_c) texcoerce.h texd.h: tex.p $(web2c_texmf)
 	$(web2c) tex
 
+# We need to merge etex.ch and tex.ch with tie.
+tex-merged.ch: $(tie) tex.web etex.ch tex.ch tex.ech
+	$(tie) -c $@ tex.web etex.ch tex.ch tex.ech
+
 # As long as we have to have separate rules to create these, might as well do
 # a little work to avoid separate compilation rules, too.
 mfextra.c: lib/texmfmp.c
@@ -275,13 +296,69 @@
 
 tex.fmt: tex
 	$(MAKE) files="plain.tex cmr10.tfm" prereq-check
-	./tex --ini \\input plain \\dump </dev/null
+	./tex --ini \\input plain \\input SIPB.tex \\dump </dev/null
 	rm -f tex.fmt; mv plain.fmt tex.fmt
 	rm -f tex.log; mv plain.log tex.log
 
-latex.fmt: tex
+etex.fmt: tex
+	$(MAKE) files="etex.src plain.tex cmr10.tfm" prereq-check
+	./tex --ini \*\\input etex.src \\input SIPB.tex \\dump </dev/null
+	rm -f etex.log; mv etex.src.log etex.log
+	rm -f etex.fmt; mv etex.src.fmt etex.fmt
+
+latex.fmt: $(LATEX).fmt
+	rm -f latex.fmt; ln -s $(LATEX).fmt latex.fmt
+	rm -f latex.log; ln -s $(LATEX).log latex.log
+
+etex_latex.fmt: etex_$(LATEX).fmt
+	rm -f etex_latex.fmt; ln -s etex_$(LATEX).fmt etex_latex.fmt
+	rm -f etex_latex.log; ln -s etex_$(LATEX).log etex_latex.log
+
+latex209.fmt: tex
+	$(MAKE) files=lplain.tex prereq-check
+	./tex --ini \\input lplain \\input SIPB.tex \\dump </dev/null
+	rm -f latex209.fmt; mv lplain.fmt latex209.fmt
+	rm -f latex209.log; mv lplain.log latex209.log
+
+etex_latex209.fmt: tex
+	$(MAKE) files=lplain.tex prereq-check
+	./tex --ini \*\\input lplain \\input SIPB.tex \\dump </dev/null
+	rm -f etex_latex209.fmt; mv lplain.fmt etex_latex209.fmt
+	rm -f etex_latex209.log; mv lplain.log etex_latex209.log
+
+latex2e.fmt: tex
+	$(MAKE) files=latex.ltx prereq-check
+	-mv latex.fmt latex.fmt.save
+	-mv latex.log latex.log.save
+# There doesn't appear to be a way to use SIPB.tex here.  Oh well.
+	./tex --ini latex.ltx </dev/null
+	mv latex.fmt latex2e.fmt
+	mv latex.log latex2e.log
+	-mv latex.fmt.save latex.fmt
+	-mv latex.log.save latex.log
+
+etex_latex2e.fmt: tex
 	$(MAKE) files=latex.ltx prereq-check
-	./tex --ini \\input latex.ltx </dev/null
+	-mv latex.fmt latex.fmt.save
+	-mv latex.log latex.log.save
+# There doesn't appear to be a way to use SIPB.tex here.  Oh well.
+	./tex --ini \*latex.ltx </dev/null
+	mv latex.fmt etex_latex2e.fmt
+	mv latex.log etex_latex2e.log
+	-mv latex.fmt.save latex.fmt
+	-mv latex.log.save latex.log
+
+slitex.fmt: tex
+	$(MAKE) files=splain.tex prereq-check
+	./tex --ini \\input splain \\input SIPB.tex \\dump </dev/null
+	mv splain.fmt slitex.fmt
+	mv splain.log slitex.log
+
+etex_slitex.fmt: tex
+	$(MAKE) files=splain.tex prereq-check
+	./tex --ini \*\\input splain \\input SIPB.tex \\dump </dev/null
+	mv splain.fmt etex_slitex.fmt
+	mv splain.log etex_slitex.log
 
 mf.base: mf
 	$(MAKE) files="plain.mf cmr10.mf $(localmodes).mf" prereq-check
@@ -289,6 +366,12 @@
 	rm -f mf.base; mv plain.base mf.base
 	rm -f mf.log; mv plain.log mf.log
 
+cmmf.base: mf mf.base
+	$(MAKE) files="cmbase.mf" prereq-check
+	./mf --ini \&./mf cmbase dump </dev/null
+	rm -f cmmf.base; mv cmbase.base cmmf.base
+	rm -f cmmf.log; mv cmbase.log cmmf.log
+
 mpost.mem: mpost
 	$(MAKE) files=plain.mp prereq-check
 	./mpost --ini \\input plain dump </dev/null
@@ -314,16 +397,92 @@
 
 $(kpathsea_dir)/kpsewhich: $(kpathsea)
 
-amstex.fmt: tex
-	./tex -ini amstex.ini </dev/null
+amstex.fmt: tex tex.fmt
+#	./tex -ini amstex.ini </dev/null
+	./tex -ini \&./tex amstex \\input SIPB.tex \\dump
+
+etex_amstex.fmt: tex etex.fmt
+#	./tex -ini amstex.ini </dev/null
+	-mv amstex.fmt amstex.fmt.save
+	-mv amstex.log amstex.log.save
+	./tex -ini \&./etex amstex \\input SIPB.tex \\dump
+	mv amstex.fmt etex_amstex.fmt
+	mv amstex.log etex_amstex.log
+	-mv amstex.fmt.save amstex.fmt
+	-mv amstex.log.save amstex.log
+
+# AMSLaTeX requires that you
+# 1) move Lamport's lfonts.tex out of TeX's way (I use the lfonts.tex I
+# distribute with the sauter CM parameter files, and call it lfonts.sauter),
+# 2) say `lfonts.new' when lplain.tex can't find lfonts.tex,
+# 3) choose a ``fontdef'' file (I use fontdef.ori),
+# 4) a ``preload'' file, (I use preload.ori),
+# 5) and a ``basefont'' file.  (I use basefont).
+# How automatic, huh?  I can hardly wait for LaTeX 3.
+
+# Gross manual build procedures require gross hacks.
+amslatex.fmt: tex
+	$(MAKE) files=lfonts.new prereq-check
+	rm -f lfonts.tex fontdef.tex preload.tex xxxlfont.sty
+#	cp ../../texmf/tex/amslatex/fontsel/lfonts.new lfonts.tex
+#	cp ../../texmf/tex/amslatex/inputs/fontdef.ams fontdef.tex
+#	cp ../../texmf/tex/amslatex/fontsel/preload.ori preload.tex
+#	cp ../../texmf/tex/amslatex/fontsel/basefont.tex xxxlfont.sty
+	echo '\input lfonts.new' > lfonts.tex
+	echo '\input fontdef.ams' > fontdef.tex
+	echo '\input preload.ori' > preload.tex
+	echo '\input basefont.tex' > xxxlfont.sty
+	./tex -ini lplain \\input SIPB.tex \\dump
+	rm -f lfonts.tex fontdef.tex preload.tex xxxlfont.sty amslatex.fmt
+	rm -f amslatex.log
+	mv lplain.fmt amslatex.fmt
+	mv lplain.log amslatex.log
+
+etex_amslatex.fmt: tex
+	$(MAKE) files=lfonts.new prereq-check
+	rm -f lfonts.tex fontdef.tex preload.tex xxxlfont.sty
+#	cp ../../texmf/tex/amslatex/fontsel/lfonts.new lfonts.tex
+#	cp ../../texmf/tex/amslatex/inputs/fontdef.ams fontdef.tex
+#	cp ../../texmf/tex/amslatex/fontsel/preload.ori preload.tex
+#	cp ../../texmf/tex/amslatex/fontsel/basefont.tex xxxlfont.sty
+	echo '\input lfonts.new' > lfonts.tex
+	echo '\input fontdef.ams' > fontdef.tex
+	echo '\input preload.ori' > preload.tex
+	echo '\input basefont.tex' > xxxlfont.sty
+	./tex -ini \*lplain \\input SIPB.tex \\dump
+	rm -f lfonts.tex fontdef.tex preload.tex xxxlfont.sty
+	rm -f etex_amslatex.fmt etex_amslatex.log
+	mv lplain.fmt etex_amslatex.fmt
+	mv lplain.log etex_amslatex.log
+
 
 # Texinfo changes the escape character from `\' to `@'.
 texinfo.fmt: tex.fmt
-	./tex -ini texinfo @dump </dev/null
+	./tex -ini texinfo @input SIPB.texinfo @dump </dev/null
+
+etex_texinfo.fmt: tex.fmt
+	-mv texinfo.fmt texinfo.fmt.save
+	-mv texinfo.log texinfo.log.save
+	./tex -ini \*texinfo @input SIPB.texinfo @dump </dev/null
+	mv texinfo.fmt etex_texinfo.fmt
+	mv texinfo.log etex_texinfo.log
+	-mv texinfo.fmt.save texinfo.fmt
+	-mv texinfo.log.save texinfo.log
 
 eplain.fmt: tex.fmt
 	touch eplain.aux # Makes cross-reference warnings work right.
-	./tex -ini \&./tex eplain \\dump </dev/null
+	./tex -ini \&./tex eplain \\input SIPB.tex \\dump </dev/null
+
+etex_eplain.fmt: tex.fmt
+	touch eplain.aux # Makes cross-reference warnings work right.
+	-mv eplain.fmt eplain.fmt.save
+	-mv eplain.log eplain.log.save
+	./tex -ini \&./etex eplain \\input SIPB.tex \\dump </dev/null
+	mv eplain.fmt etex_eplain.fmt
+	mv eplain.log etex_eplain.log
+	-mv eplain.fmt.save eplain.fmt
+	-mv eplain.log.save eplain.log
+
 
 # 
 install: install-exec install-data
@@ -335,6 +494,7 @@
 	$(SHELL) $(top_srcdir)/../mkdirchain $(bindir) $(texpooldir) \
 	  $(mfpooldir) $(mppooldir)
 	cd mpware && $(MAKE) $(install_makeargs) install-exec
+	cd tie && $(MAKE) $(install_makeargs) install
 	for p in $(programs); do $(INSTALL_LIBTOOL_PROG) $(bindir) $$p; done
 
 # The links to {mf,mp,tex} for each format and for {ini,vir}{mf,mp,tex}.
@@ -491,14 +651,14 @@
 	@echo ">>> See $(testdir)/trip.diffs for example of acceptable diffs." >&2
 	./pltotf $(testdir)/trip.pl trip.tfm
 	./tftopl ./trip.tfm trip.pl
-	-diff $(testdir)/trip.pl trip.pl
+	$(DIFF) $(DIFFFLAGS) $(testdir)/trip.pl trip.pl
 	rm -f trip.tex; $(LN) $(testdir)/trip.tex . # get same filename in log
 	-$(SHELL) -c '$(testenv) ./tex -ini <$(testdir)/trip1.in >tripin.fot'
 	mv trip.log tripin.log
-	-diff $(testdir)/tripin.log tripin.log
+	-$(DIFF) $(DIFFFLAGS) $(testdir)/tripin.log tripin.log
 # May as well test non-ini second time through.
 	-$(SHELL) -c '$(testenv) ./tex <$(testdir)/trip2.in >trip.fot'
-	-diff $(testdir)/trip.fot trip.fot
+	-$(DIFF) $(DIFFFLAGS) $(testdir)/trip.fot trip.fot
 # We use $(DIFF) instead of `diff' only for those files where there
 # might actually be legitimate numerical differences.
 	-$(DIFF) $(DIFFFLAGS) $(testdir)/trip.log trip.log
@@ -511,48 +671,48 @@
 	rm -f trap.mf; $(LN) $(testdir)/trap.mf . # get same filename in log
 	-$(SHELL) -c '$(testenv) ./mf -ini <$(testdir)/mftrap1.in >mftrapin.fot'
 	mv trap.log mftrapin.log
-	-diff $(testdir)/mftrapin.log mftrapin.log
+	-$(DIFF) $(DIFFFLAGS) $(testdir)/mftrapin.log mftrapin.log
 	-$(SHELL) -c '$(testenv) ./mf <$(testdir)/mftrap2.in >mftrap.fot'
 	mv trap.log mftrap.log
 	mv trap.tfm mftrap.tfm
-	-diff $(testdir)/mftrap.fot mftrap.fot
-	-diff $(testdir)/mftrap.log mftrap.log
+	-$(DIFF) $(DIFFFLAGS) $(testdir)/mftrap.fot mftrap.fot
+	-$(DIFF) $(DIFFFLAGS) $(testdir)/mftrap.log mftrap.log
 	./tftopl ./mftrap.tfm mftrap.pl
-	-diff $(testdir)/mftrap.pl mftrap.pl
+	$(DIFF) $(DIFFFLAGS) $(testdir)/mftrap.pl mftrap.pl
 	$(SHELL) -c '$(testenv) ./gftype -m -i ./trap.72270gf >trap.typ'
-	-diff $(testdir)/trap.typ trap.typ
+	-$(DIFF) $(DIFFFLAGS) $(testdir)/trap.typ trap.typ
 
 mptrap: pltotf mpost tftopl
 	@echo ">>> See $(testdir)/mptrap.diffs for example of acceptable diffs." >&2
 	rm -f mtrap.mp; $(LN) $(testdir)/mtrap.mp . # get same filename in log
 	./pltotf $(testdir)/trapf.pl trapf.tfm
 	-$(SHELL) -c '$(testenv) ./mpost -ini mtrap'
-	-diff $(testdir)/mtrap.log mtrap.log
-	-diff $(testdir)/mtrap.0 mtrap.0
-	-diff $(testdir)/mtrap.1 mtrap.1
-	-diff $(testdir)/writeo writeo
-	-diff $(testdir)/writeo.2 writeo.2
+	-$(DIFF) $(DIFFFLAGS) $(testdir)/mtrap.log mtrap.log
+	$(DIFF) $(DIFFFLAGS) $(testdir)/mtrap.0 mtrap.0
+	$(DIFF) $(DIFFFLAGS) $(testdir)/mtrap.1 mtrap.1
+	$(DIFF) $(DIFFFLAGS) $(testdir)/writeo writeo
+	$(DIFF) $(DIFFFLAGS) $(testdir)/writeo.2 writeo.2
 	rm -f trap.mp; $(LN) $(testdir)/trap.mp .
 	rm -f trap.mpx; $(LN) $(testdir)/trap.mpx .
 	-$(SHELL) -c '$(testenv) ./mpost -ini <$(testdir)/mptrap1.in >mptrapin.fot'
 	mv trap.log mptrapin.log
-	-diff $(testdir)/mptrapin.log mptrapin.log
+	-$(DIFF) $(DIFFFLAGS) $(testdir)/mptrapin.log mptrapin.log
 # Must run inimp or font_name[null_font] is not initialized, leading to diffs.
 	-$(SHELL) -c '$(testenv) ./mpost -ini <$(testdir)/mptrap2.in >mptrap.fot'
 	mv trap.log mptrap.log
 	mv trap.tfm mptrap.tfm
-	-diff $(testdir)/mptrap.fot mptrap.fot
-	-diff $(testdir)/mptrap.log mptrap.log
-	-diff $(testdir)/trap.5 trap.5
-	-diff $(testdir)/trap.6 trap.6
-	-diff $(testdir)/trap.148 trap.148
-	-diff $(testdir)/trap.149 trap.149
-	-diff $(testdir)/trap.150 trap.150
-	-diff $(testdir)/trap.151 trap.151
-	-diff $(testdir)/trap.197 trap.197
-	-diff $(testdir)/trap.200 trap.200
+	-$(DIFF) $(DIFFFLAGS) $(testdir)/mptrap.fot mptrap.fot
+	-$(DIFF) $(DIFFFLAGS) $(testdir)/mptrap.log mptrap.log
+	$(DIFF) $(DIFFFLAGS) $(testdir)/trap.5 trap.5
+	$(DIFF) $(DIFFFLAGS) $(testdir)/trap.6 trap.6
+	$(DIFF) $(DIFFFLAGS) $(testdir)/trap.148 trap.148
+	$(DIFF) $(DIFFFLAGS) $(testdir)/trap.149 trap.149
+	$(DIFF) $(DIFFFLAGS) $(testdir)/trap.150 trap.150
+	$(DIFF) $(DIFFFLAGS) $(testdir)/trap.151 trap.151
+	$(DIFF) $(DIFFFLAGS) $(testdir)/trap.197 trap.197
+	$(DIFF) $(DIFFFLAGS) $(testdir)/trap.200 trap.200
 	./tftopl ./mptrap.tfm mptrap.pl
-	-diff $(testdir)/mptrap.pl mptrap.pl
+	$(DIFF) $(DIFFFLAGS) $(testdir)/mptrap.pl mptrap.pl
 
 # Ad hoc tests.
 bibtex-check: bibtex
@@ -593,7 +753,7 @@
 
 mpost-check: mptrap mpost.mem
 	./mpost '&./mpost \tracingstats:=1; end.'
-	MAKEMPX_BINDIR=`pwd`:`pwd`/mpware ./mpost $(srcdir)/tests/mptest
+	MPXCOMMAND=`pwd`/mpware/makempx ./mpost $(srcdir)/tests/mptest
 	./mpost $(srcdir)/tests/one.two
 	./mpost $(srcdir)/tests/uno.dos
 
@@ -670,7 +830,9 @@
 clean::
 	test ! -r lib/Makefile \
 	  || for d in $(all_subdirs); do (cd $$d && $(MAKE) $@); done
+	mv triptrapdiff.pl triptrapdiff.pl.save
 	rm -f *.aux *.c *.dvi *.fot *.log *.pl *.tfm *.typ 
+	mv triptrapdiff.pl.save triptrapdiff.pl
 	rm -f *.base *.fmt *.mem
 # Have to list generated .h's explicitly since our real headers,
 # e.g., help.h, are in this directory too.
Index: texk/web2c/SIPB.tex
diff -u /dev/null texk/web2c/SIPB.tex:1.1
--- /dev/null	Wed Nov  5 23:19:43 1997
+++ texk/web2c/SIPB.tex	Mon Sep  1 16:17:11 1997
@@ -0,0 +1,6 @@
+%
+% This redefines \everyjob to print out a banner with the format name,
+% version and a reference to newtex.
+
+\expandafter\everyjob\expandafter{\the\everyjob
+  \immediate\write16{[prepared for ``newtex'' locker]}}\dump
Index: texk/web2c/SIPB.texinfo
diff -u /dev/null texk/web2c/SIPB.texinfo:1.1
--- /dev/null	Wed Nov  5 23:19:44 1997
+++ texk/web2c/SIPB.texinfo	Mon Sep  1 16:17:15 1997
@@ -0,0 +1,2 @@
+@expandafter@everyjob@expandafter{@the@everyjob
+  @message{[prepared for ``newtex'' locker]}}@dump
Index: texk/web2c/bibtex.ch
diff -u texk/web2c/bibtex.ch:1.1.1.1 texk/web2c/bibtex.ch:1.2
--- texk/web2c/bibtex.ch:1.1.1.1	Fri Jul 18 17:01:55 1997
+++ texk/web2c/bibtex.ch	Mon Sep  1 15:43:23 1997
@@ -139,7 +139,7 @@
 @x [still 14]
 @!buf_size=1000; {maximum number of characters in an input line (or string)}
 @y
-@!buf_size=3000; {maximum number of characters in an input line (or string)}
+@!buf_size=5000; {maximum number of characters in an input line (or string)}
 @z
 
 @x [still 14]
@@ -178,7 +178,7 @@
 @!MAX_ENT_STRS=3000; {initial number of |str_entry_var|s
                                         (entries $\times$ |str_entry_var|s)}
 @!ent_str_size=250; {maximum size of a |str_entry_var|; must be |<=buf_size|}
-@!glob_str_size=3000; {maximum  size of a |str_global_var|;
+@!glob_str_size=5000; {maximum  size of a |str_global_var|;
                                                         must be |<=buf_size|}
 @!MAX_FIELDS=5000; {initial number of fields (entries $\times$ fields,
 @z
Index: texk/web2c/c-auto.h.in
diff -u texk/web2c/c-auto.h.in:1.1.1.1 texk/web2c/c-auto.h.in:1.2
--- texk/web2c/c-auto.h.in:1.1.1.1	Fri Jul 18 17:01:50 1997
+++ texk/web2c/c-auto.h.in	Mon Sep  1 14:57:11 1997
@@ -76,7 +76,7 @@
 #undef NO_DUMP_SHARE
 
 /* web2c: Default editor for interactive `e' option. */
-#define EDITOR "vi +%d %s"
+#define EDITOR "emacs +%d %s"
 
 /* web2c: Window system support for Metafont. */
 #undef HP2627WIN
Index: texk/web2c/configure
diff -u texk/web2c/configure:1.1.1.1 texk/web2c/configure:1.5
--- texk/web2c/configure:1.1.1.1	Fri Jul 18 17:01:52 1997
+++ texk/web2c/configure	Mon Sep  8 23:40:50 1997
@@ -1635,10 +1635,10 @@
   withval="$with_maketexmf_default"
   :
 else
-  enableval=yes
+  withval=yes
 fi
 
-if test $enableval = yes; then
+if test $withval = yes; then
   cat >> confdefs.h <<\EOF
 #define MAKE_TEX_MF_BY_DEFAULT 1
 EOF
@@ -1649,10 +1649,10 @@
   withval="$with_maketexpk_default"
   :
 else
-  enableval=yes
+  withval=yes
 fi
 
-if test $enableval = yes; then
+if test $withval = yes; then
   cat >> confdefs.h <<\EOF
 #define MAKE_TEX_PK_BY_DEFAULT 1
 EOF
@@ -1663,10 +1663,10 @@
   withval="$with_maketextfm_default"
   :
 else
-  enableval=yes
+  withval=yes
 fi
 
-if test $enableval = yes; then
+if test $withval = yes; then
   cat >> confdefs.h <<\EOF
 #define MAKE_TEX_TFM_BY_DEFAULT 1
 EOF
@@ -3503,7 +3503,7 @@
 ac_given_INSTALL="$INSTALL"
 
 trap 'rm -fr `echo "Makefile doc/Makefile lib/Makefile mpware/Makefile 
-          web2c/Makefile window/Makefile c-auto.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+          web2c/Makefile window/Makefile tie/Makefile c-auto.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
 EOF
 cat >> $CONFIG_STATUS <<EOF
 
@@ -3601,7 +3601,7 @@
 cat >> $CONFIG_STATUS <<EOF
 
 CONFIG_FILES=\${CONFIG_FILES-"Makefile doc/Makefile lib/Makefile mpware/Makefile 
-          web2c/Makefile window/Makefile"}
+          web2c/Makefile window/Makefile tie/Makefile"}
 EOF
 cat >> $CONFIG_STATUS <<\EOF
 for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
Index: texk/web2c/configure.in
diff -u texk/web2c/configure.in:1.1.1.1 texk/web2c/configure.in:1.2
--- texk/web2c/configure.in:1.1.1.1	Fri Jul 18 17:01:50 1997
+++ texk/web2c/configure.in	Tue Sep  2 11:27:46 1997
@@ -69,4 +69,4 @@
 
 dnl Generate `Makefile's, `config.status', and our header file.
 AC_OUTPUT(Makefile doc/Makefile lib/Makefile mpware/Makefile 
-          web2c/Makefile window/Makefile)
+          web2c/Makefile window/Makefile tie/Makefile)
Index: texk/web2c/etex.ch
diff -u /dev/null texk/web2c/etex.ch:1.1
--- /dev/null	Wed Nov  5 23:19:47 1997
+++ texk/web2c/etex.ch	Tue Sep  2 11:15:39 1997
@@ -0,0 +1,3414 @@
+% This is etex.ch in text format, as of October 26, 1996.
+% WEB change file containing code for various features extending TeX;
+% to be applied to tex.web (Version 3.14159) in order to define the
+% e-TeX program.
+
+% e-TeX is copyright (C) 1994,96 by the NTS team; all rights are reserved.
+% Copying of this file is authorized only if (1) you are a member of the
+% NTS team, or if (2) you make absolutely no changes to your copy.
+% (Programs such as PATCHWEB, TIE, or WEBMERGE allow the application of
+% several change files to tex.web; the master files tex.web and etex.ch
+% should stay intact.)
+
+% See etex_gen.tex for hints on how to install this program.
+% And see etripman.tex for details about how to validate it.
+
+% The TeX program is copyright (C) 1982 by D. E. Knuth.
+% TeX is a trademark of the American Mathematical Society.
+% e-TeX and NTS are trademarks of the NTS group.
+
+% All line numbers refer to TEX.WEB 3.14159 as of March 21, 1995.
+
+@x limbo l.1 - this is e-TeX
+% This program is copyright (C) 1982 by D. E. Knuth; all rights are reserved.
+% Copying of this file is authorized only if (1) you are D. E. Knuth, or if
+% (2) you make absolutely no changes to your copy. (The WEB system provides
+% for alterations via an auxiliary file; the master file should stay intact.)
+% See Appendix H of the WEB manual for hints on how to install this program.
+% And see Appendix A of the TRIP manual for details about how to validate it.
+
+% TeX is a trademark of the American Mathematical Society.
+% METAFONT is a trademark of Addison-Wesley Publishing Company.
+@y
+% e-TeX is copyright (C) 1994,96 by the NTS team; all rights are reserved.
+% Copying of this file is authorized only if (1) you are a member of the
+% NTS team, or if (2) you make absolutely no changes to your copy.
+% (Programs such as PATCHWEB, TIE, or WEBMERGE allow the application of
+% several change files to tex.web; the master files tex.web and etex.ch
+% should stay intact.)
+
+% See etex_gen.tex for hints on how to install this program.
+% And see etripman.tex for details about how to validate it.
+
+% e-TeX and NTS are trademarks of the NTS group.
+% TeX is a trademark of the American Mathematical Society.
+% METAFONT is a trademark of Addison-Wesley Publishing Company.
+
+% This program is directly derived from Donald E. Knuth's TeX;
+% the change history which follows and the reward offered for finders of
+% bugs refer specifically to TeX; they should not be taken as referring
+% to e-TeX, although the change history is relevant in that it
+% demonstrates the evolutionary path followed.  This program is not TeX;
+% that name is reserved strictly for the program which is the creation
+% and sole responsibility of Professor Knuth.
+@z
+%---------------------------------------
+@x limbo l.50 - e-TeX history
+% Although considerable effort has been expended to make the TeX program
+% correct and reliable, no warranty is implied; the author disclaims any
+% obligation or liability for damages, including but not limited to
+% special, indirect, or consequential damages arising out of or in
+% connection with the use or performance of this software. This work has
+% been a ``labor of love'' and the author hopes that users enjoy it.
+@y
+% A preliminary version of TeX--XeT was released in April 1992.
+% TeX--XeT version 1.0 was released in June 1992,
+%   version 1.1 prevented arith overflow in glue computation (Oct 1992).
+% A preliminary e-TeX version 0.95 was operational in March 1994.
+% Version 1.0beta was released in May 1995.
+% Version 1.01beta fixed bugs in just_copy and every_eof (December 1995).
+% Version 1.02beta allowed 256 mark classes (March 1996).
+% Version 1.1 changed \group{type,level} -> \currentgroup{type,level},
+%             first public release (October 1996).
+
+% Although considerable effort has been expended to make the e-TeX program
+% correct and reliable, no warranty is implied; the authors disclaim any
+% obligation or liability for damages, including but not limited to
+% special, indirect, or consequential damages arising out of or in
+% connection with the use or performance of this software. This work has
+% been a ``labor of love'' and the authors hope that users enjoy it.
+@z
+%---------------------------------------
+@x limbo l.61 - e-TeX logo, TeXXeT
+\let\mc=\ninerm % medium caps for names like SAIL
+@y
+\let\mc=\ninerm % medium caps for names like SAIL
+\def\eTeX{$\varepsilon$-\TeX}
+\font\revrm=xbmc10 % for right-to-left text
+% to generate xbmc10 (i.e., reflected cmbx10) use a file
+% xbmc10.mf containing:
+%+++++++++++++++++++++++++++++++++++++++++++++++++
+%     if unknown cmbase: input cmbase fi
+%     extra_endchar := extra_endchar &
+%       "currentpicture:=currentpicture " &
+%       "reflectedabout((.5[l,r],0),(.5[l,r],1));";
+%     input cmbx10
+%+++++++++++++++++++++++++++++++++++++++++++++++++
+\ifx\beginL\undefined % this is TeX
+  \def\XeT{X\kern-.125em\lower.5ex\hbox{E}\kern-.1667emT}
+  \def\TeXeT{\TeX-\hbox{\revrm \XeT}}      % for TeX-XeT
+  \def\TeXXeT{\TeX-\hbox{\revrm -\XeT}}    % for TeX--XeT
+\else % this is TeX--XeT (or TeX-XeT)
+  \ifx\TeXXeTstate\undefined \else % this is e-TeX
+    \TeXXeTstate=1
+  \fi
+  \def\TeXeT{\TeX-{\revrm\beginR\TeX\endR}}      % for TeX-XeT
+  \def\TeXXeT{\TeX-{\revrm\beginR\TeX-\endR}}    % for TeX--XeT
+\fi
+@z
+%---------------------------------------
+@x limbo l.64 - bug fix (print only changed modules)
+\def\pct!{{\char`\%}} % percent sign in ordinary text
+@y
+\def\pct!{{\char`\%}} % percent sign in ordinary text
+\def\grp{\.{\char'173...\char'175}}
+@z
+%---------------------------------------
+@x limbo l.80 - e-TeX basic
+\def\title{\TeX82}
+@y
+\def\title{\eTeX}
+% system dependent redefinitions of \title should come later
+% and should use:
+%    \toks0=\expandafter{\title}
+%    \edef\title{...\the\toks0...}
+\let\maybe=\iffalse % print only changed modules
+@z
+%---------------------------------------
+@x [1] m.1 l.91 - this is e-TeX
+This is \TeX, a document compiler intended to produce typesetting of high
+@y
+This is \eTeX, a program derived from and extending the capabilities of
+\TeX, a document compiler intended to produce typesetting of high
+@z
+%---------------------------------------
+@x [1] m.2 l.179 - e-TeX basic
+If this program is changed, the resulting system should not be called
+@y
+This program contains code for various features extending \TeX,
+therefore this program is called `\eTeX' and not
+@z
+%---------------------------------------
+@x [1] m.2 l.185 - e-TeX basic
+November 1984].
+@y
+November 1984].
+
+A similar test suite called the ``\.{e-TRIP} test'' is available for
+helping to determine whether a particular implementation deserves to be
+known as `\eTeX'.
+@z
+%---------------------------------------
+@x [1] m.2 l.187 - e-TeX basic
+@d banner=='This is TeX, Version 3.14159' {printed when \TeX\ starts}
+@y
+@d banner=='This is TeX, Version 3.14159' {printed when \TeX\ starts}
+@#
+@d eTeX_version_string=='3.14159-1.1' {current \eTeX\ version}
+@d eTeX_version=1 { \.{\\eTeXversion} }
+@d eTeX_revision==".1" { \.{\\eTeXrevision} }
+@#
+@d eTeX_banner=='This is e-TeX, Version ',eTeX_version_string
+  {printed when \eTeX\ starts}
+@#
+@d TEX==ETEX {change program name into |ETEX|}
+@#
+@d TeXXeT_code=0 {the \TeXXeT\ feature is optional}
+@#
+@d eTeX_states=1 {number of \eTeX\ state variables in |eqtb|}
+@z
+%---------------------------------------
+@x [5] m.61 l.1556 - e-TeX basic
+wterm(banner);
+@y
+wterm(eTeX_banner);
+@z
+%---------------------------------------
+@x [10] m.147 l.3069 - e-TeX TeXXeT
+the amount of surrounding space inserted by \.{\\mathsurround}.
+@y
+the amount of surrounding space inserted by \.{\\mathsurround}.
+
+In addition a |math_node| with |subtype>after| and |width=0| will be
+(ab)used to record a regular |math_node| reinserted after being
+discarded at a line break or one of the text direction primitives (
+\.{\\beginL}, \.{\\endL}, \.{\\beginR}, and \.{\\endR} ).
+@z
+%---------------------------------------
+@x [10] m.147 l.3073 - e-TeX TeXXeT
+@d after=1 {|subtype| for math node that winds up a formula}
+@y
+@d after=1 {|subtype| for math node that winds up a formula}
+@#
+@d M_code=2
+@d begin_M_code=M_code+before {|subtype| for \.{\\beginM} node}
+@d end_M_code=M_code+after {|subtype| for \.{\\endM} node}
+@d L_code=4
+@d begin_L_code=L_code+begin_M_code {|subtype| for \.{\\beginL} node}
+@d end_L_code=L_code+end_M_code {|subtype| for \.{\\endL} node}
+@d R_code=L_code+L_code
+@d begin_R_code=R_code+begin_M_code {|subtype| for \.{\\beginR} node}
+@d end_R_code=R_code+end_M_code {|subtype| for \.{\\endR} node}
+@#
+@d end_LR(#)==odd(subtype(#))
+@d end_LR_type(#)==(L_code*(subtype(#) div L_code)+end_M_code)
+@d begin_LR_type(#)==(#-after+before)
+@z
+%---------------------------------------
+@x [12] m.175 l.3546 - e-TeX TeXXeT
+math_node: print_char("$");
+@y
+math_node: if subtype(p)>=L_code then print("[]")
+  else print_char("$");
+@z
+%---------------------------------------
+@x [12] m.184 l.3713 - e-TeX TeXXeT
+    begin print(", shifted "); print_scaled(shift_amount(p));
+    end;
+@y
+    begin print(", shifted "); print_scaled(shift_amount(p));
+    end;
+  if eTeX_ex then @<Display if this box is never to be reversed@>;
+@z
+%---------------------------------------
+@x [12] m.192 l.3811 - e-TeX TeXXeT
+begin print_esc("math");
+@y
+if subtype(p)>after then
+  begin if end_LR(p) then print_esc("end")
+  else print_esc("begin");
+  if subtype(p)>R_code then print_char("R")
+  else if subtype(p)>L_code then print_char("L")
+  else print_char("M");
+  end else
+begin print_esc("math");
+@z
+%---------------------------------------
+@x [12] m.196 l.3844 - e-TeX marks
+begin print_esc("mark"); print_mark(mark_ptr(p));
+@y
+begin print_esc("mark");
+if subtype(p)>min_quarterword then
+  begin print_char("s"); print_int(qo(subtype(p)));
+  end;
+print_mark(mark_ptr(p));
+@z
+%---------------------------------------
+@x [15] m.208 l.4091 - e-TeX TeXXeT
+@d valign=33 {vertical table alignment ( \.{\\valign} )}
+@y
+@d valign=33 {vertical table alignment ( \.{\\valign} )}
+  {or text direction directives ( \.{\\beginL}, etc.~)}
+@z
+%---------------------------------------
+@x [15] m.208 l.4107 - e-TeX middle
+@d left_right=49 {variable delimiter ( \.{\\left}, \.{\\right} )}
+@y
+@d left_right=49 {variable delimiter ( \.{\\left}, \.{\\right} )}
+  {or \.{\\middle}}
+@z
+%---------------------------------------
+@x [15] m.209 l.4151 - e-TeX basic
+  \.{\\insertpenalties} )}
+@y
+  \.{\\insertpenalties} )}
+  {or \.{\\interactionmode}}
+@z
+%---------------------------------------
+@x [15] m.209 l.4163 - e-TeX protected
+@d prefix=93 {qualify a definition ( \.{\\global}, \.{\\long}, \.{\\outer} )}
+@y
+@d prefix=93 {qualify a definition ( \.{\\global}, \.{\\long}, \.{\\outer} )}
+  {or \.{\\protected}}
+@z
+%---------------------------------------
+@x [15] m.209 l.4166 - e-TeX read_line
+@d read_to_cs=96 {read into a control sequence ( \.{\\read} )}
+@y
+@d read_to_cs=96 {read into a control sequence ( \.{\\read} )}
+  {or \.{\\readline}}
+@z
+%---------------------------------------
+@x [15] m.210 l.4181 - e-TeX scan_tokens
+@d input=max_command+4 {input a source file ( \.{\\input}, \.{\\endinput} )}
+@y
+@d input=max_command+4 {input a source file ( \.{\\input}, \.{\\endinput} )}
+  {or \.{\\scantokens}}
+@z
+%---------------------------------------
+@x [15] m.210 l.4186 - e-TeX unexpanded
+@d the=max_command+9 {expand an internal quantity ( \.{\\the} )}
+@y
+@d the=max_command+9 {expand an internal quantity ( \.{\\the} )}
+  {or \.{\\unexpanded}, \.{\\detokenize}}
+@z
+%---------------------------------------
+@x [16] m.212 l.4289 - e-TeX basic
+user's output routine.
+@y
+user's output routine.
+
+A seventh quantity, |eTeX_aux|, is used by the extended features \eTeX.
+In vertical modes it is known as |LR_save| and holds the LR stack when a
+paragraph is interrupted by a displayed formula.  In display math mode
+it is known as |LR_box| and holds a pointer to a prototype box for the
+display.  In math mode it is known as |delim_ptr| and points to the most
+recent |left_noad| or |middle_noad| of a |math_left_group|.
+@z
+%---------------------------------------
+@x [16] m.212 l.4304 - e-TeX basic
+  @!head_field,@!tail_field: pointer;
+@y
+  @!head_field,@!tail_field: pointer;
+  @!eTeX_aux_field: pointer;
+@z
+%---------------------------------------
+@x [16] m.213 l.4311 - e-TeX basic
+@d tail==cur_list.tail_field {final node on current list}
+@y
+@d tail==cur_list.tail_field {final node on current list}
+@d eTeX_aux==cur_list.eTeX_aux_field {auxiliary data for \eTeX}
+@d LR_save==eTeX_aux {LR stack when a paragraph is interrupted}
+@d LR_box==eTeX_aux {prototype box for display}
+@d delim_ptr==eTeX_aux {most recent left or right noad of a math left group}
+@z
+%---------------------------------------
+@x [16] m.215 l.4342 - e-TeX basic
+mode:=vmode; head:=contrib_head; tail:=contrib_head;
+@y
+mode:=vmode; head:=contrib_head; tail:=contrib_head;
+eTeX_aux:=null;
+@z
+%---------------------------------------
+@x [16] m.216 l.4358 push_nest - e-TeX basic
+incr(nest_ptr); head:=get_avail; tail:=head; prev_graf:=0; mode_line:=line;
+@y
+incr(nest_ptr); head:=get_avail; tail:=head; prev_graf:=0; mode_line:=line;
+eTeX_aux:=null;
+@z
+%---------------------------------------
+@x [17] m.230 l.4720 - e-TeX basic
+@d err_help_loc=local_base+9 {points to token list for \.{\\errhelp}}
+@d toks_base=local_base+10 {table of 256 token list registers}
+@y
+@d every_eof_loc=local_base+9 {points to token list for \.{\\everyeof}}
+@d err_help_loc=local_base+10 {points to token list for \.{\\errhelp}}
+@d toks_base=local_base+11 {table of 256 token list registers}
+@z
+%---------------------------------------
+@x [17] m.231 l.4787 - e-TeX basic
+  othercases print_esc("errhelp")
+@y
+  @/@<Cases of |assign_toks| for |print_cmd_chr|@>@/
+  othercases print_esc("errhelp")
+@z
+%---------------------------------------
+@x [17] m.236 l.4955 - e-TeX basic
+@d count_base=int_base+int_pars {256 user \.{\\count} registers}
+@y
+@d tracing_assigns_code=int_pars {show assignments}
+@d tracing_groups_code=int_pars+1 {show save/restore groups}
+@d tracing_ifs_code=int_pars+2 {show conditionals}
+@d tracing_scan_tokens_code=int_pars+3 {show pseudo file open and close}
+@d pre_display_direction_code=int_pars+4 {text direction preceding a display}
+@d eTeX_state_code=int_pars+5 {\eTeX\ state variables}
+@d count_base=int_base+eTeX_state_code+eTeX_states
+  {256 user \.{\\count} registers}
+@z
+%---------------------------------------
+@x [17] m.236 l.5016 - e-TeX basic
+@d error_context_lines==int_par(error_context_lines_code)
+@y
+@d error_context_lines==int_par(error_context_lines_code)
+@d tracing_assigns==int_par(tracing_assigns_code)
+@d tracing_groups==int_par(tracing_groups_code)
+@d tracing_ifs==int_par(tracing_ifs_code)
+@d tracing_scan_tokens==int_par(tracing_scan_tokens_code)
+@d pre_display_direction==int_par(pre_display_direction_code)
+@z
+%---------------------------------------
+@x [17] m.237 l.5081 print_param - e-TeX basic
+othercases print("[unknown integer parameter!]")
+@y
+@/@<Cases for |print_param|@>@/
+othercases print("[unknown integer parameter!]")
+@z
+%---------------------------------------
+@x [18] m.264 l.5612 primitive - e-TeX basic
+@!j:small_number; {index into |buffer|}
+@y
+@!j:0..buf_size; {index into |buffer|}
+@z
+%---------------------------------------
+@x [18] m.264 l.5616 primitive - e-TeX basic
+    {we will move |s| into the (empty) |buffer|}
+  for j:=0 to l-1 do buffer[j]:=so(str_pool[k+j]);
+  cur_val:=id_lookup(0,l); {|no_new_control_sequence| is |false|}
+@y
+    {we will move |s| into the (possibly non-empty) |buffer|}
+  if first+l>buf_size+1 then
+      overflow("buffer size",buf_size);
+@:TeX capacity exceeded buffer size}{\quad buffer size@>
+  for j:=0 to l-1 do buffer[first+j]:=so(str_pool[k+j]);
+  cur_val:=id_lookup(first,l); {|no_new_control_sequence| is |false|}
+@z
+%---------------------------------------
+@x [18] m.266 l.5741 - e-TeX cond
+expand_after: print_esc("expandafter");
+@y
+expand_after: if chr_code=0 then print_esc("expandafter")
+  @<Cases of |expandafter| for |print_cmd_chr|@>;
+@z
+%---------------------------------------
+@x [18] m.266 l.5747 - e-TeX marks
+mark: print_esc("mark");
+@y
+mark: begin print_esc("mark");
+  if chr_code>0 then print_char("s");
+  end;
+@z
+%---------------------------------------
+@x [18] m.266 l.5758 - e-TeX read_line
+read_to_cs: print_esc("read");
+@y
+read_to_cs: if chr_code=0 then print_esc("read")
+  @<Cases of |read| for |print_cmd_chr|@>;
+@z
+%---------------------------------------
+@x [18] m.266 l.5763 - e-TeX unexpanded
+the: print_esc("the");
+@y
+the: if chr_code=0 then print_esc("the")
+  @<Cases of |the| for |print_cmd_chr|@>;
+@z
+%---------------------------------------
+@x [18] m.266 l.5766 - e-TeX TeXXeT
+valign: print_esc("valign");
+@y
+valign: if chr_code=0 then print_esc("valign")@/
+  @<Cases of |valign| for |print_cmd_chr|@>;
+@z
+%---------------------------------------
+@x [19] m.268 l.5820 - e-TeX tracing
+the entries for that group.
+@y
+the entries for that group.
+Furthermore, in extended \eTeX\ mode, |save_stack[p-1]| contains the
+source line number at which the current level of grouping was entered.
+@z
+%---------------------------------------
+@x [19] m.268 l.5830 - e-TeX basic
+@d level_boundary=3 {|save_type| corresponding to beginning of group}
+@y
+@d level_boundary=3 {|save_type| corresponding to beginning of group}
+
+@p@t\4@>@<Declare \eTeX\ procedures for tracing and input@>
+@z
+%---------------------------------------
+@x [19] m.274 l.5916 new_save_level - e-TeX tracing
+begin check_full_save_stack;
+@y
+begin check_full_save_stack;
+if eTeX_ex then
+  begin saved(0):=line; incr(save_ptr);
+  end;
+@z
+%---------------------------------------
+@x [19] m.274 l.5923 new_save_level - e-TeX tracing
+cur_boundary:=save_ptr; incr(cur_level); incr(save_ptr); cur_group:=c;
+@y
+cur_boundary:=save_ptr; cur_group:=c;
+@!stat if tracing_groups>0 then group_trace(false);@+tats@;@/
+incr(cur_level); incr(save_ptr);
+@z
+%---------------------------------------
+@x [19] m.277 l.5967 eq_define - e-TeX tracing
+begin if eq_level(p)=cur_level then eq_destroy(eqtb[p])
+else if cur_level>level_one then eq_save(p,eq_level(p));
+eq_level(p):=cur_level; eq_type(p):=t; equiv(p):=e;
+@y
+begin @!stat if tracing_assigns>0 then restore_trace(p,"changing");
+tats@;@/
+begin if eq_level(p)=cur_level then eq_destroy(eqtb[p])
+else if cur_level>level_one then eq_save(p,eq_level(p));
+eq_level(p):=cur_level; eq_type(p):=t; equiv(p):=e;
+end;
+@!stat if tracing_assigns>0 then restore_trace(p,"into");
+tats@;@/
+@z
+%---------------------------------------
+@x [19] m.278 l.5980 eq_word_define - e-TeX tracing
+eqtb[p].int:=w;
+@y
+@!stat if tracing_assigns>0 then restore_trace(p,"changing");
+tats@;@/
+eqtb[p].int:=w;
+@!stat if tracing_assigns>0 then restore_trace(p,"into");
+tats@;@/
+@z
+%---------------------------------------
+@x [19] m.279 l.5990 geq_define - e-TeX tracing
+begin eq_destroy(eqtb[p]);
+eq_level(p):=level_one; eq_type(p):=t; equiv(p):=e;
+@y
+begin @!stat if tracing_assigns>0 then restore_trace(p,"globally changing");
+tats@;@/
+begin eq_destroy(eqtb[p]);
+eq_level(p):=level_one; eq_type(p):=t; equiv(p):=e;
+end;
+@!stat if tracing_assigns>0 then restore_trace(p,"into");
+tats@;@/
+@z
+%---------------------------------------
+@x [19] m.279 l.5995 geq_word_define - e-TeX tracing
+begin eqtb[p].int:=w; xeq_level[p]:=level_one;
+@y
+begin @!stat if tracing_assigns>0 then restore_trace(p,"globally changing");
+tats@;@/
+begin eqtb[p].int:=w; xeq_level[p]:=level_one;
+end;
+@!stat if tracing_assigns>0 then restore_trace(p,"into");
+tats@;@/
+@z
+%---------------------------------------
+@x [19] m.281 l.6012 - e-TeX tracing
+@p@t\4@>@<Declare the procedure called |restore_trace|@>@;@/
+@y
+@p
+@z
+%---------------------------------------
+@x [19] m.282 l.6041 - e-TeX tracing
+done: cur_group:=save_level(save_ptr); cur_boundary:=save_index(save_ptr)
+@y
+done: @!stat if tracing_groups>0 then group_trace(true);@+tats@;@/
+cur_group:=save_level(save_ptr); cur_boundary:=save_index(save_ptr);
+if eTeX_ex then decr(save_ptr)
+@z
+%---------------------------------------
+@x [19] m.284 l.6067 - e-TeX tracing
+@ @<Declare the procedure called |restore_trace|@>=
+@y
+@ @<Declare \eTeX\ procedures for tracing and input@>=
+@z
+%---------------------------------------
+@x [20] m.289 l.6155 - e-TeX protected
+@d end_match_token=@'7000 {$2^8\cdot|end_match|$}
+@y
+@d end_match_token=@'7000 {$2^8\cdot|end_match|$}
+@d protected_token=@'7001 {$2^8\cdot|end_match|+1$}
+@z
+%---------------------------------------
+@x [20] m.294 l.6280 - e-TeX protected
+end_match: print("->");
+@y
+end_match: if c=0 then print("->");
+@z
+%---------------------------------------
+@x [20] m.296 l.6301 print_meaning - e-TeX marks
+else if cur_cmd=top_bot_mark then
+  begin print_char(":"); print_ln;
+@y
+else if (cur_cmd=top_bot_mark)and(cur_chr<marks_code) then
+  begin mark_class:=0; print_char(":"); print_ln;
+@z
+%---------------------------------------
+@x [21] m.298 l.6375 print_cmd_chr - e-TeX protected
+procedure print_cmd_chr(@!cmd:quarterword;@!chr_code:halfword);
+@y
+procedure print_cmd_chr(@!cmd:quarterword;@!chr_code:halfword);
+var n:integer; {temp variable}
+@z
+%---------------------------------------
+@x [21] m.299 l.6394 show_cur_cmd_chr - e-TeX tracing
+@p procedure show_cur_cmd_chr;
+@y
+@p procedure show_cur_cmd_chr;
+var n:integer; {level of \.{\\if...\\fi} nesting}
+@!l:integer; {line where \.{\\if} started}
+@!p:pointer;
+@z
+%---------------------------------------
+@x [21] m.299 l.6399 show_cur_cmd_chr - e-TeX tracing
+print_cmd_chr(cur_cmd,cur_chr); print_char("}");
+@y
+print_cmd_chr(cur_cmd,cur_chr);
+if tracing_ifs>0 then
+  if cur_cmd>=if_test then if cur_cmd<=fi_or_else then
+    begin print(": ");
+    if cur_cmd=fi_or_else then
+      begin print_cmd_chr(if_test,cur_if); print_char(" ");
+      n:=0; l:=if_line;
+      end
+    else  begin n:=1; l:=line;
+      end;
+    p:=cond_ptr;
+    while p<>null do
+      begin incr(n); p:=link(p);
+      end;
+    print_int(n);
+    if l<>0 then
+      begin print(" on line "); print_int(l);
+      end;
+    end;
+print_char("}");
+@z
+%---------------------------------------
+@x [22] m.303 l.6475 show_context - e-TeX scan_tokens
+the terminal, under control of the procedure |read_toks|.)
+@y
+the terminal, under control of the procedure |read_toks|.)
+Finally |18<=name<=19| indicates that we are reading a pseudo file
+created by the \.{\\scantokens} command.
+@z
+%---------------------------------------
+@x [22] m.304 l.6538 - e-TeX every_eof
+@!line_stack : array[1..max_in_open] of integer;
+@y
+@!line_stack : array[1..max_in_open] of integer;
+@!eof_seen : array[1..max_in_open] of boolean; {has eof been seen?}
+@z
+%---------------------------------------
+@x [22] m.307 l.6692 - e-TeX basic
+@d mark_text=14 {|token_type| code for \.{\\topmark}, etc.}
+@d write_text=15 {|token_type| code for \.{\\write}}
+@y
+@d every_eof_text=14 {|token_type| code for \.{\\everyeof}}
+@d mark_text=15 {|token_type| code for \.{\\topmark}, etc.}
+@d write_text=16 {|token_type| code for \.{\\write}}
+@z
+%---------------------------------------
+@x [22] m.311 l.6749 show_context - e-TeX scan_tokens
+    if (name>17) or (base_ptr=0) then bottom_line:=true;
+@y
+    if (name>19) or (base_ptr=0) then bottom_line:=true;
+@z
+%---------------------------------------
+@x [22] m.313 l.6794 - e-TeX scan_tokens
+else  begin print_nl("l."); print_int(line);
+@y
+else if index<>in_open then {input from a pseudo file}
+  begin print_nl("l."); print_int(line_stack[index+1]);
+  end
+else  begin print_nl("l."); print_int(line);
+@z
+%---------------------------------------
+@x [22] m.314 l.6814 - e-TeX basic
+every_cr_text: print_nl("<everycr> ");
+@y
+every_cr_text: print_nl("<everycr> ");
+every_eof_text: print_nl("<everyeof> ");
+@z
+%---------------------------------------
+@x [23] m.328 l.7037 begin_file_reading - e-TeX every_eof
+incr(in_open); push_input; index:=in_open;
+@y
+incr(in_open); push_input; index:=in_open;
+eof_seen[index]:=false;
+@z
+%---------------------------------------
+@x [23] m.329 l.7047 end_file_reading - e-TeX scan_tokens
+if name>17 then a_close(cur_file); {forget it}
+@y
+if (name=18)or(name=19) then pseudo_close else
+if name>17 then a_close(cur_file); {forget it}
+@z
+%---------------------------------------
+@x [24] m.362 l.7538 - e-TeX scan_tokens, every_eof
+if not force_eof then
+@y
+if not force_eof then
+  if name<=19 then
+    begin if pseudo_input then {not end of file}
+      firm_up_the_line {this sets |limit|}
+    else if (every_eof<>null)and not eof_seen[index] then
+      begin limit:=first-1; eof_seen[index]:=true; {fake one empty line}
+      begin_token_list(every_eof,every_eof_text); goto restart;
+      end
+    else force_eof:=true;
+    end
+  else
+@z
+%---------------------------------------
+@x [24] m.362 l.7541 - e-TeX every_eof
+  else force_eof:=true;
+@y
+  else if (every_eof<>null)and not eof_seen[index] then
+    begin limit:=first-1; eof_seen[index]:=true; {fake one empty line}
+    begin_token_list(every_eof,every_eof_text); goto restart;
+    end
+  else force_eof:=true;
+@z
+%---------------------------------------
+@x [24] m.362 l.7544 - e-TeX scan_tokens
+  begin print_char(")"); decr(open_parens);
+  update_terminal; {show user that file has been read}
+@y
+  begin if name>=19 then
+  begin print_char(")"); decr(open_parens);
+  update_terminal; {show user that file has been read}
+  end;
+@z
+%---------------------------------------
+@x [25] m.366 l.7630 - e-TeX basic
+@t\4@>@<Declare the procedure called |insert_relax|@>@;@/
+@y
+@t\4@>@<Declare the procedure called |insert_relax|@>@;@/
+@t\4@>@<Declare \eTeX\ procedures for expanding and scanning@>@;@/
+@z
+%---------------------------------------
+@x [25] m.366 l.7637 expand - e-TeX cond
+procedure expand;
+@y
+procedure expand;
+label reswitch;
+@z
+%---------------------------------------
+@x [25] m.366 l.7648 expand - e-TeX cond
+if cur_cmd<call then @<Expand a nonmacro@>
+@y
+reswitch:
+if cur_cmd<call then @<Expand a nonmacro@>
+@z
+%---------------------------------------
+@x [25] m.367 l.7659 - e-TeX cond
+expand_after:@<Expand the token after the next token@>;
+@y
+expand_after:if cur_chr=0 then @<Expand the token after the next token@>
+  else @<Negate a boolean conditional and |goto reswitch|@>;
+@z
+%---------------------------------------
+@x [25] m.377 l.7779 - e-TeX scan_tokens
+input: if chr_code=0 then print_esc("input")@+else print_esc("endinput");
+@y
+input: if chr_code=0 then print_esc("input")
+  @/@<Cases of |input| for |print_cmd_chr|@>@/
+  else print_esc("endinput");
+@z
+%---------------------------------------
+@x [25] m.378 l.7782 - e-TeX scan_tokens
+if cur_chr>0 then force_eof:=true
+@y
+if cur_chr=1 then force_eof:=true
+@/@<Cases for |input|@>@/
+@z
+%---------------------------------------
+@x [25] m.382 l.7835 - e-TeX marks
+array by symbolic names |top_mark|, etc. The value of |top_mark| is either
+@y
+array by symbolic names |top_mark|, etc.\ (depending on a local or
+global variable |0<=mark_class<=255|). The value of |top_mark| is either
+@z
+%---------------------------------------
+@x [25] m.382 l.7838 - e-TeX marks
+@d top_mark_code=0 {the mark in effect at the previous page break}
+@y
+@d marks_code==5 {add this for \.{\\topmarks} etc.}
+@d cur_mark==cur_marks[mark_class]
+@#
+@d top_mark_code=0 {the mark in effect at the previous page break}
+@z
+%---------------------------------------
+@x [25] m.382 l.7850 - e-TeX marks
+@!cur_mark:array[top_mark_code..split_bot_mark_code] of pointer;
+@y
+@!mark_class:eight_bits; {a mark class}
+@!cur_marks:array[0..255,top_mark_code..split_bot_mark_code] of pointer;
+@z
+%---------------------------------------
+@x [25] m.383 l.7854 - e-TeX marks
+top_mark:=null; first_mark:=null; bot_mark:=null;
+split_first_mark:=null; split_bot_mark:=null;
+@y
+for mark_class:=0 to 255 do
+begin
+top_mark:=null; first_mark:=null; bot_mark:=null;
+split_first_mark:=null; split_bot_mark:=null;
+end;
+@z
+%---------------------------------------
+@x [25] m.385 l.7870 - e-TeX marks
+top_bot_mark: case chr_code of
+@y
+top_bot_mark: begin case (chr_code mod marks_code) of
+@z
+%---------------------------------------
+@x [25] m.385 l.7876 - e-TeX marks
+  endcases;
+@y
+  endcases;
+  if chr_code>=marks_code then print_char("s");
+  end;
+@z
+%---------------------------------------
+@x [25] m.386 l.7882 - e-TeX marks
+begin if cur_mark[cur_chr]<>null then
+  begin_token_list(cur_mark[cur_chr],mark_text);
+@y
+begin if cur_chr>=marks_code then
+  begin t:=cur_chr mod marks_code; scan_eight_bit_int; cur_chr:=t;
+  mark_class:=cur_val;
+  end
+else mark_class:=0;
+begin if cur_mark[cur_chr]<>null then
+  begin_token_list(cur_mark[cur_chr],mark_text);
+end;
+@z
+%---------------------------------------
+@x [25] m.389 l.7945 macro_call - e-TeX protected
+if info(r)<>end_match_token then
+@y
+if info(r)=protected_token then r:=link(r);
+if info(r)<>end_match_token then
+@z
+%---------------------------------------
+@x [26] m.416 l.8390 - e-TeX last_node_type
+|glue_val|, |input_line_no_code|, or |badness_code|.
+
+@d input_line_no_code=glue_val+1 {code for \.{\\inputlineno}}
+@d badness_code=glue_val+2 {code for \.{\\badness}}
+@y
+|glue_val|, |last_node_type_code|, |input_line_no_code|, |badness_code|,
+|eTeX_version_code|, |group_level_code|, or |group_type_code|.
+
+@d last_node_type_code=glue_val+1 {code for \.{\\lastnodetype}}
+@d input_line_no_code=glue_val+2 {code for \.{\\inputlineno}}
+@d badness_code=glue_val+3 {code for \.{\\badness}}
+@z
+%---------------------------------------
+@x [26] m.417 l.8425 - e-TeX interaction_mode
+@+else print_esc("insertpenalties");
+@y
+@/@<Cases of |set_page_int| for |print_cmd_chr|@>@/
+@+else print_esc("insertpenalties");
+@z
+%---------------------------------------
+@x [26] m.417 l.8434 - e-TeX basic
+  othercases print_esc("badness")
+@y
+  @/@<Cases of |last_item| for |print_cmd_chr|@>@/
+  othercases print_esc("badness")
+@z
+%---------------------------------------
+@x [26] m.419 l.8457 - e-TeX interaction_mode
+begin if m=0 then cur_val:=dead_cycles@+else cur_val:=insert_penalties;
+@y
+begin if m=0 then cur_val:=dead_cycles
+@/@<Cases for `Fetch the |dead_cycles| or the |insert_penalties|'@>@/
+else cur_val:=insert_penalties;
+@z
+%---------------------------------------
+@x [26] m.424 l.8493 - e-TeX TeXXeT
+implemented. The reference count for \.{\\lastskip} will be updated later.
+@y
+implemented. The reference count for \.{\\lastskip} will be updated later.
+A final \.{\\endM} node is temporarily removed.
+@z
+%---------------------------------------
+@x [26] m.424 l.8499 - e-TeX last_node_type
+if cur_chr>glue_val then
+  begin if cur_chr=input_line_no_code then cur_val:=line
+@y
+if cur_chr>last_node_type_code then
+  begin if cur_chr=input_line_no_code then cur_val:=line
+  @/@<Cases for `Fetch an item in the current mode'@>@/
+@z
+%---------------------------------------
+@x [26] m.424 l.8505 - e-TeX last_node_type
+  cur_val_level:=cur_chr;
+@y
+  if cur_chr=last_node_type_code then
+    begin cur_val:=int_val;
+    if (tail=head)or(mode=0) then cur_val:=-1;
+    end
+  else cur_val_level:=cur_chr;
+@z
+%---------------------------------------
+@x [26] m.424 l.8507 - e-TeX TeXXeT
+    case cur_chr of
+@y
+    begin if (type(tail)=math_node)and(subtype(tail)=end_M_code) then
+      remove_end_M;
+    case cur_chr of
+@z
+%---------------------------------------
+@x [26] m.424 l.8513 - e-TeX last_node_type
+      end;
+@y
+      end;
+    last_node_type_code:
+      if (type(tail)<>math_node)or(subtype(tail)<>end_M_code) then
+        if type(tail)<=unset_node then cur_val:=type(tail)+1
+        else cur_val:=unset_node+2;
+@z
+%---------------------------------------
+@x [26] m.424 l.8514 - e-TeX TeXXeT
+    end {there are no other cases}
+@y
+    end; {there are no other cases}
+    if LR_temp<>null then insert_end_M;
+    end
+@z
+%---------------------------------------
+@x [26] m.424 l.8519 - e-TeX last_node_type
+    glue_val: if last_glue<>max_halfword then cur_val:=last_glue;
+@y
+    glue_val: if last_glue<>max_halfword then cur_val:=last_glue;
+    last_node_type_code: cur_val:=last_node_type;
+@z
+%---------------------------------------
+@x [27] m.464 l.9129 - e-TeX basic
+@p function str_toks(@!b:pool_pointer):pointer;
+@y
+@p @t\4@>@<Declare \eTeX\ procedures for token lists@>@;@/
+function str_toks(@!b:pool_pointer):pointer;
+@z
+%---------------------------------------
+@x [27] m.465 l.9154 the_toks - e-TeX unexpanded
+@p function the_toks:pointer;
+@y
+@p function the_toks:pointer;
+label exit;
+@z
+%---------------------------------------
+@x [27] m.465 l.9158 the_toks - e-TeX unexpanded
+begin get_x_token; scan_something_internal(tok_val,false);
+@y
+@!c:small_number; {value of |cur_chr|}
+begin @<Handle \.{\\unexpanded} or \.{\\detokenize} and |return|@>;@/
+get_x_token; scan_something_internal(tok_val,false);
+@z
+%---------------------------------------
+@x [27] m.465 l.9172 the_toks - e-TeX unexpanded
+end;
+@y
+exit:end;
+@z
+%---------------------------------------
+@x [27] m.469 l.9223 - e-TeX basic
+  othercases print_esc("jobname")
+@y
+  @/@<Cases of |convert| for |print_cmd_chr|@>@/
+  othercases print_esc("jobname")
+@z
+%---------------------------------------
+@x [27] m.470 l.9232 conv_toks - e-TeX basic
+@!c:number_code..job_name_code; {desired type of conversion}
+@y
+@!c:small_number; {desired type of conversion}
+@z
+%---------------------------------------
+@x [27] m.471 l.9249 - e-TeX basic
+end {there are no other cases}
+@y
+@/@<Cases of `Scan the argument for command |c|'@>@/
+end {there are no other cases}
+@z
+%---------------------------------------
+@x [27] m.472 l.9265 - e-TeX basic
+end {there are no other cases}
+@y
+@/@<Cases of `Print the result of command |c|'@>@/
+end {there are no other cases}
+@z
+%---------------------------------------
+@x [27] m.478 l.9374 - e-TeX protected
+  if cur_cmd<=max_command then goto done2;
+@y
+  if cur_cmd>=call then
+    if info(link(cur_chr))=protected_token then
+      begin cur_cmd:=relax; cur_chr:=no_expand_flag;
+      end;
+  if cur_cmd<=max_command then goto done2;
+@z
+%---------------------------------------
+@x [27] m.482 l.9422 read_toks - e-TeX read_line
+@p procedure read_toks(@!n:integer;@!r:pointer);
+@y
+@p procedure read_toks(@!n:integer;@!r:pointer;@!j:halfword);
+@z
+%---------------------------------------
+@x [27] m.483 l.9448 - e-TeX read_line
+loop@+  begin get_token;
+@y
+@<Handle \.{\\readline} and |goto done|@>;@/
+loop@+  begin get_token;
+@z
+%---------------------------------------
+@x [27] m.486 l.9489 - e-TeX read_line
+    print_err("File ended within "); print_esc("read");
+@y
+    print_err("File ended within "); print_cmd_chr(read_to_cs,j);
+@.File ended within \\readline@>
+@z
+%---------------------------------------
+@x [28] m.487 l.9500 - e-TeX cond
+@d if_char_code=0 { `\.{\\if}' }
+@y
+@d unless_code=32 {amount added for `\.{\\unless}' prefix}
+@#
+@d if_char_code=0 { `\.{\\if}' }
+@z
+%---------------------------------------
+@x [28] m.488 l.9555 - e-TeX cond
+if_test: case chr_code of
+@y
+if_test: begin if chr_code>=unless_code then print_esc("unless");
+case chr_code mod unless_code of
+@z
+%---------------------------------------
+@x [28] m.488 l.9572 - e-TeX cond
+  othercases print_esc("if")
+  endcases;
+@y
+  @/@<Cases of |if_test| for |print_cmd_chr|@>@/
+  othercases print_esc("if")
+  endcases;
+end;
+@z
+%---------------------------------------
+@x [28] m.494 l.9646 pass_text - e-TeX tracing
+done: scanner_status:=save_scanner_status;
+@y
+done: scanner_status:=save_scanner_status;
+if tracing_ifs>0 then show_cur_cmd_chr;
+@z
+%---------------------------------------
+@x [28] m.498 l.9699 conditional - e-TeX cond
+begin @<Push the condition stack@>;@+save_cond_ptr:=cond_ptr;this_if:=cur_chr;@/
+@<Either process \.{\\ifcase} or set |b| to the value of a boolean condition@>;
+@y
+@!is_unless:boolean; {was this if preceded by `\.{\\unless}' ?}
+begin if tracing_ifs>0 then if tracing_commands<=1 then show_cur_cmd_chr;
+@<Push the condition stack@>;@+save_cond_ptr:=cond_ptr;
+is_unless:=(cur_chr>=unless_code); this_if:=cur_chr mod unless_code;@/
+@<Either process \.{\\ifcase} or set |b| to the value of a boolean condition@>;
+if is_unless then b:=not b;
+@z
+%---------------------------------------
+@x [28] m.501 l.9742 - e-TeX cond
+if_false_code: b:=false;
+@y
+if_false_code: b:=false;
+@/@<Cases for |conditional|@>@/
+@z
+%---------------------------------------
+@x [28] m.510 l.9871 - e-TeX cond
+if cur_chr>if_limit then
+@y
+begin if tracing_ifs>0 then if tracing_commands<=1 then show_cur_cmd_chr;
+if cur_chr>if_limit then
+@z
+%---------------------------------------
+@x [28] m.510 l.9882 - e-TeX cond
+  end
+@y
+  end;
+end
+@z
+%---------------------------------------
+@x [29] m.536 l.10324 - e-TeX basic
+begin wlog(banner);
+@y
+begin wlog(eTeX_banner);
+@z
+%---------------------------------------
+@x [29] m.536 l.10331 - e-TeX basic
+end
+@y
+wlog_cr; wlog('entering ');
+if eTeX_ex then wlog('extended') else wlog('compatibility');
+wlog(' mode');
+end
+@z
+%---------------------------------------
+@x [32] m.616 l.12238 - e-TeX TeXXeT
+this is essentially the depth of |push| commands in the \.{DVI} output.
+@y
+this is essentially the depth of |push| commands in the \.{DVI} output.
+
+For mixed direction text (\TeXXeT) the current text direction is called
+|cur_dir|. As the box being shipped out will never be used again and
+soon be recycled, we can simply reverse any R-text (i.e., right-to-left)
+segments of hlist nodes as well as complete hlist nodes embedded in such
+segments. Moreover this can be done iteratively rather than recursively.
+There are, however, two complications related to leaders that require
+some additional bookkeeping: (1)~One and the same hlist node might be
+used more than once (but never inside both L- and R-text); and
+(2)~leader boxes inside hlists must be aligned with respect to the left
+edge of the original hlist.
+
+A math node is changed into a kern node whenever the text direction
+remains the same, it is replaced by an |edge_node| if the text direction
+changes; the subtype of an an |hlist_node| inside R-text is changed to
+|reversed| once its hlist has been reversed.
+@!@^data structure assumptions@>
+@z
+%---------------------------------------
+@x [32] m.616 l.12240 - e-TeX TeXXeT
+@d synch_h==if cur_h<>dvi_h then
+@y
+@d reversed=min_quarterword+1 {subtype for an |hlist_node| whose hlist
+  has been reversed}
+@d dlist=min_quarterword+2 {subtype for an |hlist_node| from display math mode}
+@d left_to_right=0
+@d right_to_left=1
+@d reflected==1-cur_dir {the opposite of |cur_dir|}
+@#
+@d synch_h==if cur_h<>dvi_h then
+@z
+%---------------------------------------
+@x [32] m.619 l.12300 hlist_out - e-TeX add_glue
+@!g_order: glue_ord; {applicable order of infinity for glue}
+@y
+@z
+%---------------------------------------
+@x [32] m.619 l.12308 hlist_out - e-TeX TeXXeT
+@!edge:scaled; {left edge of sub-box, or right edge of leader space}
+@y
+@!edge:scaled; {right edge of sub-box or leader space}
+@!prev_p:pointer; {one step behind |p|}
+@z
+%---------------------------------------
+@x [32] m.619 l.12309 hlist_out - e-TeX add_glue
+@!glue_temp:real; {glue value before rounding}
+begin this_box:=temp_ptr; g_order:=glue_order(this_box);
+@y
+begin this_box:=temp_ptr;
+@z
+%---------------------------------------
+@x [32] m.619 l.12315 hlist_out - e-TeX TeXXeT
+save_loc:=dvi_offset+dvi_ptr; base_line:=cur_v; left_edge:=cur_h;
+@y
+save_loc:=dvi_offset+dvi_ptr; base_line:=cur_v;
+prev_p:=this_box+list_offset;
+if eTeX_ex then
+  begin @<Initialize the LR stack@>;
+  if subtype(this_box)=dlist then
+    if cur_dir=right_to_left then
+      begin cur_dir:=left_to_right; cur_h:=cur_h-width(this_box);
+      end
+    else subtype(this_box):=min_quarterword;
+  if (cur_dir=right_to_left)and(subtype(this_box)<>reversed) then
+    @<Reverse the complete hlist and set the subtype to |reversed|@>;
+  end;
+left_edge:=cur_h;
+@z
+%---------------------------------------
+@x [32] m.619 l.12318 hlist_out - e-TeX TeXXeT
+prune_movements(save_loc);
+@y
+if eTeX_ex then
+  begin @<Check for LR anomalies at the end of |hlist_out|@>;
+  if subtype(this_box)=dlist then cur_dir:=right_to_left;
+  end;
+prune_movements(save_loc);
+@z
+%---------------------------------------
+@x [32] m.620 l.12337 - e-TeX TeXXeT
+  p:=link(p);
+@y
+  prev_p:=p;
+  p:=link(p);
+@z
+%---------------------------------------
+@x [32] m.622 l.12362 - e-TeX TeXXeT
+kern_node,math_node:cur_h:=cur_h+width(p);
+@y
+kern_node:cur_h:=cur_h+width(p);
+math_node:begin if eTeX_ex then
+    @<Adjust the LR stack for the |hlist_out| routine; if necessary
+      reverse an hlist segment and |goto reswitch|@>;
+  cur_h:=cur_h+width(p);
+  end;
+@z
+%---------------------------------------
+@x [32] m.622 l.12364 - e-TeX TeXXeT
+othercases do_nothing
+@y
+@/@<Cases of |hlist_out| that arise in mixed direction text only@>@;
+othercases do_nothing
+@z
+%---------------------------------------
+@x [32] m.622 l.12369 - e-TeX TeXXeT
+next_p:p:=link(p);
+@y
+next_p:prev_p:=p; p:=link(p);
+@z
+%---------------------------------------
+@x [32] m.623 l.12376 - e-TeX TeXXeT
+  temp_ptr:=p; edge:=cur_h;
+@y
+  temp_ptr:=p; edge:=cur_h+width(p);
+  if cur_dir=right_to_left then cur_h:=edge;
+@z
+%---------------------------------------
+@x [32] m.623 l.12379 - e-TeX TeXXeT
+  cur_h:=edge+width(p); cur_v:=base_line;
+@y
+  cur_h:=edge; cur_v:=base_line;
+@z
+%---------------------------------------
+@x [32] m.625 l.12401 - e-TeX add_glue
+  begin if g_sign=stretching then
+    begin if stretch_order(g)=g_order then
+      begin vet_glue(float(glue_set(this_box))*stretch(g));
+@^real multiplication@>
+      rule_wd:=rule_wd+round(glue_temp);
+      end;
+    end
+  else if shrink_order(g)=g_order then
+    begin vet_glue(float(glue_set(this_box))*shrink(g));
+      rule_wd:=rule_wd-round(glue_temp);
+    end;
+  end;
+@y
+  add_glue(rule_wd);
+@z
+%---------------------------------------
+@x [32] m.626 l.12428 - e-TeX TeXXeT
+  edge:=cur_h+rule_wd; lx:=0;
+@y
+  if cur_dir=right_to_left then cur_h:=cur_h-10;
+  edge:=cur_h+rule_wd; lx:=0;
+@z
+%---------------------------------------
+@x [32] m.626 l.12434 - e-TeX TeXXeT
+  cur_h:=edge-10; goto next_p;
+@y
+  if cur_dir=right_to_left then cur_h:=edge
+  else cur_h:=edge-10;
+  goto next_p;
+@z
+%---------------------------------------
+@x [32] m.628 l.12473 - e-TeX TeXXeT
+synch_h; save_h:=dvi_h; temp_ptr:=leader_box;
+@y
+synch_h; save_h:=dvi_h; temp_ptr:=leader_box;
+if cur_dir=right_to_left then cur_h:=cur_h+leader_wd;
+@z
+%---------------------------------------
+@x [32] m.629 l.12489 vlist_out - e-TeX add_glue
+@!g_order: glue_ord; {applicable order of infinity for glue}
+@y
+@z
+%---------------------------------------
+@x [32] m.629 l.12498 vlist_out - e-TeX add_glue
+@!glue_temp:real; {glue value before rounding}
+begin this_box:=temp_ptr; g_order:=glue_order(this_box);
+@y
+begin this_box:=temp_ptr;
+@z
+%---------------------------------------
+@x [32] m.632 l.12544 - e-TeX TeXXeT
+  cur_h:=left_edge+shift_amount(p); {shift the box right}
+@y
+  if cur_dir=right_to_left then cur_h:=left_edge-shift_amount(p)
+  else cur_h:=left_edge+shift_amount(p); {shift the box right}
+@z
+%---------------------------------------
+@x [32] m.633 l.12556 - e-TeX TeXXeT
+  begin synch_h; synch_v;
+  dvi_out(put_rule); dvi_four(rule_ht); dvi_four(rule_wd);
+@y
+  begin if cur_dir=right_to_left then cur_h:=cur_h-rule_wd;
+  synch_h; synch_v;
+  dvi_out(put_rule); dvi_four(rule_ht); dvi_four(rule_wd);
+  cur_h:=left_edge;
+@z
+%---------------------------------------
+@x [32] m.634 l.12564 - e-TeX add_glue
+  begin if g_sign=stretching then
+    begin if stretch_order(g)=g_order then
+      begin vet_glue(float(glue_set(this_box))*stretch(g));
+@^real multiplication@>
+      rule_ht:=rule_ht+round(glue_temp);
+      end;
+    end
+  else if shrink_order(g)=g_order then
+    begin vet_glue(float(glue_set(this_box))*shrink(g));
+    rule_ht:=rule_ht-round(glue_temp);
+    end;
+  end;
+@y
+  add_glue(rule_ht);
+@z
+%---------------------------------------
+@x [32] m.637 l.12619 - e-TeX TeXXeT
+begin cur_h:=left_edge+shift_amount(leader_box); synch_h; save_h:=dvi_h;@/
+@y
+begin if cur_dir=right_to_left then
+  cur_h:=left_edge-shift_amount(leader_box)
+  else cur_h:=left_edge+shift_amount(leader_box);
+synch_h; save_h:=dvi_h;@/
+@z
+%---------------------------------------
+@x [32] m.638 l.12656 ship_out - e-TeX TeXXeT
+@<Ship box |p| out@>;
+@y
+@<Ship box |p| out@>;
+if eTeX_ex then @<Check for LR anomalies at the end of |ship_out|@>;
+@z
+%---------------------------------------
+@x [33] m.649 l.12876 hpack - e-TeX TeXXeT
+h:=0; @<Clear dimensions to zero@>;
+@y
+h:=0; @<Clear dimensions to zero@>;
+if TeXXeT_en then @<Initialize the LR stack@>;
+@z
+%---------------------------------------
+@x [33] m.649 l.12886 hpack - e-TeX TeXXeT
+exit: hpack:=r;
+@y
+exit: if TeXXeT_en then @<Check for LR anomalies at the end of |hpack|@>;
+hpack:=r;
+@z
+%---------------------------------------
+@x [33] m.651 l.12910 - e-TeX TeXXeT
+  kern_node,math_node: x:=x+width(p);
+@y
+  kern_node: x:=x+width(p);
+  math_node: begin x:=x+width(p);
+    if TeXXeT_en then @<Adjust the LR stack for the |hpack| routine@>;
+    end;
+@z
+%---------------------------------------
+@x [34] m.687 l.13480 - e-TeX middle
+\TeX's \.{\\left} and \.{\\right}. The |nucleus| of such noads is
+@y
+\TeX's \.{\\left} and \.{\\right} as well as \eTeX's \.{\\middle}.
+The |nucleus| of such noads is
+@z
+%---------------------------------------
+@x [34] m.687 l.13497 - e-TeX middle
+@d delimiter==nucleus {|delimiter| field in left and right noads}
+@y
+@d delimiter==nucleus {|delimiter| field in left and right noads}
+@d middle_noad==1 {|subtype| of right noad representing \.{\\middle}}
+@z
+%---------------------------------------
+@x [34] m.696 l.13670 - e-TeX middle
+right_noad: begin print_esc("right"); print_delimiter(nucleus(p));
+  end;
+end;
+if subtype(p)<>normal then
+  if subtype(p)=limits then print_esc("limits")
+  else print_esc("nolimits");
+if type(p)<left_noad then print_subsidiary_data(nucleus(p),".");
+@y
+right_noad: begin if subtype(p)=normal then print_esc("right")
+  else print_esc("middle");
+  print_delimiter(nucleus(p));
+  end;
+end;
+if type(p)<left_noad then
+  begin if subtype(p)<>normal then
+    if subtype(p)=limits then print_esc("limits")
+    else print_esc("nolimits");
+  print_subsidiary_data(nucleus(p),".");
+  end;
+@z
+%---------------------------------------
+@x [36] m.727 l.14268 - e-TeX middle
+done_with_noad: r:=q; r_type:=type(r);
+@y
+done_with_noad: r:=q; r_type:=type(r);
+if r_type=right_noad then
+  begin r_type:=left_noad; cur_style:=style; @<Set up the values...@>;
+  end;
+@z
+%---------------------------------------
+@x [36] m.760 l.14929 - e-TeX middle
+  r_type:=t;
+@y
+  if type(q)=right_noad then t:=open_noad;
+  r_type:=t;
+@z
+%---------------------------------------
+@x [36] m.762 l.14970 make_left_right - e-TeX middle
+begin if style<script_style then cur_size:=text_size
+else cur_size:=16*((style-text_style) div 2);
+@y
+begin cur_style:=style; @<Set up the values...@>;
+@z
+%---------------------------------------
+@x [37] m.807 l.15834 - e-TeX TeXXeT
+  begin type(q):=hlist_node; width(q):=width(p);
+@y
+  begin type(q):=hlist_node; width(q):=width(p);
+  if nest[nest_ptr-1].mode_field=mmode then subtype(q):=dlist; {for |ship_out|}
+@z
+%---------------------------------------
+@x [37] m.808 l.15852 - e-TeX TeXXeT
+n:=span_count(r); t:=width(s); w:=t; u:=hold_head;
+@y
+n:=span_count(r); t:=width(s); w:=t; u:=hold_head;
+subtype(r):=min_quarterword; {for |ship_out|}
+@z
+%---------------------------------------
+@x [39] m.866 l.17030 - e-TeX TeXXeT
+math_node: begin auto_breaking:=(subtype(cur_p)=after); kern_break;
+@y
+math_node: begin if subtype(cur_p)<L_code then auto_breaking:=end_LR(cur_p);
+  kern_break;
+@z
+%---------------------------------------
+@x [39] m.877 l.17216 post_line_break - e-TeX TeXXeT
+begin @<Reverse the links of the relevant passive nodes, setting |cur_p| to the
+@y
+@!LR_ptr:pointer; {stack of LR codes}
+begin LR_ptr:=LR_save;
+@<Reverse the links of the relevant passive nodes, setting |cur_p| to the
+@z
+%---------------------------------------
+@x [39] m.877 l.17229 post_line_break - e-TeX TeXXeT
+prev_graf:=best_line-1;
+@y
+prev_graf:=best_line-1;
+LR_save:=LR_ptr;
+@z
+%---------------------------------------
+@x [39] m.879 l.17259 - e-TeX TeXXeT
+  r:=q; {now |type(q)=glue_node|, |kern_node|, |math_node| or |penalty_node|}
+@y
+  r:=q; {now |type(q)=glue_node|, |kern_node|, |math_node| or |penalty_node|}
+  if type(q)=math_node then if TeXXeT_en then
+    @<Adjust the LR stack for the |post_line_break| routine@>;
+@z
+%---------------------------------------
+@x [39] m.880 l.17276 - e-TeX TeXXeT
+@<Modify the end of the line to reflect the nature of the break and to include
+  \.{\\rightskip}; also set the proper value of |disc_break|@>;
+@y
+if TeXXeT_en then
+  @<Insert LR nodes at the beginning of the current line and adjust
+    the LR stack based on LR nodes in this line@>;
+@<Modify the end of the line to reflect the nature of the break and to include
+  \.{\\rightskip}; also set the proper value of |disc_break|@>;
+if TeXXeT_en then @<Insert LR nodes at the end of the current line@>;
+@z
+%---------------------------------------
+@x [39] m.881 l.17299 - e-TeX TeXXeT
+    else if (type(q)=math_node)or(type(q)=kern_node) then width(q):=0;
+@y
+    else if type(q)=kern_node then width(q):=0
+    else if type(q)=math_node then
+      begin width(q):=0;
+      if TeXXeT_en then @<Adjust the LR stack for the |p...@>;
+      end;
+@z
+%---------------------------------------
+@x [44] m.977 l.18998 vsplit - e-TeX marks
+begin v:=box(n);
+@y
+@!mark_class:eight_bits;
+begin v:=box(n);
+for mark_class:=0 to 255 do
+@z
+%---------------------------------------
+@x [44] m.979 l.19032 - e-TeX marks
+else loop@+begin if type(p)=mark_node then
+@y
+else loop@+begin if type(p)=mark_node then
+    begin mark_class:=qo(subtype(p));
+@z
+%---------------------------------------
+@x [44] m.979 l.19042 - e-TeX marks
+      end;
+@y
+      end;
+    end;
+@z
+%---------------------------------------
+@x [45] m.982 l.19167 - e-TeX last_node_type
+The variables |last_penalty| and |last_kern| are similar.  And
+@y
+The variables |last_penalty|, |last_kern|, and |last_node_type|
+are similar.  And
+@z
+%---------------------------------------
+@x [45] m.982 l.19180 - e-TeX last_node_type
+@!last_kern:scaled; {used to implement \.{\\lastkern}}
+@y
+@!last_kern:scaled; {used to implement \.{\\lastkern}}
+@!last_node_type:integer; {used to implement \.{\\lastnodetype}}
+@z
+%---------------------------------------
+@x [45] m.991 l.19317 - e-TeX last_node_type
+last_glue:=max_halfword; last_penalty:=0; last_kern:=0;
+@y
+last_glue:=max_halfword; last_penalty:=0; last_kern:=0;
+last_node_type:=-1;
+@z
+%---------------------------------------
+@x [45] m.996 l.19384 - e-TeX last_node_type
+last_penalty:=0; last_kern:=0;
+@y
+last_penalty:=0; last_kern:=0;
+last_node_type:=type(p)+1;
+@z
+%---------------------------------------
+@x [45] m.1012 l.19660 fire_up - e-TeX marks
+begin @<Set the value of |output_penalty|@>;
+@y
+@!mark_class:eight_bits;
+begin @<Set the value of |output_penalty|@>;
+for mark_class:=0 to 255 do
+@z
+%---------------------------------------
+@x [45] m.1012 l.19669 fire_up - e-TeX marks
+if (top_mark<>null)and(first_mark=null) then
+@y
+for mark_class:=0 to 255 do
+if (top_mark<>null)and(first_mark=null) then
+@z
+%---------------------------------------
+@x [45] m.1016 l.19725 - e-TeX marks
+begin if first_mark=null then
+@y
+begin mark_class:=qo(subtype(p));
+if first_mark=null then
+@z
+%---------------------------------------
+@x [46] m.1030 l.19973 - e-TeX basic
+@p @t\4@>@<Declare action procedures for use by |main_control|@>@;
+@y
+@p @t\4@>@<Declare \eTeX\ procedures for use by |main_control|@>
+@t\4@>@<Declare action procedures for use by |main_control|@>@;
+@z
+%---------------------------------------
+@x [47] m.1080 l.20901 - e-TeX TeXXeT
+since |head| is a one-word node.
+@y
+since |head| is a one-word node.
+A final \.{\\endM} node is temporarily removed.
+@z
+%---------------------------------------
+@x [47] m.1080 l.20914 - e-TeX TeXXeT
+    if (type(tail)=hlist_node)or(type(tail)=vlist_node) then
+      @<Remove the last box, unless it's part of a discretionary@>;
+@y
+    begin if (type(tail)=math_node)and(subtype(tail)=end_M_code) then
+      remove_end_M;
+    if (type(tail)=hlist_node)or(type(tail)=vlist_node) then
+      @<Remove the last box, unless it's part of a discretionary@>;
+    if LR_temp<>null then insert_end_M;
+    end;
+@z
+%---------------------------------------
+@x [47] m.1096 l.21119 - e-TeX TeXXeT
+  else line_break(widow_penalty);
+@y
+  else line_break(widow_penalty);
+  if LR_save<>null then
+    begin flush_list(LR_save); LR_save:=null;
+    end;
+@z
+%---------------------------------------
+@x [47] m.1101 l.21175 make_mark - e-TeX marks
+begin p:=scan_toks(false,true); p:=get_node(small_node_size);
+type(p):=mark_node; subtype(p):=0; {the |subtype| is not used}
+@y
+@!c:eight_bits; {the mark class}
+begin if cur_chr=0 then c:=0
+else  begin scan_eight_bit_int; c:=cur_val;
+  end;
+p:=scan_toks(false,true); p:=get_node(small_node_size);
+type(p):=mark_node; subtype(p):=qi(c);
+@z
+%---------------------------------------
+@x [47] m.1105 l.21203 - e-TeX TeXXeT
+will be deleted, if present.
+@y
+will be deleted, if present.
+A final \.{\\endM} node is temporarily removed.
+@z
+%---------------------------------------
+@x [47] m.1105 l.21213 delete_last - e-TeX TeXXeT
+else  begin if not is_char_node(tail) then if type(tail)=cur_chr then
+@y
+else  begin if not is_char_node(tail) then
+  begin if (type(tail)=math_node)and(subtype(tail)=end_M_code) then
+    remove_end_M;
+  if type(tail)=cur_chr then
+@z
+%---------------------------------------
+@x [47] m.1105 l.21224 delete_last - e-TeX TeXXeT
+  end;
+@y
+  if LR_temp<>null then insert_end_M;
+  end;
+  end;
+@z
+%---------------------------------------
+@x [47] m.1130 l.21562 - e-TeX TeXXeT
+vmode+halign,hmode+valign:init_align;
+@y
+vmode+halign:init_align;
+hmode+valign:@<Cases of |main_control| for |hmode+valign|@>@; init_align;
+@z
+%---------------------------------------
+@x [48] m.1138 l.21629 init_math - e-TeX TeXXeT
+procedure init_math;
+label reswitch,found,not_found,done;
+var w:scaled; {new or partial |pre_display_size|}
+@y
+@t\4@>@<Declare subprocedures for |init_math|@>@;
+procedure init_math;
+label reswitch,found,not_found,done;
+var w:scaled; {new or partial |pre_display_size|}
+@!j:pointer; {prototype box for display}
+@!x:integer; {new |pre_display_direction|}
+@z
+%---------------------------------------
+@x [48] m.1145 l.21687 - e-TeX TeXXeT
+begin if head=tail then {`\.{\\noindent\$\$}' or `\.{\$\${ }\$\$}'}
+  begin pop_nest; w:=-max_dimen;
+  end
+@y
+begin j:=null; w:=-max_dimen;
+if head=tail then {`\.{\\noindent\$\$}' or `\.{\$\${ }\$\$}'}
+  @<Prepare for display after an empty paragraph@>
+@z
+%---------------------------------------
+@x [48] m.1145 l.21700 - e-TeX TeXXeT
+eq_word_define(dimen_base+pre_display_size_code,w);
+@y
+eq_word_define(dimen_base+pre_display_size_code,w);
+LR_box:=j;
+if eTeX_ex then eq_word_define(int_base+pre_display_direction_code,x);
+@z
+%---------------------------------------
+@x [48] m.1146 l.21708 - e-TeX TeXXeT
+v:=shift_amount(just_box)+2*quad(cur_font); w:=-max_dimen;
+p:=list_ptr(just_box);
+@y
+@<Prepare for display after a non-empty paragraph@>;
+@z
+%---------------------------------------
+@x [48] m.1146 l.21723 - e-TeX TeXXeT
+done:
+@y
+done:
+@<Finish the natural width computation@>
+@z
+%---------------------------------------
+@x [48] m.1147 l.21734 - e-TeX TeXXeT
+kern_node,math_node: d:=width(p);
+@y
+kern_node: d:=width(p);
+@t\4@>@<Cases of `Let |d| be the natural width' that need special treatment@>@;
+@z
+%---------------------------------------
+@x [48] m.1185 l.22243 - e-TeX middle
+  if type(q)<>left_noad then confusion("right");
+@:this can't happen right}{\quad right@>
+  info(numerator(incompleat_noad)):=link(q);
+  link(q):=incompleat_noad; link(incompleat_noad):=p;
+@y
+  if (type(q)<>left_noad)or(delim_ptr=null) then confusion("right");
+@:this can't happen right}{\quad right@>
+  info(numerator(incompleat_noad)):=link(delim_ptr);
+  link(delim_ptr):=incompleat_noad; link(incompleat_noad):=p;
+@z
+%---------------------------------------
+@x [48] m.1189 l.22288 - e-TeX middle
+else print_esc("right");
+@y
+@/@<Cases of |left_right| for |print_cmd_chr|@>@/
+else print_esc("right");
+@z
+%---------------------------------------
+@x [48] m.1191 l.22297 math_left_right - e-TeX middle
+begin t:=cur_chr;
+if (t=right_noad)and(cur_group<>math_left_group) then
+@y
+@!q:pointer; {resulting mlist}
+begin t:=cur_chr;
+if (t<>left_noad)and(cur_group<>math_left_group) then
+@z
+%---------------------------------------
+@x [48] m.1191 l.22302 math_left_right - e-TeX middle
+  if t=left_noad then
+    begin push_math(math_left_group); link(head):=p; tail:=p;
+    end
+  else  begin p:=fin_mlist(p); unsave; {end of |math_left_group|}
+@y
+  if t=middle_noad then
+    begin type(p):=right_noad; subtype(p):=middle_noad;
+    end;
+  if t=left_noad then q:=p
+  else  begin q:=fin_mlist(p); unsave; {end of |math_left_group|}
+    end;
+  if t<>right_noad then
+    begin push_math(math_left_group); link(head):=q; tail:=p;
+    delim_ptr:=p;
+    end
+  else  begin
+@z
+%---------------------------------------
+@x [48] m.1191 l.22308 math_left_right - e-TeX middle
+    info(nucleus(tail)):=p;
+@y
+    info(nucleus(tail)):=q;
+@z
+%---------------------------------------
+@x [48] m.1192 l.22316 - e-TeX middle
+  print_err("Extra "); print_esc("right");
+@.Extra \\right.@>
+  help1("I'm ignoring a \right that had no matching \left.");
+@y
+  print_err("Extra ");
+  if t=middle_noad then
+    begin print_esc("middle");
+@.Extra \\middle.@>
+    help1("I'm ignoring a \middle that had no matching \left.");
+    end
+  else  begin print_esc("right");
+@.Extra \\right.@>
+    help1("I'm ignoring a \right that had no matching \left.");
+    end;
+@z
+%---------------------------------------
+@x [48] m.1194 l.22331 after_math - e-TeX TeXXeT
+procedure after_math;
+@y
+@t\4@>@<Declare subprocedures for |after_math|@>@;
+procedure after_math;
+@z
+%---------------------------------------
+@x [48] m.1194 l.22338 after_math - e-TeX TeXXeT
+begin danger:=false;
+@y
+begin danger:=false;
+@<Retrieve the prototype box@>;
+@z
+%---------------------------------------
+@x [48] m.1194 l.22345 after_math - e-TeX TeXXeT
+  mlist_to_hlist; a:=hpack(link(temp_head),natural);
+@y
+  mlist_to_hlist; a:=hpack(link(temp_head),natural);
+  subtype(a):=dlist;
+@z
+%---------------------------------------
+@x [48] m.1194 l.22348 after_math - e-TeX TeXXeT
+  danger:=false;
+@y
+  danger:=false;
+  @<Retrieve the prototype box@>;
+@z
+%---------------------------------------
+@x [48] m.1199 l.22435 - e-TeX TeXXeT
+w:=width(b); z:=display_width; s:=display_indent;
+@y
+w:=width(b); z:=display_width; s:=display_indent;
+if pre_display_direction<0 then s:=-s-z;
+@z
+%---------------------------------------
+@x [48] m.1199 l.22450 - e-TeX TeXXeT
+resume_after_display
+@y
+@<Flush the prototype box@>;
+resume_after_display
+@z
+%---------------------------------------
+@x [48] m.1202 l.22492 - e-TeX TeXXeT
+d:=half(z-w);
+@y
+subtype(b):=dlist;
+d:=half(z-w);
+@z
+%---------------------------------------
+@x [48] m.1203 l.22513 - e-TeX TeXXeT
+  begin shift_amount(a):=s; append_to_vlist(a);
+@y
+  begin app_display(j,a,0);
+@z
+%---------------------------------------
+@x [48] m.1204 l.22528 - e-TeX TeXXeT
+shift_amount(b):=s+d; append_to_vlist(b)
+@y
+app_display(j,b,d)
+@z
+%---------------------------------------
+@x [48] m.1205 l.22533 - e-TeX TeXXeT
+  shift_amount(a):=s+z-width(a);
+  append_to_vlist(a);
+@y
+  app_display(j,a,z-width(a));
+@z
+%---------------------------------------
+@x [48] m.1206 l.22552 - e-TeX TeXXeT
+pop_nest;
+@y
+flush_node_list(LR_box);
+pop_nest;
+@z
+%---------------------------------------
+@x [49] m.1208 l.22577 - e-TeX protected
+control sequence can be defined to be `\.{\\long}' or `\.{\\outer}', and
+it might or might not be expanded. The prefixes `\.{\\global}', `\.{\\long}',
+@y
+control sequence can be defined to be `\.{\\long}', `\.{\\protected}',
+or `\.{\\outer}', and it might or might not be expanded. The prefixes
+`\.{\\global}', `\.{\\long}', `\.{\\protected}',
+@z
+%---------------------------------------
+@x [49] m.1209 l.22603 - e-TeX protected
+  else print_esc("global");
+@y
+  @/@<Cases of |prefix| for |print_cmd_chr|@>@/
+  else print_esc("global");
+@z
+%---------------------------------------
+@x [49] m.1211 l.22665 prefixed_command - e-TeX tracing
+    @<Discard erroneous prefixes and |return|@>;
+@y
+    @<Discard erroneous prefixes and |return|@>;
+  if tracing_commands>2 then if eTeX_ex then show_cur_cmd_chr;
+@z
+%---------------------------------------
+@x [49] m.1213 l.22686 - e-TeX protected
+if (cur_cmd<>def)and(a mod 4<>0) then
+@y
+if a>=8 then
+  begin j:=protected_token; a:=a-8;
+  end
+else j:=0;
+if (cur_cmd<>def)and((a mod 4<>0)or(j<>0)) then
+@z
+%---------------------------------------
+@x [49] m.1218 l.22749 - e-TeX protected
+  q:=scan_toks(true,e); define(p,call+(a mod 4),def_ref);
+@y
+  q:=scan_toks(true,e);
+  if j<>0 then
+    begin q:=get_avail; info(q):=j; link(q):=link(def_ref);
+    link(def_ref):=q;
+    end;
+  define(p,call+(a mod 4),def_ref);
+@z
+%---------------------------------------
+@x [49] m.1225 l.22853 - e-TeX read_line
+read_to_cs: begin scan_int; n:=cur_val;
+@y
+read_to_cs: begin j:=cur_chr; scan_int; n:=cur_val;
+@z
+%---------------------------------------
+@x [49] m.1225 l.22861 - e-TeX read_line
+  p:=cur_cs; read_toks(n,p); define(p,call,cur_val);
+@y
+  p:=cur_cs; read_toks(n,p,j); define(p,call,cur_val);
+@z
+%---------------------------------------
+@x [49] m.1246 l.23179 alter_integer - e-TeX interaction_mode
+var c:0..1; {0 for \.{\\deadcycles}, 1 for \.{\\insertpenalties}}
+begin c:=cur_chr; scan_optional_equals; scan_int;
+if c=0 then dead_cycles:=cur_val
+@y
+var c:small_number;
+  {0 for \.{\\deadcycles}, 1 for \.{\\insertpenalties}, etc.}
+begin c:=cur_chr; scan_optional_equals; scan_int;
+if c=0 then dead_cycles:=cur_val
+@/@<Cases for |alter_integer|@>@/
+@z
+%---------------------------------------
+@x [49] m.1292 l.23581 - e-TeX show_levels
+  show_lists:print_esc("showlists");
+@y
+  show_lists:print_esc("showlists");
+  @<Cases of |xray| for |print_cmd_chr|@>@;@/
+@z
+%---------------------------------------
+@x [49] m.1293 l.23594 show_whatever - e-TeX show_levels
+othercases @<Show the current value of some parameter or register,
+@y
+@<Cases for |show_whatever|@>@;@/
+othercases @<Show the current value of some parameter or register,
+@z
+%---------------------------------------
+@x [49] m.1295 l.23629 - e-TeX protected
+call: print("macro");
+long_call: print_esc("long macro");
+outer_call: print_esc("outer macro");
+long_outer_call: begin print_esc("long"); print_esc("outer macro");
+@y
+call,long_call,outer_call,long_outer_call: begin n:=cmd-call;
+  if info(link(chr_code))=protected_token then n:=n+4;
+  if odd(n div 4) then print_esc("protected");
+  if odd(n) then print_esc("long");
+  if odd(n div 2) then print_esc("outer");
+  if n>0 then print_char(" ");
+  print("macro");
+@z
+%---------------------------------------
+@x [50] m.1307 l.23779 - e-TeX basic
+dump_int(@$);@/
+@y
+dump_int(@$);@/
+@<Dump the \eTeX\ state@>@/
+@z
+%---------------------------------------
+@x [50] m.1308 l.23794 - e-TeX basic
+if x<>@$ then goto bad_fmt; {check that strings are the same}
+@y
+if x<>@$ then goto bad_fmt; {check that strings are the same}
+@/@<Undump the \eTeX\ state@>@/
+@z
+%---------------------------------------
+@x [51] m.1335 l.24301 final_cleanup - e-TeX marks
+var c:small_number; {0 for \.{\\end}, 1 for \.{\\dump}}
+@y
+var c:small_number; {0 for \.{\\end}, 1 for \.{\\dump}}
+@!mark_class:eight_bits; {a mark class}
+@z
+%---------------------------------------
+@x [51] m.1335 l.24313 final_cleanup - tracing
+  print_int(cur_level-level_one); print_char(")");
+@y
+  print_int(cur_level-level_one); print_char(")");
+  if eTeX_ex then show_save_groups;
+@z
+%---------------------------------------
+@x [51] m.1335 l.24336 final_cleanup - e-TeX marks
+    if cur_mark[c]<>null then delete_token_ref(cur_mark[c]);
+@y
+   for mark_class:=0 to 255 do
+    if cur_mark[c]<>null then delete_token_ref(cur_mark[c]);
+@z
+%---------------------------------------
+@x [51] m.1336 l.24345 ] m.1336 l.24340 init_prim - e-TeX basic
+begin no_new_control_sequence:=false;
+@y
+begin no_new_control_sequence:=false;
+first:=0;
+@z
+%---------------------------------------
+@x [51] m.1337 l.24360 - e-TeX basic
+if (format_ident=0)or(buffer[loc]="&") then
+@y
+@<Enable \eTeX, if requested@>@;@/
+if (format_ident=0)or(buffer[loc]="&") then
+@z
+%---------------------------------------
+@x [51] m.1337 l.24368 - e-TeX basic
+  end;
+@y
+  end;
+wterm('entering ');
+if eTeX_ex then wterm('extended') else wterm('compatibility');
+wterm_ln(' mode');
+@z
+%---------------------------------------
+@x [54] m.1379 l.24903 - e-TeX additions
+@* \[54] System-dependent changes.
+@y
+@* \[53a] The extended features of \eTeX.
+The program has two modes of operation:  (1)~In \TeX\ compatibility mode
+it fully deserves the name \TeX\ and there are neither extended features
+nor additional primitive commands.  There are, however, a few
+modifications that would be legitimate in any implementation of \TeX\
+such as, e.g., preventing arithmetic overflow in the glue to \.{DVI}
+unit conversion during |ship_out|.  (2)~In extended mode there are
+additional primitive commands and the extended features of \eTeX\ are
+available.
+
+The distinction between these two modes of operation initially takes
+place when a `virgin' \.{INITEX} starts without reading a format file.
+Later on the values of all \eTeX\ state variables are inherited when
+\.{VIRTEX} (or \.{INITEX}) reads a format file.
+
+The code below is designed to work for cases where `$|init|\ldots|tini|$'
+is a run-time switch.
+
+@<Enable \eTeX, if requested@>=
+@!init if (buffer[loc]="*")and(format_ident=" (INITEX)") then
+  begin no_new_control_sequence:=false;
+  @<Generate all \eTeX\ primitives@>@;
+  incr(loc); eTeX_mode:=1; {enter extended mode}
+  end;
+tini@;@/
+if not no_new_control_sequence then {just entered extended mode ?}
+  no_new_control_sequence:=true@+else
+
+@ The \eTeX\ features available in extended mode are grouped into two
+categories:  (1)~Some of them are permanently enabled and have no
+semantic effect as long as none of the additional primitives are
+executed.  (2)~The remaining \eTeX\ features are optional and can be
+individually enabled and disabled.  For each optional feature there is
+an \eTeX\ state variable named \.{\\...state}; the feature is enabled,
+resp.\ disabled by assigning a positive, resp.\ non-positive value to
+that integer.
+
+@d eTeX_state_base=int_base+eTeX_state_code
+@d eTeX_state(#)==eqtb[eTeX_state_base+#].int {an \eTeX\ state variable}
+@#
+@d eTeX_version_code=glue_val+4 {code for \.{\\eTeXversion}}
+@d eTeX_revision_code=6 {command code for \.{\\eTeXrevision}}
+
+@<Generate all \eTeX...@>=
+primitive("lastnodetype",last_item,last_node_type_code);
+@!@:last_node_type_}{\.{\\lastnodetype} primitive@>
+primitive("eTeXversion",last_item,eTeX_version_code);
+@!@:eTeX_version_}{\.{\\eTeXversion} primitive@>
+primitive("eTeXrevision",convert,eTeX_revision_code);@/
+@!@:eTeX_revision_}{\.{\\eTeXrevision} primitive@>
+
+@ @<Cases of |last_item| for |print_cmd_chr|@>=
+last_node_type_code: print_esc("lastnodetype");
+eTeX_version_code: print_esc("eTeXversion");
+
+@ @<Cases for `Fetch an item in the current mode'@>=
+else if cur_chr=eTeX_version_code then cur_val:=eTeX_version
+
+@ @<Cases of |convert| for |print_cmd_chr|@>=
+eTeX_revision_code: print_esc("eTeXrevision");
+
+@ @<Cases of `Scan the argument for command |c|'@>=
+eTeX_revision_code: do_nothing;
+
+@ @<Cases of `Print the result of command |c|'@>=
+eTeX_revision_code: print(eTeX_revision);
+
+@ @d eTeX_ex==(eTeX_mode=1) {is this extended mode?}
+
+@<Glob...@>=
+@!eTeX_mode: 0..1; {identifies compatibility and extended mode}
+
+@ @<Initialize table entries...@>=
+eTeX_mode:=0; {initially we are in compatibility mode}
+
+@ @<Dump the \eTeX\ state@>=
+dump_int(eTeX_mode);
+for j:=0 to eTeX_states-1 do eTeX_state(j):=0; {disable all enhancements}
+
+@ @<Undump the \eTeX\ state@>=
+undump(0)(1)(eTeX_mode);
+
+@ The |eTeX_enabled| function simply returns its first argument as
+result.  This argument is |true| if an optional \eTeX\ feature is
+currently enabled; otherwise, if the argument is |false|, the function
+gives an error message.
+
+@<Declare \eTeX\ procedures for use by |main_control|@>=
+function eTeX_enabled(@!b:boolean;@!j:quarterword;@!k:halfword):boolean;
+begin if not b then
+  begin print_err("Improper "); print_cmd_chr(j,k);
+  help1("Sorry, this optional e-TeX feature has been disabled."); error;
+  end;
+eTeX_enabled:=b;
+end;
+
+@ @<Declare \eTeX\ procedures for expanding and scanning@>=
+procedure@?scan_eight_bit_int; forward;@t\2@>
+
+@ First we implement the additional \eTeX\ parameters in the table of
+equivalents.
+
+@<Generate all \eTeX...@>=
+primitive("everyeof",assign_toks,every_eof_loc);
+@!@:every_eof_}{\.{\\everyeof} primitive@>
+primitive("tracingassigns",assign_int,int_base+tracing_assigns_code);@/
+@!@:tracing_assigns_}{\.{\\tracingassigns} primitive@>
+primitive("tracinggroups",assign_int,int_base+tracing_groups_code);@/
+@!@:tracing_groups_}{\.{\\tracinggroups} primitive@>
+primitive("tracingifs",assign_int,int_base+tracing_ifs_code);@/
+@!@:tracing_ifs_}{\.{\\tracingifs} primitive@>
+primitive("tracingscantokens",assign_int,int_base+tracing_scan_tokens_code);@/
+@!@:tracing_scan_tokens_}{\.{\\tracingscantokens} primitive@>
+primitive("predisplaydirection",
+  assign_int,int_base+pre_display_direction_code);@/
+@!@:pre_display_direction_}{\.{\\predisplaydirection} primitive@>
+
+@ @d every_eof==equiv(every_eof_loc)
+
+@<Cases of |assign_toks| for |print_cmd_chr|@>=
+every_eof_loc: print_esc("everyeof");
+
+@ @<Cases for |print_param|@>=
+tracing_assigns_code:print_esc("tracingassigns");
+tracing_groups_code:print_esc("tracinggroups");
+tracing_ifs_code:print_esc("tracingifs");
+tracing_scan_tokens_code:print_esc("tracingscantokens");
+pre_display_direction_code:print_esc("predisplaydirection");
+
+@ The |print_group| procedure prints the current level of grouping and
+the name corresponding to |cur_group|.
+
+@<Declare \eTeX\ procedures for tracing and input@>=
+procedure print_group(@!e:boolean);
+label exit;
+begin print_int(cur_level); print(": ");
+case cur_group of
+  bottom_level: begin print("bottom level"); return;
+    end;
+  simple_group,semi_simple_group:
+    begin if cur_group=semi_simple_group then print("semi ");
+    print("simple");
+    end;
+  hbox_group,adjusted_hbox_group:
+    begin if cur_group=adjusted_hbox_group then print("adjusted ");
+    print("hbox");
+    end;
+  vbox_group: print("vbox");
+  vtop_group: print("vtop");
+  align_group,no_align_group:
+    begin if cur_group=no_align_group then print("no ");
+    print("align");
+    end;
+  output_group: print("output");
+  disc_group: print("disc");
+  insert_group: print("insert");
+  vcenter_group: print("vcenter");
+  math_group,math_choice_group,math_shift_group,math_left_group:
+    begin print("math");
+    if cur_group=math_choice_group then print(" choice")
+    else if cur_group=math_shift_group then print(" shift")
+    else if cur_group=math_left_group then print(" left");
+    end;
+  end; {there are no other cases}
+print(" group");
+if saved(-1)<>0 then
+  begin if e then print(" entered at line ") else print(" at line ");
+  print_int(saved(-1));
+  end;
+exit:end;
+
+@ The |group_trace| procedure is called when a new level of grouping
+begins (|e=false|) or ends (|e=true|) with |saved(-1)| containing the
+line number.
+
+@<Declare \eTeX\ procedures for tracing and input@>=
+@!stat procedure group_trace(@!e:boolean);
+begin begin_diagnostic; print_char("{");
+if e then print("leaving ") else print("entering ");
+print_group(e); print_char("}"); end_diagnostic(false);
+end;
+tats
+
+@ The \.{\\currentgrouplevel} and \.{\\currentgrouptype} commands return
+the current level of grouping and the type of the current group
+respectively.
+
+@d group_level_code=glue_val+5 {code for \.{\\currentgrouplevel}}
+@d group_type_code=glue_val+6 {code for \.{\\currentgrouptype}}
+
+@<Generate all \eTeX...@>=
+primitive("currentgrouplevel",last_item,group_level_code);
+@!@:current_group_level_}{\.{\\currentgrouplevel} primitive@>
+primitive("currentgrouptype",last_item,group_type_code);
+@!@:current_group_type_}{\.{\\currentgrouptype} primitive@>
+
+@ @<Cases of |last_item| for |print_cmd_chr|@>=
+group_level_code: print_esc("currentgrouplevel");
+group_type_code: print_esc("currentgrouptype");
+
+@ @<Cases for `Fetch an item in the current mode'@>=
+else if cur_chr=group_level_code then cur_val:=cur_level-level_one
+else if cur_chr=group_type_code then cur_val:=cur_group
+
+@ The \.{\\showgroups} command displays all currently active grouping
+levels.
+
+@d show_groups=4 { \.{\\showgroups} }
+
+@<Generate all \eTeX...@>=
+primitive("showgroups",xray,show_groups);
+@!@:show_groups_}{\.{\\showgroups} primitive@>
+
+@ @<Cases of |xray| for |print_cmd_chr|@>=
+show_groups:print_esc("showgroups");
+
+@ @<Cases for |show_whatever|@>=
+show_groups: begin begin_diagnostic; show_save_groups;
+  end;
+
+@ The modifications of \TeX\ required for the display produced by the
+|show_save_groups| procedure were first discussed by Donald~E. Knuth in
+{\sl TUGboat\/} {\bf 11}, 165--170 and 499--511, 1990.
+@^Knuth, Donald Ervin@>
+
+In order to understand a group type we also have to know its mode.
+Since unrestricted horizontal modes are not associated with grouping,
+they are skipped when traversing the semantic nest.
+
+@<Declare \eTeX\ procedures for use by |main_control|@>=
+procedure show_save_groups;
+label found1,found2,found,done;
+var p:0..nest_size; {index into |nest|}
+@!m:-mmode..mmode; {mode}
+@!v:0..save_size; {saved value of |save_ptr|}
+@!l:quarterword; {saved value of |cur_level|}
+@!c:group_code; {saved value of |cur_group|}
+@!a:-1..1; {to keep track of alignments}
+@!i:integer;
+@!j:quarterword;
+@!s:str_number;
+begin p:=nest_ptr; nest[p]:=cur_list; {put the top level into the array}
+v:=save_ptr; l:=cur_level; c:=cur_group;
+save_ptr:=cur_boundary; decr(cur_level);@/
+a:=1;
+print_nl(""); print_ln;
+loop@+begin print_nl("### "); print_group(true);
+  if cur_group=bottom_level then goto done;
+  repeat m:=nest[p].mode_field;
+  if p>0 then decr(p) else m:=vmode;
+  until m<>hmode;
+  print(" (");
+  case cur_group of
+    simple_group: begin incr(p); goto found2;
+      end;
+    hbox_group,adjusted_hbox_group: s:="hbox";
+    vbox_group: s:="vbox";
+    vtop_group: s:="vtop";
+    align_group: if a=0 then
+        begin if m=-vmode then s:="halign" else s:="valign";
+        a:=1; goto found1;
+        end
+      else  begin if a=1 then print("align entry") else print_esc("cr");
+        if p>=a then p:=p-a;
+        a:=0; goto found;
+        end;
+    no_align_group:
+      begin incr(p); a:=-1; print_esc("noalign"); goto found2;
+      end;
+    output_group:
+      begin print_esc("output"); goto found;
+      end;
+    math_group: goto found2;
+    disc_group,math_choice_group:
+      begin if cur_group=disc_group then print_esc("discretionary")
+      else print_esc("mathchoice");
+      for i:=1 to 3 do if i<=saved(-2) then print("{}");
+      goto found2;
+      end;
+    insert_group:
+      begin if saved(-2)=255 then print_esc("vadjust")
+      else  begin print_esc("insert"); print_int(saved(-2));
+        end;
+      goto found2;
+      end;
+    vcenter_group: begin s:="vcenter"; goto found1;
+      end;
+    semi_simple_group: begin incr(p); print_esc("begingroup"); goto found;
+      end;
+    math_shift_group:
+      begin if m=mmode then print_char("$")
+      else if nest[p].mode_field=mmode then
+        begin print_cmd_chr(eq_no,saved(-2)); goto found;
+        end;
+      print_char("$"); goto found;
+      end;
+    math_left_group:
+      begin if type(nest[p+1].eTeX_aux_field)=left_noad then print_esc("left")
+      else print_esc("middle");
+      goto found;
+      end;
+    end; {there are no other cases}
+  @<Show the box context@>;
+  found1: print_esc(s); @<Show the box packaging info@>;
+  found2: print_char("{");
+  found: print_char(")"); decr(cur_level);
+  cur_group:=save_level(save_ptr); save_ptr:=save_index(save_ptr)
+  end;
+done: save_ptr:=v; cur_level:=l; cur_group:=c;
+end;
+
+@ @<Show the box packaging info@>=
+if saved(-2)<>0 then
+  begin print_char(" ");
+  if saved(-3)=exactly then print("to") else print("spread");
+  print_scaled(saved(-2)); print("pt");
+  end
+
+@ @<Show the box context@>=
+i:=saved(-4);
+if i<>0 then
+  if i<box_flag then
+    begin if abs(nest[p].mode_field)=vmode then j:=hmove else j:=vmove;
+    if i>0 then print_cmd_chr(j,0) else print_cmd_chr(j,1);
+    print_scaled(abs(i)); print("pt");
+    end
+  else if i<ship_out_flag then
+    begin i:=i-box_flag;
+    if i>255 then
+      begin print_esc("global"); i:=i-256;
+      end;
+    print_esc("setbox"); print_int(i); print_char("=");
+    end
+  else print_cmd_chr(leader_ship,i-(leader_flag-a_leaders))
+
+@ The |scan_general_text| procedure is much like |scan_toks(false,false)|,
+but will be invoked via |expand|, i.e., recursively.
+@^recursion@>
+
+@<Declare \eTeX\ procedures for expanding and scanning@>=
+procedure@?scan_general_text; forward;@t\2@>
+
+@ The token list (balanced text) created by |scan_general_text| begins
+at |link(temp_head)| and ends at |cur_val|.  (If |cur_val=temp_head|,
+the list is empty.)
+
+@<Declare \eTeX\ procedures for token lists@>=
+procedure scan_general_text;
+label found;
+var s:normal..absorbing; {to save |scanner_status|}
+@!w:pointer; {to save |warning_index|}
+@!d:pointer; {to save |def_ref|}
+@!p:pointer; {tail of the token list being built}
+@!q:pointer; {new node being added to the token list via |store_new_token|}
+@!unbalance:halfword; {number of unmatched left braces}
+begin s:=scanner_status; w:=warning_index; d:=def_ref;
+scanner_status:=absorbing; warning_index:=cur_cs;
+def_ref:=get_avail; token_ref_count(def_ref):=null; p:=def_ref;
+scan_left_brace; {remove the compulsory left brace}
+unbalance:=1;
+loop@+  begin get_token;
+  if cur_tok<right_brace_limit then
+    if cur_cmd<right_brace then incr(unbalance)
+    else  begin decr(unbalance);
+      if unbalance=0 then goto found;
+      end;
+  store_new_token(cur_tok);
+  end;
+found: q:=link(def_ref); free_avail(def_ref); {discard reference count}
+if q=null then cur_val:=temp_head @+ else cur_val:=p;
+link(temp_head):=q;
+scanner_status:=s; warning_index:=w; def_ref:=d;
+end;
+
+@ The \.{\\showtokens} command displays a token list.
+
+@d show_tokens=5 { \.{\\showtokens} }
+
+@<Generate all \eTeX...@>=
+primitive("showtokens",xray,show_tokens);
+@!@:show_tokens_}{\.{\\showtokens} primitive@>
+
+@ @<Cases of |xray| for |print_cmd_chr|@>=
+show_tokens:print_esc("showtokens");
+
+@ The \.{\\unexpanded} primitive prevents expansion of tokens much as
+the result from \.{\\the} applied to a token variable.  The
+\.{\\detokenize} primitive converts a token list into a list of
+character tokens much as if the token list were written to a file.  We
+use the fact that the command modifiers for \.{\\unexpanded} and
+\.{\\detokenize} are odd whereas those for \.{\\the} and \.{\\showthe}
+are even.
+
+@<Generate all \eTeX...@>=
+primitive("unexpanded",the,1);@/
+@!@:unexpanded_}{\.{\\unexpanded} primitive@>
+primitive("detokenize",the,show_tokens);@/
+@!@:detokenize_}{\.{\\detokenize} primitive@>
+
+@ @<Cases of |the| for |print_cmd_chr|@>=
+else if chr_code=1 then print_esc("unexpanded")
+else print_esc("detokenize")
+
+@ @<Handle \.{\\unexpanded} or \.{\\detokenize} and |return|@>=
+if odd(cur_chr) then
+  begin c:=cur_chr; scan_general_text;
+  if c=1 then the_toks:=cur_val
+  else begin old_setting:=selector; selector:=new_string; b:=pool_ptr;
+    p:=get_avail; link(p):=link(temp_head);
+    token_show(p); flush_list(p);
+    selector:=old_setting; the_toks:=str_toks(b);
+    end;
+  return;
+  end
+
+@ The \.{\\interactionmode} primitive allows to query and set the
+interaction mode.
+
+@<Generate all \eTeX...@>=
+primitive("interactionmode",set_page_int,2);
+@!@:interaction_mode_}{\.{\\interactionmode} primitive@>
+
+@ @<Cases of |set_page_int| for |print_cmd_chr|@>=
+else if chr_code=2 then print_esc("interactionmode")
+
+@ @<Cases for `Fetch the |dead_cycles| or the |insert_penalties|'@>=
+else if m=2 then cur_val:=interaction
+
+@ @<Declare \eTeX\ procedures for use by |main_control|@>=
+procedure@?new_interaction; forward;@t\2@>
+
+@ @<Cases for |alter_integer|@>=
+else if c=2 then
+  begin if (cur_val<batch_mode)or(cur_val>error_stop_mode) then
+    begin print_err("Bad interaction mode");
+@.Bad interaction mode@>
+    help2("Modes are 0=batch, 1=nonstop, 2=scroll, and")@/
+    ("3=errorstop. Proceed, and I'll ignore this case.");
+    int_error(cur_val);
+    end
+  else  begin cur_chr:=cur_val; new_interaction;
+    end;
+  end
+
+@ The |middle| feature of \eTeX\ allows one ore several \.{\\middle}
+delimiters to appear between \.{\\left} and \.{\\right}.
+
+@<Generate all \eTeX...@>=
+primitive("middle",left_right,middle_noad);
+@!@:middle_}{\.{\\middle} primitive@>
+
+@ @<Cases of |left_right| for |print_cmd_chr|@>=
+else if chr_code=middle_noad then print_esc("middle")
+
+@ In constructions such as
+$$\vbox{\halign{\.{#}\hfil\cr
+{}\\vbox to \\vsize\{\cr
+\hskip 25pt \\vskip 0pt plus 0.0001fil\cr
+\hskip 25pt ...\cr
+\hskip 25pt \\vfil\\penalty-200\\vfilneg\cr
+\hskip 25pt ...\}\cr}}$$
+the stretch components of \.{\\vfil} and \.{\\vfilneg} compensate;
+in standard \TeX\ they may get modified in order to prevent arithmetic
+overflow during |ship_out| when each of them is multiplied by a large
+|glue_set| value.
+
+In \eTeX\ the conversion from stretch or shrink components of glue to
+\.{DVI} units is performed by the |do_glue| function defined below.
+
+In extended mode the |do_glue| function adds up the relevant stretch (or
+shrink) components of consecutive glue nodes and converts the glue nodes
+into equivalent kern nodes; during this process glue specifications may
+be recycled.  The accumulated stretch or shrink is then multiplied by
+|glue_set(this_box)| and returned as result.  Since one and the same box
+may be used several times inside leaders the result is also added to the
+width of the first or only kern node; the subtype of the glue node(s)
+remains unchanged.  The consecutive glue nodes may be separated by
+insert, mark, adjust, kern, and penalty nodes.
+
+@d add_glue(#)==#:=#+do_glue(this_box,p)
+@#
+@d add_stretch_shrink== {accumulate stretch or shrink amount}
+if g_sign=stretching then
+  begin if stretch_order(g)=g_order then s:=s+stretch(g);
+  end
+else  begin if shrink_order(g)=g_order then s:=s-shrink(g);
+  end
+
+@<Declare procedures needed in |hlist_out|, |vlist_out|@>=
+function do_glue(@!this_box,@!p:pointer):scaled;
+label continue, next_p, done;
+var q:pointer; {list traverser}
+@!g_order: glue_ord; {applicable order of infinity for glue}
+@!g_sign: normal..shrinking; {selects type of glue}
+@!s:scaled; {accumulated stretch or shrink}
+@!glue_temp:real; {glue value before rounding}
+begin g_order:=glue_order(this_box); g_sign:=glue_sign(this_box);
+s:=0; add_stretch_shrink;
+if not eTeX_ex or(subtype(p)>=a_leaders) then goto done;
+q:=p;
+continue: type(q):=kern_node; width(q):=width(g);
+fast_delete_glue_ref(g);
+next_p: q:=link(q);
+if (q<>null) and not is_char_node(q) then case type(q) of
+ins_node,mark_node,adjust_node,kern_node,penalty_node: goto next_p;
+glue_node: if subtype(q)<a_leaders then
+  begin g:=glue_ptr(q); add_stretch_shrink; goto continue;
+  end;
+othercases do_nothing
+endcases;@/
+done: if s<>0 then
+  begin vet_glue(float(glue_set(this_box))*s); s:=round(glue_temp);
+@^real multiplication@>
+  if type(p)=kern_node then width(p):=width(p)+s;
+  end;
+do_glue:=s;
+end;
+
+@ The optional |TeXXeT| feature of \eTeX\ contains the code for mixed
+left-to-right and right-to-left typesetting.  This code is inspired by
+but different from \TeXeT\ as presented by Donald~E. Knuth and Pierre
+MacKay in {\sl TUGboat\/} {\bf 8}, 14--25, 1987.
+@^Knuth, Donald Ervin@>
+@^MacKay, Pierre@>
+
+In order to avoid confusion with \TeXeT\ the present implementation of
+mixed direction typesetting is called \TeXXeT.  It differs from \TeXeT\
+in several important aspects:  (1)~Right-to-left text is reversed
+explicitely by the |ship_out| routine and is written to a normal \.{DVI}
+file without any |begin_reflect| or |end_reflect| commands; (2)~a
+|math_node| is (ab)used instead of a |whatsit_node| to record the
+\.{\\beginL}, \.{\\endL}, \.{\\beginR}, and \.{\\endR} text direction
+primitives in order to keep the influence on the line breaking algorithm
+for pure left-to-right text as small as possible; (3)~right-to-left text
+interrupted by a displayed equation is automatically resumed after that
+equation; and (4)~the |valign| command code with a non-zero command
+modifier is (ab)used for the text direction primitives.
+
+Nevertheless there is a subtle difference between \TeX\ and \TeXXeT\
+that may influence the line breaking algorithm for pure left-to-right
+text.  When a paragraph containing math mode material is broken into
+lines \TeX\ may generate lines where math mode material is not enclosed
+by properly nested \.{\\mathon} and \.{\\mathoff} nodes.  Unboxing such
+lines as part of a new paragraph may have the effect that hyphenation is
+attempted for `words' originating from math mode or that hyphenation is
+inhibited for words originating from horizontal mode.
+
+In \TeXXeT\ additional \.{\\beginM}, resp.\ \.{\\endM} math nodes are
+supplied at the start, resp.\ end of lines such that math mode material
+inside a horizontal list always starts with either \.{\\mathon} or
+\.{\\beginM} and ends with \.{\\mathoff} or \.{\\endM}.  These
+additional nodes are transparent to operations such as \.{\\unskip},
+\.{\\lastpenalty}, or \.{\\lastbox} but they do have the effect that
+hyphenation is never attempted for `words' originating from math mode
+and is never inhibited for words originating from horizontal mode.
+
+@d TeXXeT_state==eTeX_state(TeXXeT_code)
+@d TeXXeT_en==(TeXXeT_state>0) {is \TeXXeT\ enabled?}
+
+@<Cases for |print_param|@>=
+eTeX_state_code+TeXXeT_code:print_esc("TeXXeTstate");
+
+@ @<Generate all \eTeX...@>=
+primitive("TeXXeTstate",assign_int,eTeX_state_base+TeXXeT_code);
+@!@:TeXXeT_state_}{\.{\\TeXXeT_state} primitive@>
+primitive("beginL",valign,begin_L_code);
+@!@:beginL_}{\.{\\beginL} primitive@>
+primitive("endL",valign,end_L_code);
+@!@:endL_}{\.{\\endL} primitive@>
+primitive("beginR",valign,begin_R_code);
+@!@:beginR_}{\.{\\beginR} primitive@>
+primitive("endR",valign,end_R_code);
+@!@:endR_}{\.{\\endR} primitive@>
+
+@ @<Cases of |valign| for |print_cmd_chr|@>=
+else case chr_code of
+  begin_L_code: print_esc("beginL");
+  end_L_code: print_esc("endL");
+  begin_R_code: print_esc("beginR");
+  othercases print_esc("endR")
+  endcases
+
+@ @<Cases of |main_control| for |hmode+valign|@>=
+if cur_chr>0 then
+  begin if eTeX_enabled(TeXXeT_en,cur_cmd,cur_chr) then
+@.Improper \\beginL@>
+@.Improper \\endL@>
+@.Improper \\beginR@>
+@.Improper \\endR@>
+    tail_append(new_math(0,cur_chr));
+  end
+else
+
+@ An hbox with subtype dlist will never be reversed, even when embedded
+in right-to-left text.
+
+@<Display if this box is never to be reversed@>=
+if (type(p)=hlist_node)and(subtype(p)=dlist) then print(", display")
+
+@ A number of routines are based on a stack of one-word nodes whose
+|info| fields contain |end_M_code|, |end_L_code|, or |end_R_code|.  The
+top of the stack is pointed to by |LR_ptr|.
+
+When the stack manipulation macros of this section are used below,
+variable |LR_ptr| might be the global variable declared here for |hpack|
+and |ship_out|, or might be local to |post_line_break|.
+
+@d put_LR(#)==begin temp_ptr:=get_avail; info(temp_ptr):=#;
+  link(temp_ptr):=LR_ptr; LR_ptr:=temp_ptr;
+  end
+@#
+@d push_LR(#)==put_LR(end_LR_type(#))
+@#
+@d pop_LR==begin temp_ptr:=LR_ptr; LR_ptr:=link(temp_ptr);
+  free_avail(temp_ptr);
+  end
+
+@<Glob...@>=
+@!LR_temp:pointer; {holds a temporarily removed \.{\\endM} node}
+@!LR_ptr:pointer; {stack of LR codes for |hpack|, |ship_out|, and |init_math|}
+@!LR_problems:integer; {counts missing begins and ends}
+@!cur_dir:small_number; {current text direction}
+
+@ @<Set init...@>=
+LR_temp:=null; LR_ptr:=null; LR_problems:=0; cur_dir:=left_to_right;
+
+@ @<Insert LR nodes at the beg...@>=
+begin q:=link(temp_head);
+if LR_ptr<>null then
+  begin temp_ptr:=LR_ptr; r:=q;
+  repeat s:=new_math(0,begin_LR_type(info(temp_ptr))); link(s):=r; r:=s;
+  temp_ptr:=link(temp_ptr);
+  until temp_ptr=null;
+  link(temp_head):=r;
+  end;
+while q<>cur_break(cur_p) do
+  begin if not is_char_node(q) then
+    if type(q)=math_node then @<Adjust the LR stack for the |p...@>;
+  q:=link(q);
+  end;
+end
+
+@ @<Adjust the LR stack for the |p...@>=
+if end_LR(q) then
+  begin if LR_ptr<>null then if info(LR_ptr)=end_LR_type(q) then pop_LR;
+  end
+else push_LR(q)
+
+@ We use the fact that |q| now points to the node with \.{\\rightskip} glue.
+
+@<Insert LR nodes at the end...@>=
+if LR_ptr<>null then
+  begin s:=temp_head; r:=link(s);
+  while r<>q do
+    begin s:=r; r:=link(s);
+    end;
+  r:=LR_ptr;
+  while r<>null do
+    begin temp_ptr:=new_math(0,info(r));
+    link(s):=temp_ptr; s:=temp_ptr; r:=link(r);
+    end;
+  link(s):=q;
+  end
+
+@ Special \.{\\beginM} and \.{\\endM} nodes are inserted in cases where
+math nodes are discarded during line breaking or end up in different
+lines.  When the current lists ends with an \.{\\endM} node that node is
+temporarily removed and later reinserted when the last node is to be
+inspected or removed.  A final \.{\\endM} preceded by a |char_node| will
+not be removed.
+
+@<Declare \eTeX\ procedures for expanding and scanning@>=
+procedure remove_end_M;
+var @!p:pointer; {runs through the current list}
+begin p:=head;
+while link(p)<>tail do p:=link(p);
+if not is_char_node(p) then
+  begin LR_temp:=tail; link(p):=null; tail:=p;
+  end;
+end;
+
+@ @<Declare \eTeX\ procedures for expanding and scanning@>=
+procedure insert_end_M;
+label done;
+var @!p:pointer; {runs through the current list}
+begin if not is_char_node(tail) then
+ if (type(tail)=math_node)and(subtype(tail)=begin_M_code) then
+  begin free_node(LR_temp,small_node_size); p:=head;
+  while link(p)<>tail do p:=link(p);
+  free_node(tail,small_node_size); link(p):=null; tail:=p; goto done;
+  end;
+link(tail):=LR_temp; tail:=LR_temp;
+done: LR_temp:=null;
+end;
+
+@ @<Initialize the LR stack@>=
+put_LR(before) {this will never match}
+
+@ @<Adjust the LR stack for the |hp...@>=
+if end_LR(p) then
+  if info(LR_ptr)=end_LR_type(p) then pop_LR
+  else  begin incr(LR_problems); type(p):=kern_node; subtype(p):=explicit;
+    end
+else push_LR(p)
+
+@ @<Check for LR anomalies at the end of |hp...@>=
+begin if info(LR_ptr)<>before then
+  begin while link(q)<>null do q:=link(q);
+  repeat temp_ptr:=q; q:=new_math(0,info(LR_ptr)); link(temp_ptr):=q;
+  LR_problems:=LR_problems+10000; pop_LR;
+  until info(LR_ptr)=before;
+  end;
+if LR_problems>0 then
+  begin @<Report LR problems@>; goto common_ending;
+  end;
+pop_LR;
+if LR_ptr<>null then confusion("LR1");
+@:this can't happen LR1}{\quad LR1@>
+end
+
+@ @<Report LR problems@>=
+begin print_ln; print_nl("\endL or \endR problem (");@/
+print_int(LR_problems div 10000); print(" missing, ");@/
+print_int(LR_problems mod 10000); print(" extra");@/
+LR_problems:=0;
+end
+
+@ Breaking a paragraph into lines while \TeXXeT\ is disabled may result
+in lines whith unpaired math nodes.  Such hlists are silently accepted
+in the absence of text direction directives.
+
+@d LR_dir(#)==(subtype(#) div R_code) {text direction of a `math node'}
+
+@<Adjust the LR stack for the |hl...@>=
+begin if end_LR(p) then
+  if info(LR_ptr)=end_LR_type(p) then pop_LR
+  else  begin if subtype(p)>L_code then incr(LR_problems);
+    end
+else  begin push_LR(p);
+  if LR_dir(p)<>cur_dir then
+    @<Reverse an hlist segment and |goto reswitch|@>;
+  end;
+type(p):=kern_node;
+end
+
+@ @<Check for LR anomalies at the end of |hl...@>=
+begin while info(LR_ptr)<>before do
+  begin if info(LR_ptr)>L_code then LR_problems:=LR_problems+10000;
+  pop_LR;
+  end;
+pop_LR;
+end
+
+@ @d edge_node=style_node {a |style_node| does not occur in hlists}
+@d edge_node_size=style_node_size {number of words in an edge node}
+@d edge_dist(#)==depth(#) {new |left_edge| position relative to |cur_h|
+   (after |width| has been taken into account)}
+
+@<Declare procedures needed in |hlist_out|, |vlist_out|@>=
+function new_edge(@!s:small_number;@!w:scaled):pointer;
+  {create an edge node}
+var p:pointer; {the new node}
+begin p:=get_node(edge_node_size); type(p):=edge_node; subtype(p):=s;
+width(p):=w; edge_dist(p):=0; {the |edge_dist| field will be set later}
+new_edge:=p;
+end;
+
+@ @<Cases of |hlist_out| that arise...@>=
+edge_node: begin cur_h:=cur_h+width(p);
+  left_edge:=cur_h+edge_dist(p); cur_dir:=subtype(p);
+  end;
+
+@ We detach the hlist, start a new one consisting of just one kern node,
+append the reversed list, and set the width of the kern node.
+
+@<Reverse the complete hlist...@>=
+begin save_h:=cur_h; temp_ptr:=p; p:=new_kern(0); link(prev_p):=p;
+cur_h:=0; link(p):=reverse(this_box,null); width(p):=-cur_h;
+cur_h:=save_h; subtype(this_box):=reversed;
+end
+
+@ We detach the remainder of the hlist, replace the math node by
+an edge node, and append the reversed hlist segment to it; the tail of
+the reversed segment is another edge node and the remainder of the
+original list is attached to it.
+
+@<Reverse an hlist segment...@>=
+begin save_h:=cur_h; temp_ptr:=link(p); rule_wd:=width(p);
+free_node(p,small_node_size);
+cur_dir:=reflected; p:=new_edge(cur_dir,rule_wd); link(prev_p):=p;
+cur_h:=cur_h-left_edge+rule_wd;
+link(p):=reverse(this_box,new_edge(reflected,0));
+edge_dist(p):=cur_h; cur_dir:=reflected; cur_h:=save_h;
+goto reswitch;
+end
+
+@ The |reverse| function defined here is responsible to reverse the
+nodes of an hlist (segment). The first parameter |this_box| is the
+enclosing hlist node, the second parameter |t| is to become the tail of
+the reversed list, and the global variable |temp_ptr| is the head of the
+list to be reversed. We remove nodes from the original list and add them
+to the head of the new one.
+
+@<Declare procedures needed in |hlist_out|, |vlist_out|@>=
+function reverse(@!this_box,@!t:pointer):pointer;
+label reswitch,next_p,done;
+var l:pointer; {the new list}
+@!p:pointer; {the current node}
+@!q:pointer; {the next node}
+@!g_sign: normal..shrinking; {selects type of glue}
+@!m,@!n:halfword; {count of unmatched math nodes}
+begin g_sign:=glue_sign(this_box);
+l:=t; p:=temp_ptr; m:=min_halfword; n:=min_halfword;
+loop@+  begin while p<>null do
+    @<Move node |p| to the new list and go to the next node;
+    or |goto done| if the end of the reflected segment has been reached@>;
+  if (t=null)and(m=min_halfword)and(n=min_halfword) then goto done;
+  p:=new_math(0,info(LR_ptr)); LR_problems:=LR_problems+10000;
+    {manufacture one missing math node}
+  end;
+done:reverse:=l;
+end;
+
+@ @<Move node |p| to the new list...@>=
+reswitch: if is_char_node(p) then
+  repeat f:=font(p); c:=character(p);
+  cur_h:=cur_h+char_width(f)(char_info(f)(c));
+  q:=link(p); link(p):=l; l:=p; p:=q;
+  until not is_char_node(p)
+else @<Move the non-|char_node| |p| to the new list@>
+
+@ @<Move the non-|char_node| |p| to the new list@>=
+begin q:=link(p);
+case type(p) of
+hlist_node,vlist_node,rule_node,kern_node: rule_wd:=width(p);
+@t\4@>@<Cases of |reverse| that need special treatment@>@;
+edge_node: confusion("LR2");
+@:this can't happen LR2}{\quad LR2@>
+othercases goto next_p
+endcases;@/
+cur_h:=cur_h+rule_wd;
+next_p: link(p):=l;
+if type(p)=kern_node then if (rule_wd=0)or(l=null) then
+  begin free_node(p,small_node_size); p:=l;
+  end;
+l:=p; p:=q;
+end
+
+@ Here we have to remember that |add_glue| may have converted the glue
+node into a kern node.  If this is not the case we try to covert the
+glue node into a rule node.
+
+@<Cases of |reverse|...@>=
+glue_node: begin g:=glue_ptr(p); rule_wd:=width(g);
+if g_sign<>normal then add_glue(rule_wd);
+if subtype(p)>=a_leaders then
+  begin temp_ptr:=leader_ptr(p);
+  if type(temp_ptr)=rule_node then
+    begin delete_glue_ref(g); free_node(p,small_node_size);
+    p:=temp_ptr; width(p):=rule_wd;
+    end;
+  end;
+end;
+
+@ A ligature node is replaced by a char node.
+
+@<Cases of |reverse|...@>=
+ligature_node: begin flush_node_list(lig_ptr(p));
+temp_ptr:=p; p:=get_avail; mem[p]:=mem[lig_char(temp_ptr)]; link(p):=q;
+free_node(temp_ptr,small_node_size); goto reswitch;
+end;
+
+@ Math nodes in an inner reflected segment are modified, those at the
+outer level are changed into kern nodes.
+
+@<Cases of |reverse|...@>=
+math_node: begin rule_wd:=width(p);
+if end_LR(p) then
+  if info(LR_ptr)<>end_LR_type(p) then
+    begin type(p):=kern_node; incr(LR_problems);
+    end
+  else  begin pop_LR;
+    if n>min_halfword then
+      begin decr(n); decr(subtype(p)); {change |after| into |before|}
+      end
+    else  begin type(p):=kern_node;
+      if m>min_halfword then decr(m)
+      else @<Finish the reversed hlist segment and |goto done|@>;
+      end;
+    end
+else  begin push_LR(p);
+  if (n>min_halfword)or(LR_dir(p)<>cur_dir) then
+    begin incr(n); incr(subtype(p)); {change |before| into |after|}
+    end
+  else  begin type(p):=kern_node; incr(m);
+    end;
+  end;
+end;
+
+@ Finally we have found the end of the hlist segment to be reversed; the
+final math node is released and the remaining list attached to the
+edge node terminating the reversed segment.
+
+@<Finish the reversed...@>=
+begin free_node(p,small_node_size);
+link(t):=q; width(t):=rule_wd; edge_dist(t):=-cur_h-rule_wd; goto done;
+end
+
+@ @<Check for LR anomalies at the end of |s...@>=
+begin if LR_problems>0 then
+  begin @<Report LR problems@>; print_char(")"); print_ln;
+  end;
+if (LR_ptr<>null)or(cur_dir<>left_to_right) then confusion("LR3");
+@:this can't happen LR3}{\quad LR3@>
+end
+
+@ Some special actions are required for displayed equation in paragraphs
+with mixed direction texts.  First of all we have to set the text
+direction preceding the display.
+
+@<Set the value of |x| to the text direction before the display@>=
+if LR_save=null then x:=0
+else if info(LR_save)>=R_code then x:=-1@+else x:=1
+
+@ @<Prepare for display after an empty...@>=
+begin pop_nest; @<Set the value of |x|...@>;
+end
+
+@ When calculating the natural width, |w|, of the final line preceding
+the display, we may have to copy all or part of its hlist.  We copy,
+however, only those parts of the original list that are relevant for the
+computation of |pre_display_size|.
+@^data structure assumptions@>
+
+@<Declare subprocedures for |init_math|@>=
+procedure just_copy(@!p,@!h,@!t:pointer);
+label found,not_found;
+var @!r:pointer; {current node being fabricated for new list}
+@!words:0..5; {number of words remaining to be copied}
+begin while p<>null do
+  begin words:=1; {this setting occurs in more branches than any other}
+  if is_char_node(p) then r:=get_avail
+  else case type(p) of
+  hlist_node,vlist_node: begin r:=get_node(box_node_size);
+    mem[r+6]:=mem[p+6]; mem[r+5]:=mem[p+5]; {copy the last two words}
+    words:=5; list_ptr(r):=null; {this affects |mem[r+5]|}
+    end;
+  rule_node: begin r:=get_node(rule_node_size); words:=rule_node_size;
+    end;
+  ligature_node: begin r:=get_avail; {only |font| and |character| are needed}
+    mem[r]:=mem[lig_char(p)]; goto found;
+    end;
+  kern_node,math_node: begin r:=get_node(small_node_size);
+    words:=small_node_size;
+    end;
+  glue_node: begin r:=get_node(small_node_size); add_glue_ref(glue_ptr(p));
+    glue_ptr(r):=glue_ptr(p); leader_ptr(r):=null;
+    end;
+  whatsit_node:@<Make a partial copy of the whatsit...@>;
+  othercases goto not_found
+  endcases;
+  while words>0 do
+    begin decr(words); mem[r+words]:=mem[p+words];
+    end;
+  found: link(h):=r; h:=r;
+  not_found: p:=link(p);
+  end;
+link(h):=t;
+end;
+
+@ When the final line ends with R-text, the value |w| refers to the line
+reflected with respect to the left edge of the enclosing vertical list.
+
+@<Prepare for display after a non-empty...@>=
+if eTeX_ex then @<Let |j| be the prototype box for the display@>;
+v:=shift_amount(just_box);
+@<Set the value of |x|...@>;
+if x>=0 then
+  begin p:=list_ptr(just_box); link(temp_head):=null;
+  end
+else  begin v:=-v-width(just_box);
+  p:=new_math(0,begin_L_code); link(temp_head):=p;
+  just_copy(list_ptr(just_box),p,new_math(0,end_L_code));
+  cur_dir:=right_to_left;
+  end;
+v:=v+2*quad(cur_font);
+if TeXXeT_en then @<Initialize the LR stack@>
+
+@ @<Finish the natural width computation@>=
+if TeXXeT_en then
+  begin while LR_ptr<>null do pop_LR;
+  if LR_problems<>0 then
+    begin w:=max_dimen; LR_problems:=0;
+    end;
+  end;
+cur_dir:=left_to_right; flush_node_list(link(temp_head))
+
+@ In the presence of text direction directives we assume that any LR
+problems have been fixed by the |hpack| routine.  If the final line
+contains, however, text direction directives while \TeXXeT\ is disabled,
+then we set |w:=max_dimen|.
+
+@<Cases of `Let |d| be the natural...@>=
+math_node: begin d:=width(p);
+  if TeXXeT_en then @<Adjust the LR stack for the |init_math| routine@>
+  else if subtype(p)>=L_code then
+    begin w:=max_dimen; goto done;
+    end;
+  end;
+edge_node: begin d:=width(p); cur_dir:=subtype(p);
+  end;
+
+@ @<Adjust the LR stack for the |i...@>=
+if end_LR(p) then
+  begin if info(LR_ptr)=end_LR_type(p) then pop_LR
+  else if subtype(p)>L_code then
+    begin w:=max_dimen; goto done;
+    end
+  end
+else  begin push_LR(p);
+  if LR_dir(p)<>cur_dir then
+    begin just_reverse(p); p:=temp_head;
+    end;
+  end
+
+@ @<Declare subprocedures for |init_math|@>=
+procedure just_reverse(@!p:pointer);
+label found,done;
+var l:pointer; {the new list}
+@!t:pointer; {tail of reversed segment}
+@!q:pointer; {the next node}
+@!m,@!n:halfword; {count of unmatched math nodes}
+begin m:=min_halfword; n:=min_halfword;
+if link(temp_head)=null then
+  begin just_copy(link(p),temp_head,null); q:=link(temp_head);
+  end
+else  begin q:=link(p); link(p):=null; flush_node_list(link(temp_head));
+  end;
+t:=new_edge(cur_dir,0); l:=t; cur_dir:=reflected;
+while q<>null do
+  if is_char_node(q) then
+    repeat p:=q; q:=link(p); link(p):=l; l:=p;
+    until not is_char_node(q)
+  else  begin p:=q; q:=link(p);
+    if type(p)=math_node then
+      @<Adjust the LR stack for the |just_reverse| routine@>;
+    link(p):=l; l:=p;
+    end;
+goto done;
+found:width(t):=width(p); link(t):=q; free_node(p,small_node_size);
+done:link(temp_head):=l;
+end;
+
+@ @<Adjust the LR stack for the |j...@>=
+if end_LR(p) then
+  if info(LR_ptr)<>end_LR_type(p) then
+    begin type(p):=kern_node; incr(LR_problems);
+    end
+  else  begin pop_LR;
+    if n>min_halfword then
+      begin decr(n); decr(subtype(p)); {change |after| into |before|}
+      end
+    else  begin if m>min_halfword then decr(m)@+else goto found;
+      type(p):=kern_node;
+      end;
+    end
+else  begin push_LR(p);
+  if (n>min_halfword)or(LR_dir(p)<>cur_dir) then
+    begin incr(n); incr(subtype(p)); {change |before| into |after|}
+    end
+  else  begin type(p):=kern_node; incr(m);
+    end;
+  end
+
+@ The prototype box is an hlist node with the width, glue set, and shift
+amount of |just_box|, i.e., the last line preceding the display.  Its
+hlist reflects the current \.{\\leftskip} and \.{\\rightskip}.
+
+@<Let |j| be the prototype box for the display@>=
+begin if right_skip=zero_glue then j:=new_kern(0)
+else j:=new_param_glue(right_skip_code);
+if left_skip=zero_glue then p:=new_kern(0)
+else p:=new_param_glue(left_skip_code);
+link(p):=j; j:=new_null_box; width(j):=width(just_box);
+shift_amount(j):=shift_amount(just_box); list_ptr(j):=p;
+glue_order(j):=glue_order(just_box); glue_sign(j):=glue_sign(just_box);
+glue_set(j):=glue_set(just_box);
+end
+
+@ At the end of a displayed equation we retrieve the prototype box.
+
+@<Local variables for finishing...@>=
+@!j:pointer; {prototype box}
+
+@ @<Retrieve the prototype box@>=
+if mode=mmode then j:=LR_box
+
+@ @<Flush the prototype box@>=
+flush_node_list(j)
+
+@ The |app_display| procedure used to append the displayed equation
+and\slash or equation number to the current vertical list has three
+parameters:  the prototype box, the hbox to be appended, and the
+displacement of the hbox in the display line.
+
+@<Declare subprocedures for |after_math|@>=
+procedure app_display(@!j,@!b:pointer;@!d:scaled);
+var z:scaled; {width of the line}
+@!s:scaled; {move the line right this much}
+@!e:scaled; {distance from right edge of box to end of line}
+@!x:integer; {|pre_display_direction|}
+@!p,@!q,@!r,@!t,@!u:pointer; {for list manipulation}
+begin s:=display_indent; x:=pre_display_direction;
+if x=0 then shift_amount(b):=s+d
+else  begin z:=display_width; p:=b;
+  @<Set up the hlist for the display line@>;
+  @<Package the display line@>;
+  end;
+append_to_vlist(b);
+end;
+
+@ Here we construct the hlist for the display, starting with node |p|
+and ending with node |q|. We also set |d| and |e| to the amount of
+kerning to be added before and after the hlist (adjusted for the
+prototype box).
+
+@<Set up the hlist for the display line@>=
+if x>0 then e:=z-d-width(p)
+else  begin e:=d; d:=z-e-width(p);
+  end;
+if j<>null then
+  begin b:=copy_node_list(j); height(b):=height(p); depth(b):=depth(p);
+  s:=s-shift_amount(b); d:=d+s; e:=e+width(b)-z-s;
+  end;
+if subtype(p)=dlist then q:=p {display or equation number}
+else  begin {display and equation number}
+  r:=list_ptr(p); free_node(p,box_node_size);
+  if r=null then confusion("LR4");
+  if x>0 then
+    begin p:=r;
+    repeat q:=r; r:=link(r); {find tail of list}
+    until r=null;
+    end
+  else  begin p:=null; q:=r;
+    repeat t:=link(r); link(r):=p; p:=r; r:=t; {reverse list}
+    until r=null;
+    end;
+  end
+
+@ In the presence of a prototype box we use its shift amount and width
+to adjust the values of kerning and add these values to the glue nodes
+inserted to cancel the \.{\\leftskip} and \.{\\rightskip}.  If there is
+no prototype box (because the display is preceded by an empty
+paragraph), or if the skip parameters are zero, we just add kerns.
+
+The |cancel_glue| macro creates and links a glue node that is, together
+with another glue node, equivalent to a given amount of kerning.  We can
+use |j| as temporary pointer, since all we need is |j<>null|.
+
+@d cancel_glue(#)==j:=new_skip_param(#); cancel_glue_cont
+@d cancel_glue_cont(#)==link(#):=j; cancel_glue_cont_cont
+@d cancel_glue_cont_cont(#)==link(j):=#; cancel_glue_end
+@d cancel_glue_end(#)==j:=glue_ptr(#); cancel_glue_end_end
+@d cancel_glue_end_end(#)==
+stretch_order(temp_ptr):=stretch_order(j);
+shrink_order(temp_ptr):=shrink_order(j); width(temp_ptr):=#-width(j);
+stretch(temp_ptr):=-stretch(j); shrink(temp_ptr):=-shrink(j)
+
+@<Package the display line@>=
+if j=null then
+  begin r:=new_kern(0); t:=new_kern(0); {the widths will be set later}
+  end
+else  begin r:=list_ptr(b); t:=link(r);
+  end;
+u:=new_math(0,end_M_code);
+if type(t)=glue_node then {|t| is \.{\\rightskip} glue}
+  begin cancel_glue(right_skip_code)(q)(u)(t)(e); link(u):=t;
+  end
+else  begin width(t):=e; link(t):=u; link(q):=t;
+  end;
+u:=new_math(0,begin_M_code);
+if type(r)=glue_node then {|r| is \.{\\leftskip} glue}
+  begin cancel_glue(left_skip_code)(u)(p)(r)(d); link(r):=u;
+  end
+else  begin width(r):=d; link(r):=p; link(u):=r;
+  if j=null then
+    begin b:=hpack(u,natural); shift_amount(b):=s;
+    end
+  else list_ptr(b):=u;
+  end
+
+@ The |scan_tokens| feature of \eTeX\ defines the \.{\\scantokens}
+primitive.
+
+@<Generate all \eTeX...@>=
+primitive("scantokens",input,2);
+@!@:scan_tokens_}{\.{\\scantokens} primitive@>
+
+@ @<Cases of |input| for |print_cmd_chr|@>=
+else if chr_code=2 then print_esc("scantokens")
+
+@ @<Cases for |input|@>=
+else if cur_chr=2 then pseudo_start
+
+@ The global variable |pseudo_files| is used to maintain a stack of
+pseudo files.  The |info| field of each pseudo file points to a linked
+list of variable size nodes representing lines not yet processed: the
+|info| field of the first word contains the size of this node, all the
+following words contain ASCII codes.
+
+@<Glob...@>=
+@!pseudo_files:pointer; {stack of pseudo files}
+
+@ @<Set init...@>=
+pseudo_files:=null;
+
+@ The |pseudo_start| procedure initiates reading from a pseudo file.
+
+@<Declare \eTeX\ procedures for expanding and scanning@>=
+procedure@?pseudo_start; forward;@t\2@>
+
+@ @<Declare \eTeX\ procedures for token lists@>=
+procedure pseudo_start;
+var old_setting:0..max_selector; {holds |selector| setting}
+@!s:str_number; {string to be converted into a pseudo file}
+@!l,@!m:pool_pointer; {indices into |str_pool|}
+@!p,@!q,@!r:pointer; {for list construction}
+@!w: four_quarters; {four ASCII codes}
+@!nl,@!sz:integer;
+begin scan_general_text;
+old_setting:=selector; selector:=new_string;
+token_show(temp_head); selector:=old_setting;
+flush_list(link(temp_head));
+str_room(1); s:=make_string;
+@<Convert string |s| into a new pseudo file@>;
+flush_string;
+@<Initiate input from new pseudo file@>;
+end;
+
+@ @<Convert string |s| into a new pseudo file@>=
+str_pool[pool_ptr]:=si(" "); l:=str_start[s];
+nl:=si(new_line_char);
+p:=get_avail; q:=p;
+while l<pool_ptr do
+  begin m:=l;
+  while (l<pool_ptr)and(str_pool[l]<>nl) do incr(l);
+  sz:=(l-m+7)div 4;
+  if sz=1 then sz:=2;
+  r:=get_node(sz); link(q):=r; q:=r; info(q):=hi(sz);
+  while sz>2 do
+    begin decr(sz); incr(r);
+    w.b0:=qi(so(str_pool[m])); w.b1:=qi(so(str_pool[m+1]));
+    w.b2:=qi(so(str_pool[m+2])); w.b3:=qi(so(str_pool[m+3]));
+    mem[r].qqqq:=w; m:=m+4;
+    end;
+  w.b0:=qi(" "); w.b1:=qi(" "); w.b2:=qi(" "); w.b3:=qi(" ");
+  if l>m then
+    begin w.b0:=qi(so(str_pool[m]));
+    if l>m+1 then
+      begin  w.b1:=qi(so(str_pool[m+1]));
+      if l>m+2 then
+        begin  w.b2:=qi(so(str_pool[m+2]));
+        if l>m+3 then w.b3:=qi(so(str_pool[m+3]));
+        end;
+      end;
+    end;
+  mem[r+1].qqqq:=w;
+  if str_pool[l]=nl then incr(l);
+  end;
+info(p):=link(p); link(p):=pseudo_files; pseudo_files:=p
+
+@ @<Initiate input from new pseudo file@>=
+begin_file_reading; {set up |cur_file| and new level of input}
+line:=0; limit:=start; loc:=limit+1; {force line read}
+if tracing_scan_tokens>0 then
+  begin if term_offset>max_print_line-3 then print_ln
+  else if (term_offset>0)or(file_offset>0) then print_char(" ");
+  name:=19; print("( "); incr(open_parens); update_terminal;
+  end
+else name:=18
+
+@ Here we read a line from the current pseudo file into |buffer|.
+
+@<Declare \eTeX\ procedures for tracing and input@>=
+function pseudo_input: boolean; {inputs the next line or returns |false|}
+var p:pointer; {current line from pseudo file}
+@!sz:integer; {size of node |p|}
+@!w:four_quarters; {four ASCII codes}
+@!r:pointer; {loop index}
+begin last:=first; {cf.\ Matthew 19\thinspace:\thinspace30}
+p:=info(pseudo_files);
+if p=null then pseudo_input:=false
+else  begin info(pseudo_files):=link(p); sz:=ho(info(p));
+  if 4*sz-3>=buf_size-last then
+    @<Report overflow of the input buffer, and abort@>;
+  last:=first;
+  for r:=p+1 to p+sz-1 do
+    begin w:=mem[r].qqqq;
+    buffer[last]:=w.b0; buffer[last+1]:=w.b1;
+    buffer[last+2]:=w.b2; buffer[last+3]:=w.b3;
+    last:=last+4;
+    end;
+  if last>=max_buf_stack then max_buf_stack:=last+1;
+  while (last>first)and(buffer[last-1]=" ") do decr(last);
+  free_node(p,sz);
+  pseudo_input:=true;
+  end;
+end;
+
+@ When we are done with a pseudo file we `close' it.
+
+@<Declare \eTeX\ procedures for tracing and input@>=
+procedure pseudo_close; {close the top level pseudo file}
+var p,@!q: pointer;
+begin p:=link(pseudo_files); q:=info(pseudo_files);
+free_avail(pseudo_files); pseudo_files:=p;
+while q<>null do
+  begin p:=q; q:=link(p); free_node(p,ho(info(p)));
+  end;
+end;
+
+@ @<Dump the \eTeX\ state@>=
+while pseudo_files<>null do pseudo_close; {flush pseudo files}
+
+@ @<Generate all \eTeX...@>=
+primitive("readline",read_to_cs,1);@/
+@!@:read_line_}{\.{\\readline} primitive@>
+
+@ @<Cases of |read| for |print_cmd_chr|@>=
+else print_esc("readline")
+
+@ @<Handle \.{\\readline} and |goto done|@>=
+if j=1 then
+  begin while loc<=limit do {current line not yet finished}
+    begin cur_chr:=buffer[loc]; incr(loc);
+    if cur_chr=" " then cur_tok:=space_token
+    @+else cur_tok:=cur_chr+other_token;
+    store_new_token(cur_tok);
+    end;
+  goto done;
+  end
+
+@ The |cond| feature of \eTeX\ defines additional conditionals as well
+as the \.{\\unless} prefix.
+
+@d if_def_code=17 { `\.{\\ifdefined}' }
+@d if_cs_code=18 { `\.{\\ifcsname}' }
+
+@<Generate all \eTeX...@>=
+primitive("unless",expand_after,1);@/
+@!@:unless_}{\.{\\unless} primitive@>
+primitive("ifdefined",if_test,if_def_code);
+@!@:if_defined_}{\.{\\ifdefined} primitive@>
+primitive("ifcsname",if_test,if_cs_code);
+@!@:if_cs_name_}{\.{\\ifcsname} primitive@>
+
+@ @<Cases of |expandafter| for |print_cmd_chr|@>=
+else print_esc("unless")
+
+@ @<Cases of |if_test| for |print_cmd_chr|@>=
+if_def_code:print_esc("ifdefined");
+if_cs_code:print_esc("ifcsname");
+
+@ The result of a boolean condition is reversed when the conditional is
+preceded by \.{\\unless}.
+
+@<Negate a boolean conditional and |goto reswitch|@>=
+begin get_token;
+if (cur_cmd=if_test)and(cur_chr<>if_case_code) then
+  begin cur_chr:=cur_chr+unless_code; goto reswitch;
+  end;
+print_err("You can't use `"); print_esc("unless"); print("' before `");
+@.You can't use \\unless...@>
+print_cmd_chr(cur_cmd,cur_chr); print_char("'");
+help1("Continue, and I'll forget that it ever happened.");
+back_error;
+end
+
+@ The conditional \.{\\ifdefined} tests if a control sequence is
+defined.
+
+We need to reset |scanner_status|, since \.{\\outer} control sequences
+are allowed, but we might be scanning a macro definition or preamble.
+
+@<Cases for |conditional|@>=
+if_def_code:begin save_scanner_status:=scanner_status;
+  scanner_status:=normal;
+  get_next; b:=(cur_cmd<>undefined_cs);
+  scanner_status:=save_scanner_status;
+  end;
+
+@ The conditional \.{\\ifcsname} is equivalent to \.{\{\\expandafter}
+\.{\}\\expandafter} \.{\\ifdefined} \.{\\csname}, except that no new
+control sequence will be entered into the hash table (once all tokens
+preceding the mandatory \.{\\endcsname} have been expanded).
+
+@<Cases for |conditional|@>=
+if_cs_code:begin n:=get_avail; p:=n; {head of the list of characters}
+  repeat get_x_token;
+  if cur_cs=0 then store_new_token(cur_tok);
+  until cur_cs<>0;
+  if cur_cmd<>end_cs_name then @<Complain about missing \.{\\endcsname}@>;
+  @<Look up the characters of list |n| in the hash table, and set |cur_cs|@>;
+  flush_list(n);
+  b:=(eq_type(cur_cs)<>undefined_cs);
+  end;
+
+@ @<Look up the characters of list |n| in the hash table...@>=
+m:=first; p:=link(n);
+while p<>null do
+  begin if m>=max_buf_stack then
+    begin max_buf_stack:=m+1;
+    if max_buf_stack=buf_size then
+      overflow("buffer size",buf_size);
+@:TeX capacity exceeded buffer size}{\quad buffer size@>
+    end;
+  buffer[m]:=info(p) mod @'400; incr(m); p:=link(p);
+  end;
+if m>first+1 then
+  cur_cs:=id_lookup(first,m-first) {|no_new_control_sequence| is |true|}
+else if m=first then cur_cs:=null_cs {the list is empty}
+else cur_cs:=single_base+buffer[first] {the list has length one}
+
+@ The |protected| feature of \eTeX\ defines the \.{\\protected} prefix
+command for macro definitions.  Such macros are protected against
+expansions when lists of expanded tokens are built, e.g., for \.{\\edef}
+or during \.{\\write}.
+
+@<Generate all \eTeX...@>=
+primitive("protected",prefix,8);
+@!@:protected_}{\.{\\protected} primitive@>
+
+@ @<Cases of |prefix| for |print_cmd_chr|@>=
+else if chr_code=8 then print_esc("protected")
+
+@ \eTeX\ supports 256~classes of marks where \.{\\marks0} is a synonym
+for \.{\\mark}. Similarly there are 256~classes of topmarks etc.
+
+@<Generate all \eTeX...@>=
+primitive("marks",mark,marks_code);
+@!@:marks_}{\.{\\marks} primitive@>
+primitive("topmarks",top_bot_mark,top_mark_code+marks_code);
+@!@:top_marks_}{\.{\\topmarks} primitive@>
+primitive("firstmarks",top_bot_mark,first_mark_code+marks_code);
+@!@:first_marks_}{\.{\\firstmarks} primitive@>
+primitive("botmarks",top_bot_mark,bot_mark_code+marks_code);
+@!@:bot_marks_}{\.{\\botmarks} primitive@>
+primitive("splitfirstmarks",top_bot_mark,split_first_mark_code+marks_code);
+@!@:split_first_marks_}{\.{\\splitfirstmarks} primitive@>
+primitive("splitbotmarks",top_bot_mark,split_bot_mark_code+marks_code);
+@!@:split_bot_marks_}{\.{\\splitbotmarks} primitive@>
+
+@ We have to declare |mark_class| as local variable for |initialize|.
+
+@<Local variables for init...@>=
+@!mark_class:eight_bits; {a mark class}
+
+@* \[54] System-dependent changes.
+@z
+%---------------------------------------
Index: texk/web2c/mf.ch
diff -u texk/web2c/mf.ch:1.1.1.1 texk/web2c/mf.ch:1.3
--- texk/web2c/mf.ch:1.1.1.1	Fri Jul 18 17:01:58 1997
+++ texk/web2c/mf.ch	Mon Sep  8 22:55:42 1997
@@ -127,7 +127,7 @@
 @!lig_table_size=15000; {maximum number of ligature/kern steps, must be
   at least 255 and at most 32510}
 @!max_kerns=2500; {maximum number of distinct kern amounts}
-@!max_font_dimen=50; {maximum number of \&{fontdimen} parameters}
+@!max_font_dimen=60; {maximum number of \&{fontdimen} parameters}
 @#
 @!inf_main_memory = 2999;
 @!sup_main_memory = 8000000;
Index: texk/web2c/tex.ch
diff -u texk/web2c/tex.ch:1.1.1.1 texk/web2c/tex.ch:1.4
--- texk/web2c/tex.ch:1.1.1.1	Fri Jul 18 17:02:02 1997
+++ texk/web2c/tex.ch	Mon Oct 13 11:29:18 1997
@@ -558,7 +558,7 @@
 @d clear_terminal == do_nothing
 @z
 
-@x [3.35] l.1017 - Do `input_ln' in C => section not needed.
+@x [3.35] l.1017 - no non-local gotos.
 @<Report overflow of the input buffer, and abort@>=
 if format_ident=0 then
   begin write_ln(term_out,'Buffer size exceeded!'); goto final_end;
@@ -569,7 +569,15 @@
 @:TeX capacity exceeded buffer size}{\quad buffer size@>
   end
 @y
-Routine is implemented in C, module is not needed.
+@<Report overflow of the input buffer, and abort@>=
+if format_ident=0 then
+  begin write_ln(term_out,'Buffer size exceeded!'); uexit(1);
+@.Buffer size exceeded@>
+  end
+else begin cur_input.loc_field:=first; cur_input.limit_field:=last-1;
+  overflow("buffer size",buf_size);
+@:TeX capacity exceeded buffer size}{\quad buffer size@>
+  end
 @z
 
 @x [3.37] l.1055 - |init_terminal|, reading the command line.
@@ -689,13 +697,11 @@
 @!trick_buf:array[0..ssup_error_line] of ASCII_code; {circular buffer for
 @z
 
-@x [5.61] l.1556 - Print rest of banner, eliminate misleading `(no format preloaded)'.
-wterm(banner);
+@x [5.61] l.1557 - Print rest of banner, eliminate misleading `(no format preloaded)'.
 if format_ident=0 then wterm_ln(' (no format preloaded)')
 else  begin slow_print(format_ident); print_ln;
   end;
 @y
-wterm(banner);
 wterm(version_string);
 if format_ident>0 then slow_print(format_ident);
 print_ln;
@@ -1480,11 +1486,11 @@
   end;
 @z
 
-@x [29.536] l.10324 - Print rest of banner.
-begin wlog(banner);
+@x [29.536] l.10325 - Print rest of banner.
+slow_print(format_ident); print("  ");
 @y
-begin wlog(banner);
 wlog(version_string);
+slow_print(format_ident); print("  ");
 @z
 
 @x [29.536] l.10327 - Adjust for C string conventions.
@@ -2723,12 +2729,12 @@
   too_small(#)@+else format_debug (#)(x); undump_end_end
 @z
 
-@x [50,1307] l.23779 - texarray
-dump_int(@$);@/
+@x [50,1307] l.23780 - texarray
+dump_int(mem_bot);@/
 @y
-dump_int(@$);@/
 dump_int(max_halfword);@/
 dump_int(hash_high);
+dump_int(mem_bot);@/
 @z
 
 %%%%%%%% dynamic hyph_size
@@ -2741,10 +2747,6 @@
 @x [50.1308] l.23793 - texarray
 x:=fmt_file^.int;
 if x<>@$ then goto bad_fmt; {check that strings are the same}
-undump_int(x);
-if x<>mem_bot then goto bad_fmt;
-undump_int(x);
-if x<>mem_top then goto bad_fmt;
 @y
 @+init
 if ini_version then
@@ -2755,6 +2757,13 @@
 undump_int(x);
 format_debug('string pool checksum')(x);
 if x<>@$ then goto bad_fmt; {check that strings are the same}
+@z
+@x l.23795 - this was split to work with e-TeX patch
+undump_int(x);
+if x<>mem_bot then goto bad_fmt;
+undump_int(x);
+if x<>mem_top then goto bad_fmt;
+@y
 undump_int(x);
 if x<>max_halfword then goto bad_fmt; {check |max_halfword|}
 undump_int(hash_high);
@@ -3407,13 +3416,16 @@
     hash_size:1, '+', hash_extra:1);@/
 @z
 
-@x [51.1335] l.24335 - Only do dump if ini.
+@x [51.1335] l.24335 - Only do dump if ini.   Split to work with etex.ch.
   begin @!init for c:=top_mark_code to split_bot_mark_code do
-    if cur_mark[c]<>null then delete_token_ref(cur_mark[c]);
-  store_fmt_file; return;@+tini@/
 @y
   begin @!init if ini_version then
     begin for c:=top_mark_code to split_bot_mark_code do
+@z
+@x l.24336
+    if cur_mark[c]<>null then delete_token_ref(cur_mark[c]);
+  store_fmt_file; return;@+tini@/
+@y
       if cur_mark[c]<>null then delete_token_ref(cur_mark[c]);
     store_fmt_file; return;
     end;@+tini@/
Index: texk/web2c/tex.ech
diff -u /dev/null texk/web2c/tex.ech:1.1
--- /dev/null	Wed Nov  5 23:19:53 1997
+++ texk/web2c/tex.ech	Sun Oct 12 19:44:39 1997
@@ -0,0 +1,13 @@
+% (web2)c doesn't like variable-length arrays.
+@x [22]
+@!eof_seen : array[1..max_in_open] of boolean; {has eof been seen?}
+@y
+@!eof_seen : ^boolean; {has eof been seen?}
+@z
+
+@x
+  xmalloc_array (line_stack, max_in_open);
+@y
+  xmalloc_array (line_stack, max_in_open);
+  xmalloc_array (eof_seen, max_in_open);
+@z
Index: texk/web2c/triptrapdiff.pl
diff -u /dev/null texk/web2c/triptrapdiff.pl:1.3
--- /dev/null	Wed Nov  5 23:19:53 1997
+++ texk/web2c/triptrapdiff.pl	Wed Oct 22 01:17:20 1997
@@ -0,0 +1,186 @@
+#!/usr/athena/bin/perl
+# $Header: /afs/sipb.mit.edu/project/tex-dev/repository/texk/web2c/triptrapdiff.pl,v 1.3 1997/10/22 05:17:20 amu Exp $
+# Originally by bert; minor modifications by amu.
+# defaults
+
+$th_glue = 0.001;		# discrepancy tolerance glue, in fil's
+$th_step = 300;			# tolerance for DVI positions, in 1/65536in
+
+# verbosity control
+
+$showdelta = 1;
+$showstats = 1;
+
+# arguments
+
+($fn1 = shift(@ARGV))
+    || die __FILE__," (line ",__LINE__,"): Two filename arguments required!\n";
+($fn2 = shift(@ARGV))
+    || die __FILE__," (line ",__LINE__,"): Two filename arguments required!\n";
+
+open($fn1, $fn1) || die __FILE__," (line ",__LINE__,": Can't open $fn1!\n";
+open($fn2, $fn2) || die __FILE__," (line ",__LINE__,": Can't open $fn2!\n";
+
+# main loop
+
+while(1) {
+    ($str1,$eof1,$ln1) = &readline($fn1);
+    ($str2,$eof2,$ln2) = &readline($fn2);
+
+    if ($eof1 && $eof2) { exit 0; }
+    if ($eof1) {
+	print "\@\@ Mismatch: $fn2 is longer than $fn1.\n";
+	print "\@\@ Offending line ($fn2 line $ln2):\n$str2";
+	&error(17);
+    }
+    if ($eof2) {
+
+	print "\@\@ Mismatch: $fn1 is longer than $fn2.\n";
+	print "\@\@ Offending line ($fn1 line $ln1):\n$str1";
+	&error(17);
+    }
+
+    $err = &match($str1,$str2);
+    if ($err) {
+	print "\@\@ Mismatch: $err.\n";
+	print "\@\@ Offending lines:\n";
+	print "   $fn1 line $ln1:\n$str1";
+	print "--------\n";
+	print "   $fn2 line $ln2:\n$str2";
+	&error(17);
+    }
+}
+
+# compare two lines
+sub match {
+    local($line1,$line2) = @_;
+
+    # if they're equal, they're equal.
+    return undef if ($line1 eq $line2);
+
+    # if both say `glue set', check if the differences are OK.
+    if ((@m1 = ($line1 =~ /^\\[hv]box(.*)glue set ([\d.]+)fil/)) &&
+	(@m2 = ($line2 =~ /^\\[hv]box(.*)glue set ([\d.]+)fil/))) {
+	return 'box dimensions differ' unless ($m1[0] eq $m2[0]);
+	$glue = &abs($m1[1]-$m2[1]);
+	return 'difference exceeds $th_glue' if ($glue > $th_glue);
+	printf "\@\@ OK glue set: %8.5ffil ($m1[1] vs $m2[1])\n", $glue
+	    if $showdelta;
+	return undef;
+    }
+
+    # positioning commands
+    if ((@m1 = ($line1 =~ /^(\d+):\s+(down|y|z|right|w|x)(\d)\s+(\d+)\s*$/)) &&
+	(@m2 = ($line2 =~ /^(\d+):\s+(down|y|z|right|w|x)(\d)\s+(\d+)\s*$/))) {
+	return 'positions are different' unless ($m1[0] eq $m2[0]);
+	return 'commands are different'
+	    unless (($m1[1] eq $m2[1]) && ($m1[2] eq $m2[2]));
+	$step = &abs($m1[3]-$m2[3]);
+	return 'difference exceeds $th_step' if ($step > $th_step);
+	printf "\@\@ OK $m1[1]$m1[2]: $step ($m1[3] vs $m2[3])\n" if $showdelta;
+	return undef;
+    }
+
+    # usage stats
+    if ((@m1 = ($line1 =~ /^\s*(\d+) ([a-z ]+) out of [0-9+]+$/)) &&
+	(@m2 = ($line2 =~ /^\s*(\d+) ([a-z ]+) out of [0-9+]+$/)))
+    {
+	return 'usage stats are of different types' unless
+	    ($m1[1] eq $m2[1] || "$m1[1]s" eq $m2[1] || $m1[1] eq "$m2[1]s");
+	print "\@\@ usage of $m1[1]: $m1[0] vs $m2[0]\n" if $showstats;
+	return undef if ($m1[0] eq $m2[0]);
+	print "\@\@ WARNING: usage stats for $m1[1] differ ($m1[0] vs $m2[0])\n";
+	return undef;
+    }
+    if ((@m1 = ($line1 =~ /^String usage (\d+&\d+) /)) &&
+	(@m2 = ($line2 =~ /^String usage (\d+&\d+) /))) {
+	print "\@\@ string usage: $m1[0] vs $m2[0]\n" if $showstats;
+	print "\@\@ WARNING: string usage differs ($m1[0] vs $m2[0])\n"
+	    unless ($m1[0] eq $m2[0]);
+	return undef;
+    }
+    if ((@m1 = ($line1 =~ /^at most (\d+) strings of total length (\d+)/)) &&
+	(@m2 = ($line2 =~ /^at most (\d+) strings of total length (\d+)/))) {
+	$s1 = "$m1[0]&$m1[1]";
+	$s2 = "$m2[0]&$m2[1]";
+	print "\@\@ string usage: $s1 vs $s2\n" if $showstats;
+	print "\@\@ WARNING: string usage differs ($s1 vs $s2)\n"
+	    unless ($m1[0] eq $m2[0]);
+	return undef;
+    }
+    if ((@m1 = ($line1 =~ /^Hyphenation trie of length (\d+) has (\d+) ops out of \d+/)) &&
+	(@m2 = ($line2 =~ /^Hyphenation trie of length (\d+) has (\d+) ops out of \d+/))) {
+	print "\@\@ Hyphenation trie length: $m1[0] vs $m2[0]\n" if $showstats;
+	print "\@\@ WARNING: hyphenation tree length differs ($m1[0] vs $m2[0])\n"
+	    unless ($m1[0] eq $m2[0]);
+	print "\@\@ Number of hyphenation trie ops: $m1[1] vs $m2[1]\n" if $showstats;
+	print "\@\@ WARNING: number of hyphenation tree ops differs ($m1[1] vs $m2[1])\n"
+	    unless ($m1[1] eq $m2[1]);
+	return undef;
+    }
+
+    # ignore changes in whitespace
+    $line1b = " $line1 "; $line1b =~ s/\s+/ /g;
+    $line2b = " $line2 "; $line2b =~ s/\s+/ /g;
+    if ($line1b eq $line2b) {
+	print "\@\@ ignoring whitespace difference\n";
+	return undef;
+    }
+
+    # oops, I guess we are stuck.
+    return 'the lines are... different';
+}
+
+# absolute values
+sub abs { (@_[0] >= 0) ? @_[0] : -@_[0] }
+
+# `trivial' lines, i.e. banners, should be ignored.
+sub trivial {
+    local($_) = @_;
+    return (/^This is (TeX|e-TeX|METAFONT|DVItype|GFtype|MetaPost),( C)? Version/
+	    || /^\s*'\s*(TeX|METAFONT) output [\d.:]+'\s*$/
+	    || /^\s*\((preloaded )?(format=trip|base=trap|mem=trap) [\d.]+\)\s*$/
+	    || /^\s*\d+ strings of total length \d+\s*$/
+	    || /^\s*out of \d+w,\d+h,\d+d,\d+i,\d+l,\d+k,\d+e,\d+p\)\s*$/
+	    || /^\s*\d+i,\d+n,\d+p,\d+b stack positions out of \d+i,\d+n,\d+p,\d+b/
+	    || /^\**\s*\&tr[ia]p\s+tr[ia]p\s/
+	    || /^\**\((trip.tex|trap.mf)/
+	    || /^\s*(write|\\openout)\d+ = /
+	    || /^\s*%%CreationDate:/
+	    || /^\s*\d+ string compactions \(moved \d+ characters, \d+ strings\)/
+	    || /^\s*entering (compatibility|extended) mode/
+	    || /^\s*$/);
+}
+
+# read in a line from the filehandle passed in as argument
+sub readline {
+    local($file) = @_[0];
+    do {
+	local($line) = scalar(<$file>);
+	print $line if $printlines;
+	if (! $line) {
+	    return ('', 1, $.);
+	}
+    } while (&trivial($line));
+    print "$file($.): $line" if $printlines;
+    return ($line, 0, $.);
+}
+
+# flag an error
+sub error {
+    print <<"EndOfMessage";
+\@\@ I found a mismatch that I can't account for.
+\@\@ That can mean one of two things: either trip/trap just failed, or
+\@\@ the rules I use to determine allowable differences are incomplete.
+\@\@ In any case, a human with a clue should look at the two files I was
+\@\@ comparing and figure out what's going on.
+\@\@
+\@\@ (If you are the responsible human and are looking for the clue: see
+\@\@ web2c/tex/TeXtrip/tripman.tex and web2c/mf/MFtrap/trapman.tex.)
+\@\@
+\@\@ If trip/trap did fail, try compiling with less or no optimization.
+\@\@ Changes won't take effect unless you make clean (or clean-triptrap)!
+EndOfMessage
+
+    exit $_[0];
+}
Index: texk/web2c/tie/MANIFEST
diff -u /dev/null texk/web2c/tie/MANIFEST:1.1
--- /dev/null	Wed Nov  5 23:20:00 1997
+++ texk/web2c/tie/MANIFEST	Tue Sep  2 11:51:39 1997
@@ -0,0 +1,21 @@
+README		guess what, but read it before proceeding
+MANIFEST	this list of files
+
+Makefile.cweb	UN*X Makefile to create tie from the sources
+		(requires a working ctangle processor for source changes)
+tie.w		the source of tie, written in CWEB
+tie.c		a pretangled version of tie.w
+
+tie.tie		a small test suite (master) 
+tie.cf1		 with several change files
+tie.cf2
+tie.cf3
+tie.chf.gen	the supposed to be generated merged change file
+tie.master.gen	the supposed to be generated new master file
+
+tiedoc.tex	a short introduction on tie (LaTeX source)
+
+tie.1		a UN*X style man page for tie
+tie.1.dvi	a `groff'ed version on man page tie.1
+tie.1.nroffed	an `nroff'ed version of man page tie.1, backspaces
+			for underlining or overstriking removed
Index: texk/web2c/tie/Makefile.cweb
diff -u /dev/null texk/web2c/tie/Makefile.cweb:1.1
--- /dev/null	Wed Nov  5 23:20:00 1997
+++ texk/web2c/tie/Makefile.cweb	Tue Sep  2 11:51:39 1997
@@ -0,0 +1,38 @@
+#
+#   Makefile for tie distribution		-	21 Dec 92
+#
+#   This file makes TIE and needs ctangle from cweb distribution.
+#   Try `touch tie.c' first, if you don't have ctangle.
+#
+
+CTANGLE=ctangle
+BINDIR=.
+TIE=$(BINDIR)/tie
+
+CFLAGS=
+LDFLAGS=-s
+
+default:        tie
+
+
+# TIE
+tie.o: tie.c
+
+tie: tie.o
+	$(CC) $(LDFLAGS) $(CFLAGS) -o $(TIE) tie.o
+
+tie.c: tie.w
+	$(CTANGLE) tie
+
+
+clean:
+	rm -f tie.o tie.outc tie.outm tie.tex tie.log tie.toc tiedoc.log
+
+veryclean: clean
+	rm -f $(BINDIR)/tie tie.dvi tiedoc.dvi tiedoc.aux
+
+ttest:  $(TIE)
+	$(TIE) -c tie.outc tie.tie tie.cf?
+	diff tie.outc tie.chf.gen
+	$(TIE) -m tie.outm tie.tie tie.cf?
+	diff tie.outm tie.master.gen
Index: texk/web2c/tie/Makefile.in
diff -u /dev/null texk/web2c/tie/Makefile.in:1.3
--- /dev/null	Wed Nov  5 23:20:00 1997
+++ texk/web2c/tie/Makefile.in	Tue Sep  9 00:32:23 1997
@@ -0,0 +1,11 @@
+ac_include ../make/paths.make
+ac_include ../make/common.make
+ac_include ../make/programs.make
+ac_include kpathsea.make
+
+tie: tie.o
+	$(kpathsea_link) tie.o $(LOADLIBES)
+
+install: tie
+	$(SHELL) $(top_srcdir)/../mkdirchain $(bindir)
+	$(INSTALL_PROGRAM) tie $(bindir)/tie
Index: texk/web2c/tie/README
diff -u /dev/null texk/web2c/tie/README:1.1
--- /dev/null	Wed Nov  5 23:20:00 1997
+++ texk/web2c/tie/README	Tue Sep  2 11:51:39 1997
@@ -0,0 +1,58 @@
+This is the README file of the `tie' distribution.
+ The current version is 2.4.
+ This file was created on 18 Dec 92.
+ This file was updated on 15 Jul 93.
+
+
+SUBJECT:
+
+`Tie' is a program which was first developed to allow WEB programmers
+(be it Pascal-, C- or any other WEB) to add more than one change file
+to their programs.
+
+ But it can be used to create new versions of the WEB file with
+incorporated changes as well. This feature does not depend on any
+special WEB dialect, nor on using WEB at all, as the only controls to
+be interpreted are the change requests in the change files (delimited
+by @x, @y and @z).
+ This makes `tie' also usable for any other language, or even data
+files. See the documentation tiedoc.tex and the example file tie.tie.
+
+ Actually, this gives a second file update mechanism besides `patch'.
+Whereas patch relies on line numbers and/or precise contexts produced
+by diff, tie depends on the order of changes and on a an amount of
+context lines determined manually.
+
+
+REQUIREMENTS:
+
+This version of `tie' is written in CWEB. To preprocess and compile
+the source you will need a working `ctangle'.
+ A pretangled tie.c is supplied which has been compiled successfully
+on a variety of workstations using either the manufacturer supplied
+C compiler in the K&R or ANSI version, or gcc (version 1.40).
+ Please note, that the CWEB by Silvio Levy and Donald E. Knuth must
+be at least at version 2.8, to process and compile `tie' without
+problems.
+
+
+DISTRIBUTION:
+
+The reference version of tie may be retrieved by anonymous ftp from
+
+	ftp.th-darmstadt.de [130.83.55.75]
+	directory pub/programming/literate-programming/Tools
+	file tie-<version>.tar.Z
+
+where <version> is the most current version number.
+ See the source file tie.w for details of the distribution policy.
+
+
+BUGS/ENHANCEMENTS:
+
+If you detect bugs in the implementation of `tie' or have 
+suggestions to enhance functionality or improve portability, 
+please send a message to
+
+	Klaus Guntermann <guntermann@iti.informatik.th-darmstadt.de>
+
Index: texk/web2c/tie/tie.1
diff -u /dev/null texk/web2c/tie/tie.1:1.1
--- /dev/null	Wed Nov  5 23:20:00 1997
+++ texk/web2c/tie/tie.1	Tue Sep  2 11:51:40 1997
@@ -0,0 +1,42 @@
+.TH TIE 1L 9/24/92
+.SH NAME
+tie \- merge or apply WEB change files
+.SH SYNOPSIS
+.B tie
+.B \-c|\-m
+.I outputfile masterfile changefile1
+[
+.I ... changefile9
+]
+
+.SH DESCRIPTION
+The
+.I tie
+program is  used to process multiple change  files  used  with the WEB
+system  for  literate  programming. The WEB programs  allow  to  apply
+patches to a source file (the
+.IR masterfile )
+by  means of a number of change files (often only a single change file
+is allowed).
+.I Tie
+can be used  to either merge up to nine change files into a single one
+or to apply the changes to the
+.I masterfile
+in order to create a new one. Output of either the  new change file or
+the patched master file goes into
+.I outputfile.
+.SS OPTIONS
+.TP
+.B \-c
+Create a single change file from the given
+.I changefiles.
+.TP
+.B \-m
+Create a new master file by applying the given
+.I changefiles.
+.SH "SEE ALSO"
+.br
+web(1), cweb(1l).
+.SH "AUTHOR"
+Klaus Guntermann, TH Darmstadt, Institut f. Theoretische Informatik. Man page
+by Joachim Schnitter, TH Darmstadt, Phys. Chemie I.
Index: texk/web2c/tie/tie.1.dvi
Index: texk/web2c/tie/tie.1.nroffed
diff -u /dev/null texk/web2c/tie/tie.1.nroffed:1.1
--- /dev/null	Wed Nov  5 23:20:00 1997
+++ texk/web2c/tie/tie.1.nroffed	Tue Sep  2 11:51:40 1997
@@ -0,0 +1,66 @@
+
+
+
+     TIE(1L)                     (9/24/92)                     TIE(1L)
+
+
+
+     NAME
+          tie - merge or apply WEB change files
+
+     SYNOPSIS
+          tie -c|-m outputfile masterfile changefile1 [ ...
+            changefile9 ]
+
+
+     DESCRIPTION
+          The  tie  program is  used to process multiple change  files
+          used  with  the  WEB system  for  literate  programming. The
+          WEB  programs  allow  to apply patches to a source file (the
+          masterfile) by  means of  a number  of change  files  (often
+          only a single change file is allowed).  Tie  can  be used to
+          either merge up to nine change files into a single one or to
+          apply the changes to the masterfile in order to create a new
+          one. Output of  either  the  new  change file or the patched
+          master file goes into outputfile.
+
+        OPTIONS
+          -c   Create a single change file from the given masterfile.
+
+          -m   Create a new master file by applying the given
+               changefiles.
+
+     SEE ALSO
+          web(1), cweb(1l).
+
+     AUTHOR
+          Klaus Guntermann, TH Darmstadt, Institut f. Theoretische
+          Informatik. Man page by Joachim Schnitter, TH Darmstadt,
+          Phys. Chemie I.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+     Page 1                                         (printed 12/17/92)
+
+
+
Index: texk/web2c/tie/tie.c
diff -u /dev/null texk/web2c/tie/tie.c:1.1
--- /dev/null	Wed Nov  5 23:20:00 1997
+++ texk/web2c/tie/tie.c	Tue Sep  2 11:51:41 1997
@@ -0,0 +1,920 @@
+#define banner "This is TIE, CWEB Version 2.4."
+#define copyright  \
+"Copyright (c) 1989,1992 by THD/ITI. All rights reserved." \
+ \
+
+#define incr(v)v+= 1
+#define decr(v)v-= 1
+#define loop while(1)
+#define do_nothing 
+#define false 0
+#define true 1
+#define spotless 0
+#define troublesome 1
+#define fatal 2 \
+
+#define first_text_char 0
+#define last_text_char 255 \
+
+#define map_xchr(c)(text_char)(c) \
+
+#define map_xord(c)(ASCII_Code)(c) \
+ \
+
+#define tab_mark 9
+#define nl_mark 10
+#define form_feed 12 \
+ \
+
+#define term_out stdout
+#define print(a)fprintf(term_out,a)
+#define print2(a,b)fprintf(term_out,a,b)
+#define print3(a,b,c)fprintf(term_out,a,b,c)
+#define print_c(v)fputc(v,term_out);
+#define new_line(v)fputc('\n',v)
+#define term_new_line new_line(term_out) \
+
+#define print_ln(v){fprintf(term_out,v);term_new_line;} \
+
+#define print2_ln(a,b){print2(a,b);term_new_line;}
+#define print3_ln(a,b,c){print3(a,b,c);term_new_line;} \
+
+#define print_nl(v){term_new_line;print(v);} \
+
+#define print2_nl(a,b){term_new_line;print2(a,b);} \
+ \
+
+#define update_terminal fflush(term_out) \
+ \
+ \
+ \
+ \
+
+#define error_loc(m)err_loc(m);history= troublesome;}
+#define err_print(m){print_nl(m);error_loc \
+
+#define fatal_error(m){ \
+print(m);print_c('.');history= fatal; \
+term_new_line;jump_out(); \
+} \
+ \
+
+#define jump_out()exit(1) \
+ \
+ \
+ \
+ \
+
+#define none (max_file_index+1) \
+
+/*2:*/
+#line 112 "tie.w"
+
+/*15:*/
+#line 478 "tie.w"
+
+#include <stdio.h>
+
+
+/*:15*//*16:*/
+#line 486 "tie.w"
+
+#ifdef __STDC__
+#include <stdlib.h>
+#else
+#include <malloc.h>
+#endif
+
+/*:16*/
+#line 113 "tie.w"
+
+/*5:*/
+#line 142 "tie.w"
+
+#define buf_size 512 
+#define max_file_index 9
+
+
+
+
+/*:5*/
+#line 114 "tie.w"
+
+/*4:*/
+#line 133 "tie.w"
+
+typedef int boolean;
+typedef char*string;
+
+
+/*:4*//*7:*/
+#line 224 "tie.w"
+
+#define max_ASCII (126+1)
+typedef unsigned char ASCII_Code;
+
+
+
+/*:7*//*8:*/
+#line 250 "tie.w"
+
+typedef unsigned char text_char;
+typedef FILE*text_file;
+
+
+/*:8*//*18:*/
+#line 529 "tie.w"
+
+#define search 0
+#define test 1
+#define reading 2
+#define ignore 3
+typedef int in_file_modes;
+#define unknown 0
+#define master 1
+#define chf 2
+typedef int file_types;
+
+
+/*:18*//*19:*/
+#line 547 "tie.w"
+
+#define normal 0
+#define pre 1
+#define post 2
+typedef int out_md_type;
+
+
+/*:19*//*20:*/
+#line 557 "tie.w"
+
+typedef int buffer_index;
+typedef int file_index;
+
+
+/*:20*//*21:*/
+#line 566 "tie.w"
+
+typedef struct _idsc{
+string name_of_file;
+ASCII_Code buffer[buf_size];
+in_file_modes mode;
+long line;
+file_types type_of_file;
+buffer_index limit;
+text_file the_file;
+}input_description;
+
+
+/*:21*/
+#line 115 "tie.w"
+
+/*6:*/
+#line 159 "tie.w"
+
+static int history= spotless;
+
+
+
+/*:6*//*9:*/
+#line 270 "tie.w"
+
+static ASCII_Code xord[last_text_char+1];
+
+static text_char xchr[max_ASCII+1];
+
+
+
+/*:9*//*22:*/
+#line 582 "tie.w"
+
+static file_index actual_input,test_input,no_ch;
+static file_types prod_chf= unknown;
+static out_md_type out_mode;
+
+
+/*:22*//*23:*/
+#line 594 "tie.w"
+
+static input_description*input_organization[max_file_index+1];
+
+
+
+
+
+/*:23*//*26:*/
+#line 641 "tie.w"
+
+static boolean input_has_ended= false;
+
+
+/*:26*//*35:*/
+#line 801 "tie.w"
+
+static text_file out_file;
+static string out_name;
+
+
+/*:35*/
+#line 116 "tie.w"
+
+/*31:*/
+#line 744 "tie.w"
+
+void err_loc(i)
+int i;
+{
+print3_ln(" (file %s, l.%ld).",
+input_organization[i]->name_of_file,
+input_organization[i]->line);
+}
+
+
+/*:31*/
+#line 117 "tie.w"
+
+/*24:*/
+#line 616 "tie.w"
+
+void get_line(i)
+file_index i;
+{register input_description*inp_desc= input_organization[i];
+if(inp_desc->mode==ignore)return;
+if(feof(inp_desc->the_file))
+/*25:*/
+#line 630 "tie.w"
+
+{
+inp_desc->mode= ignore;
+inp_desc->limit= -1;
+if(inp_desc->type_of_file==master)input_has_ended= true;
+return;
+}
+
+
+/*:25*/
+#line 622 "tie.w"
+
+/*27:*/
+#line 655 "tie.w"
+
+{int final_limit;
+int c;
+/*28:*/
+#line 679 "tie.w"
+
+incr(inp_desc->line);
+if(inp_desc->type_of_file==master&&inp_desc->line%100==0){
+if(inp_desc->line%500==0)print2("%ld",inp_desc->line);
+else print_c('.');
+update_terminal;
+}
+
+
+/*:28*/
+#line 659 "tie.w"
+
+inp_desc->limit= final_limit= 0;
+while(inp_desc->limit<buf_size){
+c= fgetc(inp_desc->the_file);
+/*29:*/
+#line 696 "tie.w"
+
+if(c==EOF){
+if(inp_desc->limit<=0){
+inp_desc->mode= ignore;
+inp_desc->limit= -1;
+if(inp_desc->type_of_file==master)input_has_ended= true;
+return;
+}else{
+c= nl_mark;
+break;
+}
+}
+
+
+/*:29*/
+#line 664 "tie.w"
+
+inp_desc->buffer[inp_desc->limit++]= c= map_xord(c);
+if(c==nl_mark)break;
+if(c!=32&&c!=tab_mark)
+final_limit= inp_desc->limit;
+}
+/*30:*/
+#line 712 "tie.w"
+
+if(c!=nl_mark){
+err_print("! Input line too long")(i);
+
+while((c= fgetc(inp_desc->the_file))!=EOF&&map_xord(c)!=nl_mark)
+do_nothing;
+}
+
+
+
+
+
+/*:30*/
+#line 670 "tie.w"
+
+inp_desc->limit= final_limit;
+}
+
+
+/*:27*/
+#line 623 "tie.w"
+
+}
+
+
+/*:24*//*38:*/
+#line 850 "tie.w"
+
+boolean lines_dont_match(i,j)
+file_index i,j;
+{
+buffer_index k,lmt;
+if(input_organization[i]->limit!=input_organization[j]->limit)
+return(true);
+lmt= input_organization[i]->limit;
+for(k= 0;k<lmt;k++)
+if(input_organization[i]->buffer[k]!=input_organization[j]->buffer[k])
+return(true);
+return(false);
+}
+
+
+/*:38*//*39:*/
+#line 871 "tie.w"
+
+void init_change_file(i,b)
+file_index i;boolean b;
+{register input_description*inp_desc= input_organization[i];
+/*40:*/
+#line 885 "tie.w"
+
+loop{ASCII_Code c;
+get_line(i);
+if(inp_desc->mode==ignore)return;
+if(inp_desc->limit<2)continue;
+if(inp_desc->buffer[0]!=64)continue;
+c= inp_desc->buffer[1];
+if(c>=88&&c<=90)
+c+= 122-90;
+if(c==120)break;
+if(c==121||c==122)
+if(b)
+err_print("! Where is the matching @x?")(i);
+
+}
+
+
+/*:40*/
+#line 875 "tie.w"
+
+/*41:*/
+#line 904 "tie.w"
+
+do{
+get_line(i);
+if(inp_desc->mode==ignore){
+err_print("! Change file ended after @x")(i);
+
+return;
+}
+}while(inp_desc->limit<=0);
+
+
+/*:41*/
+#line 876 "tie.w"
+
+}
+
+
+/*:39*//*42:*/
+#line 918 "tie.w"
+
+void put_line(j)
+file_index j;
+{buffer_index i;
+buffer_index lmt;
+ASCII_Code*p;
+lmt= input_organization[j]->limit;
+p= input_organization[j]->buffer;
+for(i= 0;i<lmt;i++)fputc(map_xchr(*p++),out_file);
+new_line(out_file);
+}
+
+
+/*:42*//*43:*/
+#line 934 "tie.w"
+
+boolean e_of_ch_module(i)
+file_index i;
+{register input_description*inp_desc= input_organization[i];
+if(inp_desc->limit<0){
+print_nl("! At the end of change file missing @z ");
+
+print2("%s",input_organization[i]->name_of_file);
+term_new_line;
+return(true);
+}else if(inp_desc->limit>=2)if(inp_desc->buffer[0]==64&&
+(inp_desc->buffer[1]==90||inp_desc->buffer[1]==122))
+return(true);
+return(false);
+}
+
+
+/*:43*//*44:*/
+#line 954 "tie.w"
+
+boolean e_of_ch_preamble(i)
+file_index i;
+{register input_description*inp_desc= input_organization[i];
+if(inp_desc->limit>=2&&inp_desc->buffer[0]==64)
+if(inp_desc->buffer[1]==89||inp_desc->buffer[1]==121)return(true);
+return(false);
+}
+
+
+
+/*:44*//*55:*/
+#line 1157 "tie.w"
+
+void usage()
+{
+print("Usage: tie -[mc] outfile master changefile(s)");
+term_new_line;
+jump_out();
+}
+
+
+/*:55*/
+#line 118 "tie.w"
+
+/*59:*/
+#line 1235 "tie.w"
+
+main(argc,argv)
+int argc;string*argv;
+{{/*12:*/
+#line 408 "tie.w"
+
+int i;
+
+
+/*:12*/
+#line 1238 "tie.w"
+
+/*10:*/
+#line 296 "tie.w"
+
+xchr[32]= ' ';
+xchr[33]= '!';
+xchr[34]= '\"';
+xchr[35]= '#';
+xchr[36]= '$';
+xchr[37]= '%';
+xchr[38]= '&';
+xchr[39]= '\'';
+xchr[40]= '(';
+xchr[41]= ')';
+xchr[42]= '*';
+xchr[43]= '+';
+xchr[44]= ',';
+xchr[45]= '-';
+xchr[46]= '.';
+xchr[47]= '/';
+xchr[48]= '0';
+xchr[49]= '1';
+xchr[50]= '2';
+xchr[51]= '3';
+xchr[52]= '4';
+xchr[53]= '5';
+xchr[54]= '6';
+xchr[55]= '7';
+xchr[56]= '8';
+xchr[57]= '9';
+xchr[58]= ':';
+xchr[59]= ';';
+xchr[60]= '<';
+xchr[61]= '=';
+xchr[62]= '>';
+xchr[63]= '?';
+xchr[64]= '@';
+xchr[65]= 'A';
+xchr[66]= 'B';
+xchr[67]= 'C';
+xchr[68]= 'D';
+xchr[69]= 'E';
+xchr[70]= 'F';
+xchr[71]= 'G';
+xchr[72]= 'H';
+xchr[73]= 'I';
+xchr[74]= 'J';
+xchr[75]= 'K';
+xchr[76]= 'L';
+xchr[77]= 'M';
+xchr[78]= 'N';
+xchr[79]= 'O';
+xchr[80]= 'P';
+xchr[81]= 'Q';
+xchr[82]= 'R';
+xchr[83]= 'S';
+xchr[84]= 'T';
+xchr[85]= 'U';
+xchr[86]= 'V';
+xchr[87]= 'W';
+xchr[88]= 'X';
+xchr[89]= 'Y';
+xchr[90]= 'Z';
+xchr[91]= '[';
+xchr[92]= '\\';
+xchr[93]= ']';
+xchr[94]= '^';
+xchr[95]= '_';
+xchr[96]= '`';
+xchr[97]= 'a';
+xchr[98]= 'b';
+xchr[99]= 'c';
+xchr[100]= 'd';
+xchr[101]= 'e';
+xchr[102]= 'f';
+xchr[103]= 'g';
+xchr[104]= 'h';
+xchr[105]= 'i';
+xchr[106]= 'j';
+xchr[107]= 'k';
+xchr[108]= 'l';
+xchr[109]= 'm';
+xchr[110]= 'n';
+xchr[111]= 'o';
+xchr[112]= 'p';
+xchr[113]= 'q';
+xchr[114]= 'r';
+xchr[115]= 's';
+xchr[116]= 't';
+xchr[117]= 'u';
+xchr[118]= 'v';
+xchr[119]= 'w';
+xchr[120]= 'x';
+xchr[121]= 'y';
+xchr[122]= 'z';
+xchr[123]= '{';
+xchr[124]= '|';
+xchr[125]= '}';
+xchr[126]= '~';
+xchr[0]= ' ';xchr[0x7F]= ' ';
+
+
+/*:10*//*13:*/
+#line 429 "tie.w"
+
+for(i= 1;i<32;xchr[i++]= ' ');
+xchr[tab_mark]= '\t';
+xchr[form_feed]= '\f';
+xchr[nl_mark]= '\n';
+
+
+/*:13*//*14:*/
+#line 440 "tie.w"
+
+for(i= first_text_char;i<=last_text_char;xord[i++]= 32)do_nothing;
+for(i= 1;i<=126;i++)xord[xchr[i]]= i;
+
+
+
+
+
+/*:14*/
+#line 1239 "tie.w"
+
+}
+print_ln(banner);
+print_ln(copyright);
+actual_input= 0;
+out_mode= normal;
+/*56:*/
+#line 1177 "tie.w"
+
+{int act_arg;
+if(argc<5||argc>max_file_index+4-1)usage();
+no_ch= -1;
+for(act_arg= 1;act_arg<argc;act_arg++){
+if(argv[act_arg][0]=='-')/*57:*/
+#line 1195 "tie.w"
+
+if(prod_chf!=unknown)usage();
+else
+switch(argv[act_arg][1]){
+case'c':
+case'C':prod_chf= chf;break;
+case'm':
+case'M':prod_chf= master;break;
+default:usage();
+}
+
+
+/*:57*/
+#line 1182 "tie.w"
+
+else/*58:*/
+#line 1211 "tie.w"
+
+{if(no_ch==(-1)){
+out_name= argv[act_arg];
+}else{register input_description*inp_desc;
+inp_desc= (input_description*)
+malloc(sizeof(input_description));
+if(inp_desc==NULL)
+fatal_error("! No memory for descriptor");
+
+inp_desc->mode= search;
+inp_desc->line= 0;
+inp_desc->type_of_file= chf;
+inp_desc->limit= 0;
+inp_desc->name_of_file= argv[act_arg];
+input_organization[no_ch]= inp_desc;
+}
+incr(no_ch);
+}
+
+
+/*:58*/
+#line 1183 "tie.w"
+
+}
+if(no_ch<=0||prod_chf==unknown)usage();
+}
+
+
+/*:56*/
+#line 1245 "tie.w"
+
+/*34:*/
+#line 788 "tie.w"
+
+{
+out_file= fopen(out_name,"w");
+if(out_file==NULL){
+fatal_error("! Could not open/create output file");
+
+}
+}
+
+
+/*:34*/
+#line 1246 "tie.w"
+
+/*36:*/
+#line 809 "tie.w"
+
+{input_organization[0]->the_file= 
+fopen(input_organization[0]->name_of_file,"r");
+if(input_organization[0]->the_file==NULL)
+fatal_error("! Could not open master file");
+
+print2("(%s)",input_organization[0]->name_of_file);
+term_new_line;
+input_organization[0]->type_of_file= master;
+get_line(0);
+}
+
+/*:36*/
+#line 1247 "tie.w"
+
+/*37:*/
+#line 825 "tie.w"
+
+{file_index i;
+i= 1;
+while(i<no_ch){
+input_organization[i]->the_file= 
+fopen(input_organization[i]->name_of_file,"r");
+if(input_organization[i]->the_file==NULL)
+fatal_error("!Could not open change file");
+
+print2("(%s)",input_organization[i]->name_of_file);
+term_new_line;
+init_change_file(i,true);
+incr(i);
+}
+}
+
+
+
+
+
+/*:37*/
+#line 1248 "tie.w"
+
+/*53:*/
+#line 1128 "tie.w"
+
+actual_input= 0;
+input_has_ended= false;
+while(input_has_ended==false||actual_input!=0)
+/*45:*/
+#line 970 "tie.w"
+
+{file_index test_file;
+/*46:*/
+#line 985 "tie.w"
+
+{register input_description*inp_desc;
+while(actual_input>0&&e_of_ch_module(actual_input)){
+inp_desc= input_organization[actual_input];
+if(inp_desc->type_of_file==master){
+
+fatal_error("! This can't happen: change file is master file");
+
+}
+inp_desc->mode= search;
+init_change_file(actual_input,true);
+while((input_organization[actual_input]->mode!=reading
+&&actual_input>0))decr(actual_input);
+}
+}
+
+
+/*:46*/
+#line 972 "tie.w"
+
+if(input_has_ended&&actual_input==0)break;
+/*47:*/
+#line 1009 "tie.w"
+
+test_input= none;
+test_file= actual_input;
+while(test_input==none&&test_file<no_ch-1){
+incr(test_file);
+switch(input_organization[test_file]->mode){
+case search:if(lines_dont_match(actual_input,test_file)==false){
+input_organization[test_file]->mode= test;
+test_input= test_file;
+}
+break;
+case test:if(lines_dont_match(actual_input,test_file)==true){
+
+input_organization[test_file]->mode= search;
+err_print("! Sections do not match")(actual_input);
+
+err_loc(test_file);
+init_change_file(test_file,false);
+}else test_input= test_file;
+break;
+case reading:do_nothing;
+break;
+case ignore:do_nothing;
+break;
+}
+}
+
+
+/*:47*/
+#line 974 "tie.w"
+
+/*48:*/
+#line 1043 "tie.w"
+
+if(prod_chf==chf){
+loop{
+/*49:*/
+#line 1057 "tie.w"
+
+if(out_mode==normal){
+if(test_input!=none){
+fputc(map_xchr(64),out_file);fputc(map_xchr(120),out_file);
+new_line(out_file);
+out_mode= pre;
+}else break;
+}
+
+
+/*:49*/
+#line 1046 "tie.w"
+
+/*50:*/
+#line 1071 "tie.w"
+
+
+if(out_mode==pre){
+if(test_input==none){
+fputc(map_xchr(64),out_file);fputc(map_xchr(121),out_file);
+new_line(out_file);
+out_mode= post;
+}else{
+if(input_organization[actual_input]->type_of_file==master)
+put_line(actual_input);
+break;
+}
+}
+
+
+/*:50*/
+#line 1047 "tie.w"
+
+/*51:*/
+#line 1092 "tie.w"
+
+if(out_mode==post){
+if(input_organization[actual_input]->type_of_file==chf){
+if(test_input==none)put_line(actual_input);
+break;
+}else{
+fputc(map_xchr(64),out_file);fputc(map_xchr(122),out_file);
+new_line(out_file);
+new_line(out_file);
+out_mode= normal;
+}
+}
+
+
+/*:51*/
+#line 1048 "tie.w"
+
+}
+}else
+if(test_input==none)put_line(actual_input);
+
+
+/*:48*/
+#line 975 "tie.w"
+
+/*52:*/
+#line 1109 "tie.w"
+
+get_line(actual_input);
+if(test_input!=none){
+get_line(test_input);
+if(e_of_ch_preamble(test_input)==true){
+get_line(test_input);
+input_organization[test_input]->mode= reading;
+actual_input= test_input;
+test_input= none;
+}
+}
+
+
+/*:52*/
+#line 976 "tie.w"
+
+}
+
+
+/*:45*/
+#line 1132 "tie.w"
+
+if(out_mode==post){
+fputc(map_xchr(64),out_file);fputc(map_xchr(122),out_file);
+new_line(out_file);
+}
+
+
+/*:53*/
+#line 1249 "tie.w"
+
+/*54:*/
+#line 1143 "tie.w"
+
+{file_index i;
+for(i= 1;i<no_ch;i++){
+if(input_organization[i]->mode!=ignore)
+err_print("! Change file entry did not match")(i);
+
+}
+}
+
+
+/*:54*/
+#line 1250 "tie.w"
+
+/*60:*/
+#line 1261 "tie.w"
+
+{string msg;
+switch(history){
+case spotless:msg= "No errors were found";break;
+case troublesome:msg= "Pardon me, but I think I spotted something wrong.";
+break;
+case fatal:msg= "That was a fatal error, my friend";break;
+}
+print2_nl("(%s.)",msg);term_new_line;
+exit(history==spotless?0:1);
+}
+
+
+
+
+
+/*:60*/
+#line 1251 "tie.w"
+
+}
+
+/*:59*/
+#line 119 "tie.w"
+
+
+/*:2*/
Index: texk/web2c/tie/tie.cf1
diff -u /dev/null texk/web2c/tie/tie.cf1:1.1
--- /dev/null	Wed Nov  5 23:20:00 1997
+++ texk/web2c/tie/tie.cf1	Tue Sep  2 11:51:41 1997
@@ -0,0 +1,14 @@
+@x
+line 2
+line 3
+@y
+changed line 2
+changed line 3
+inserted line
+@z
+
+@x
+line 7
+@y
+changed line 7
+@z
Index: texk/web2c/tie/tie.cf2
diff -u /dev/null texk/web2c/tie/tie.cf2:1.1
--- /dev/null	Wed Nov  5 23:20:00 1997
+++ texk/web2c/tie/tie.cf2	Tue Sep  2 11:51:41 1997
@@ -0,0 +1,19 @@
+@x
+line 1
+changed line 2
+changed line 3
+inserted line
+line 4
+@y
+final line 2
+final line 3
+changed line 4
+@z
+
+@x
+changed line 7
+line 8
+@y
+final line 7
+final line 8
+@z
Index: texk/web2c/tie/tie.cf3
diff -u /dev/null texk/web2c/tie/tie.cf3:1.1
--- /dev/null	Wed Nov  5 23:20:01 1997
+++ texk/web2c/tie/tie.cf3	Tue Sep  2 11:51:41 1997
@@ -0,0 +1,5 @@
+@x
+changed line 4
+@y
+final line 4
+@z
Index: texk/web2c/tie/tie.chf.gen
diff -u /dev/null texk/web2c/tie/tie.chf.gen:1.1
--- /dev/null	Wed Nov  5 23:20:01 1997
+++ texk/web2c/tie/tie.chf.gen	Tue Sep  2 11:51:42 1997
@@ -0,0 +1,19 @@
+@x
+line 1
+line 2
+line 3
+line 4
+@y
+final line 2
+final line 3
+final line 4
+@z
+
+@x
+line 7
+line 8
+@y
+final line 7
+final line 8
+@z
+
Index: texk/web2c/tie/tie.master.gen
diff -u /dev/null texk/web2c/tie/tie.master.gen:1.1
--- /dev/null	Wed Nov  5 23:20:01 1997
+++ texk/web2c/tie/tie.master.gen	Tue Sep  2 11:51:42 1997
@@ -0,0 +1,14 @@
+final line 2
+final line 3
+final line 4
+line 5
+line 6
+final line 7
+final line 8
+line 9
+line 10
+The character set:
+abcdefghijklmnopqrstuvwxyz
+ABCDEFGHIJKLMNOPQRSTUVWXYZ
+=!"#$%&/()?'`^~|-+[]{}@\;:
+	0123456789<>.,*_
Index: texk/web2c/tie/tie.tie
diff -u /dev/null texk/web2c/tie/tie.tie:1.1
--- /dev/null	Wed Nov  5 23:20:01 1997
+++ texk/web2c/tie/tie.tie	Tue Sep  2 11:51:42 1997
@@ -0,0 +1,15 @@
+line 1
+line 2
+line 3
+line 4
+line 5
+line 6
+line 7
+line 8
+line 9
+line 10
+The character set:
+abcdefghijklmnopqrstuvwxyz
+ABCDEFGHIJKLMNOPQRSTUVWXYZ
+=!"#$%&/()?'`^~|-+[]{}@\;:
+	0123456789<>.,*_
Index: texk/web2c/tie/tie.w
diff -u /dev/null texk/web2c/tie/tie.w:1.1
--- /dev/null	Wed Nov  5 23:20:01 1997
+++ texk/web2c/tie/tie.w	Tue Sep  2 11:51:42 1997
@@ -0,0 +1,1297 @@
+% This is TIE.W                            as of 17 Dec 92
+%---------------------------------------------------------
+% Copyright (c) 1989,1992 by THD/ITI.
+% All rights reserved.
+%
+% This program is distributed WITHOUT ANY WARRANTY, express or implied.
+%
+% Permission is granted to make and distribute verbatim copies of this
+% program provided that the copyright notice and this permission notice
+% are preserved on all copies.
+%
+% Permission is granted to copy and distribute modified versions of this
+% program under the conditions for verbatim copying, provided that the
+% entire resulting derived work is distributed under the terms of a
+% permission notice identical to this one.
+%
+%
+% Version 1.7 was built alike TIE.WEB Version 1.6                  (89-01-27)
+%             but used a command line interface only
+% Version 2.0 was revised to include optional tab expansion        (89-02-01)
+% Version 2.1 deleted WEB relicts. (-js)			   (89-10-25)
+% Version 2.2 repaired replacing strategy                          (89-11-27)
+% Version 2.3 was slightly modified to be processed with the
+%		cweb by Levy&Knuth.
+%		also repaired loop control for end of changes test (92-09-24)
+% Version 2.4 included <stdlib.h> instead of <malloc.h> when 
+%		used with ANSI-C				   (92-12-17)
+%
+
+% Here is TeX material that gets inserted after \input cwebmac
+
+\def\hang{\hangindent 3em\indent\ignorespaces}
+\font\mc=cmr9
+\def\PASCAL{Pascal}
+\def\Cl{{\rm C}}
+\def\ASCII{{\mc ASCII}}
+
+\def\title{TIE}
+\def\topofcontents{\null\vfill
+  \centerline{\titlefont The {\ttitlefont TIE} processor}
+  \vskip 15pt
+  \centerline{(CWEB Version 2.4)}
+  \vfill}
+\def\botofcontents{
+\null\vfill
+\item{$\copyright$}1989, 1992
+   by Technische Hochschule Darmstadt,\hfill\break
+Fachbereich Informatik, Institut f\"ur Theoretische Informatik\hfill\break
+All rights reserved.\hfill\break
+This program is distributed WITHOUT ANY WARRANTY, express or implied.
+\hfill\break
+Permission is granted to make and distribute verbatim copies of this
+program provided that the copyright notice and this permission notice
+are preserved on all copies.
+\hfill\break
+Permission is granted to copy and distribute modified versions of this
+program under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+}
+
+
+
+
+
+@* Introduction.
+
+\noindent Whenever a programmer wants to change a given
+\.{WEB} or \.{CWEB} program (referred to as a \.{WEB} program throughout
+this program) because of system dependencies, she or he will
+create a new change file.  In addition there may be a second
+change file to modify system independent modules of the
+program.  But the \.{WEB} file cannot be tangled and weaved
+with more than one change file simultaneously.  Therefore,
+we introduce the present program to merge a \.{WEB} file and
+several change files producing a new \.{WEB} file.  Since
+the input files are tied together, the program is called
+\.{TIE}.  Furthermore, the program can be used to merge
+several change files giving a new single change file.  This
+method seems to be more important because it doesn't modify
+the original source file.  The use of \.{TIE} can be
+expanded to other programming languages since this processor
+only knows about the structure of change files and does not
+interpret the master file at all.
+
+The program \.{TIE} has to read lines from several input
+files to bring them in some special ordering.  For this
+purpose an algorithm is used which looks a little bit
+complicated.  But the method used only needs one buffer line
+for each input file.  Thus the storage requirement of
+\.{TIE} does not depend on the input data.
+
+The program is written in \Cl\ and uses only few features of a
+particular environment that may need to be changed in other 
+installations.
+E.g.\ it will not use the |enum| type declarations.
+The changes needed may refer to the access of the command line
+if this can be not supported by any \Cl\ compiler.
+
+The ``banner line'' defined here should be changed whenever
+\.{TIE} is modified.  This program is put into the public
+domain.  Nevertheless the copyright notice must not be
+replaced or modified.
+
+@d banner  "This is TIE, CWEB Version 2.4."
+@d copyright 
+    "Copyright (c) 1989,1992 by THD/ITI. All rights reserved."
+
+
+@ The main outline of the program is given in the next section.
+This can be used more or less for any \Cl\ program.
+@c
+@<Global |#include|s@>@;
+@<Global constants@>@;
+@<Global types@>@;
+@<Global variables@>@;
+@<Error handling functions@>@;
+@<Internal functions@>@;
+@<The main function@>@;
+
+@ Here are some macros for common programming idioms.
+
+@d incr(v) v+=1 /* increase a variable by unity */
+@d decr(v) v-=1 /* decrease a variable by unity */
+@d loop @+ while (1)@+ /* repeat over and over until a |break| happens */
+@d do_nothing  /* empty statement */
+@f loop while
+
+
+@ Furthermore we include the additional types |boolean| and |string|.
+@d false 0
+@d true 1
+@<Global types@>=
+typedef int boolean;
+typedef char* string;
+
+
+@ The following parameters should be sufficient for most
+applications of \.{TIE}.
+@^system dependencies@>
+
+@<Global constants@>=
+#define buf_size 512 /* maximum length of one input line */
+#define max_file_index 9
+/* we don't think that anyone needs more than 9 change files,
+    but \dots\ just change it */
+
+
+@ We introduce a history variable that allows us to set a
+return code if the operating system can use it.
+First we introduce the coded values for the history.
+This variable must be initialized.
+(We do this even if the value given may be the default for
+variables, just to document the need for the initial value.)
+@d spotless 0
+@d troublesome 1
+@d fatal 2
+
+@<Global variables@>=
+static int history=spotless;
+
+
+
+@* The character set.
+
+\noindent One of the main goals in the design of \.{TIE} has
+been to make it readily portable between a wide variety of
+computers.  Yet \.{TIE} by its very nature must use a
+greater variety of characters than most computer programs
+deal with, and character encoding is one of the areas in
+which existing machines differ most widely from each other.
+
+To resolve this problem, all input to \.{TIE} is converted to an
+internal seven-bit code that is essentially standard \ASCII{}, the
+``American Standard Code for Information Interchange.'' The conversion
+is done immediately when each character is read in.  Conversely,
+characters are converted from \ASCII{} to the user's external
+representation just before they are output.  But the algorithm is
+prepared for the usage of eight-bit data. 
+
+\noindent Here is a table of the standard visible \ASCII{} codes:
+$$\def\:{\char\count255\global\advance\count255 by 1}
+\count255='40
+\vbox{
+\hbox{\hbox to 40pt{\it\hfill0\/\hfill}%
+\hbox to 40pt{\it\hfill1\/\hfill}%
+\hbox to 40pt{\it\hfill2\/\hfill}%
+\hbox to 40pt{\it\hfill3\/\hfill}%
+\hbox to 40pt{\it\hfill4\/\hfill}%
+\hbox to 40pt{\it\hfill5\/\hfill}%
+\hbox to 40pt{\it\hfill6\/\hfill}%
+\hbox to 40pt{\it\hfill7\/\hfill}}
+\vskip 4pt
+\hrule
+\def\^{\vrule height 10.5pt depth 4.5pt}
+\halign{\hbox to 0pt{\hskip -24pt\O{#0}\hfill}&\^
+\hbox to 40pt{\tt\hfill#\hfill\^}&
+&\hbox to 40pt{\tt\hfill#\hfill\^}\cr
+04&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+05&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+06&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+07&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+10&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+11&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+12&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+13&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+14&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+15&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+16&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+17&\:&\:&\:&\:&\:&\:&\:\cr}
+\hrule width 280pt}$$
+(Actually, of course, code |040| is an invisible blank space.)  Code |0136|
+was once an upward arrow (\.{\char'13}), and code |0137| was
+once a left arrow (\.^^X), in olden times when the first draft
+of ASCII code was prepared; but \.{TIE} works with today's standard
+ASCII in which those codes represent circumflex and underline as shown.
+The maximum value used is also defined, it must be changed if an
+extended \ASCII{} is used.
+
+If the \Cl\ compiler is not able to process \&{unsigned char}'s, you
+should define |ASCII_Code| as \&{short}.
+@^system dependencies@>
+
+@<Global types@>=
+#define max_ASCII (@'~'+1)
+typedef unsigned char ASCII_Code; 
+         /* eight-bit numbers, a subrange of the integers */
+
+
+@ \Cl\ was first implemented on a machine that uses the
+\ASCII{} representation for characters. But to make it readily
+available also for other machines (big brother is watching?)\
+we add a conversion that may be undone for most installations.
+\.{TIE} assumes that it is being used
+with a character set that contains at least the
+characters of standard \ASCII{} as listed above.
+
+In order to accommodate this difference, we shall use the
+name |text_char| to stand for the data type of the
+characters in the input and output files.  We shall also
+assume that |text_char| consists of the elements
+|first_text_char| through |last_text_char|,
+inclusive.  The following definitions should be adjusted if
+necessary.
+@^system dependencies@>
+
+@d first_text_char 0 /* ordinal number of the smallest element of |text_char|*/
+@d last_text_char 255 /* ordinal number of the largest element of |text_char|*/
+
+@<Global types@>=
+typedef unsigned char text_char; /* the data type of characters in text files */
+typedef FILE* text_file;
+
+
+@ The \.{TIE} processor converts between \ASCII{} code and
+the user's external character set by means of arrays |xord|
+and |xchr| that are analogous to \PASCAL's |ord| and |chr|
+functions.
+
+The mapping may be disabled by changing the following macro
+definitions to just a cast. If your \Cl\ compiler does not support
+\&{unsigned char}'s, you should incorporate a binary and with |0xff|.
+@^system dependencies@>
+
+@d map_xchr(c)  (text_char)(c)
+         /* change this to |xchr[c]| on non \ASCII{} machines */
+@d map_xord(c)  (ASCII_Code)(c)
+         /* change this to |xord[c]| on non \ASCII{} machines */
+
+@<Global variables@>=
+static ASCII_Code xord[last_text_char+1];
+         /* specifies conversion of input characters */
+static text_char xchr[max_ASCII+1];
+         /* specifies conversion of output characters */
+
+
+@ If we assume that every system using \.{WEB} is able to
+read and write the visible characters of standard \ASCII{}
+(although not necessarily using the \ASCII{} codes to
+represent them), the following assignment statements
+initialize most of the |xchr| array properly, without
+needing any system-dependent changes.  For example, the
+statement |xchr[@'A']='A'| that appears in the present
+\.{WEB} file might be encoded in, say, {\mc EBCDIC} code on
+the external medium on which it resides, but \.{CTANGLE} will
+convert from this external code to \ASCII{} and back again.
+Therefore the assignment statement |xchr[65]='A'| will
+appear in the corresponding \Cl\ file, and \Cl\ will
+compile this statement so that |xchr[65]| receives the
+character \.A in the external code.  Note that it
+would be quite incorrect to say |xchr[@'A']=@'A'|, because
+|@'A'| is a constant of type |int| not \&{char}, and
+because we have |@'A'==65| regardless of the external
+character set.
+
+@<Set initial values@>=
+xchr[@' ']=' ';
+xchr[@'!']='!';
+xchr[@'\"']='\"';
+xchr[@'#']='#';@/
+xchr[@'$']='$';
+xchr[@'%']='%';
+xchr[@'&']='&';
+xchr[@'\'']='\'';@/
+xchr[@'(']='(';
+xchr[@')']=')';
+xchr[@'*']='*';
+xchr[@'+']='+';@/
+xchr[@',']=',';
+xchr[@'-']='-';
+xchr[@'.']='.';
+xchr[@'/']='/';@/
+xchr[@'0']='0';
+xchr[@'1']='1';
+xchr[@'2']='2';
+xchr[@'3']='3';@/
+xchr[@'4']='4';
+xchr[@'5']='5';
+xchr[@'6']='6';
+xchr[@'7']='7';@/
+xchr[@'8']='8';
+xchr[@'9']='9';
+xchr[@':']=':';
+xchr[@';']=';';@/
+xchr[@'<']='<';
+xchr[@'=']='=';
+xchr[@'>']='>';
+xchr[@'?']='?';@/
+xchr[@'@@']='@@';
+xchr[@'A']='A';
+xchr[@'B']='B';
+xchr[@'C']='C';@/
+xchr[@'D']='D';
+xchr[@'E']='E';
+xchr[@'F']='F';
+xchr[@'G']='G';@/
+xchr[@'H']='H';
+xchr[@'I']='I';
+xchr[@'J']='J';
+xchr[@'K']='K';@/
+xchr[@'L']='L';
+xchr[@'M']='M';
+xchr[@'N']='N';
+xchr[@'O']='O';@/
+xchr[@'P']='P';
+xchr[@'Q']='Q';
+xchr[@'R']='R';
+xchr[@'S']='S';@/
+xchr[@'T']='T';
+xchr[@'U']='U';
+xchr[@'V']='V';
+xchr[@'W']='W';@/
+xchr[@'X']='X';
+xchr[@'Y']='Y';
+xchr[@'Z']='Z';
+xchr[@'[']='[';@/
+xchr[@'\\']='\\';
+xchr[@']']=']';
+xchr[@'^']='^';
+xchr[@'_']='_';@/
+xchr[@'`']='`';
+xchr[@'a']='a';
+xchr[@'b']='b';
+xchr[@'c']='c';@/
+xchr[@'d']='d';
+xchr[@'e']='e';
+xchr[@'f']='f';
+xchr[@'g']='g';@/
+xchr[@'h']='h';
+xchr[@'i']='i';
+xchr[@'j']='j';
+xchr[@'k']='k';@/
+xchr[@'l']='l';
+xchr[@'m']='m';
+xchr[@'n']='n';
+xchr[@'o']='o';@/
+xchr[@'p']='p';
+xchr[@'q']='q';
+xchr[@'r']='r';
+xchr[@'s']='s';@/
+xchr[@'t']='t';
+xchr[@'u']='u';
+xchr[@'v']='v';
+xchr[@'w']='w';@/
+xchr[@'x']='x';
+xchr[@'y']='y';
+xchr[@'z']='z';
+xchr[@'{']='{';@/
+xchr[@'|']='|';
+xchr[@'}']='}';
+xchr[@'~']='~';@/
+xchr[0]=' '; xchr[0x7F]=' '; /* these \ASCII{} codes are not used */
+
+
+@ Some of the \ASCII{} codes below |0x20| have been given a
+symbolic name in \.{TIE} because they are used with a special
+meaning.
+
+@d tab_mark   @'\t' /* \ASCII{} code used as tab-skip */
+@d nl_mark    @'\n' /* \ASCII{} code used as line end marker */
+@d form_feed  @'\f' /* \ASCII{} code used as page eject */
+
+
+@ When we initialize the |xord| array and the remaining
+parts of |xchr|, it will be convenient to make use of an
+index variable, |i|.
+
+@<Local variables for initialisation@>=
+int i;
+
+
+@ Here now is the system-dependent part of the character
+set.  If \.{TIE} is being implemented on a garden-variety
+\Cl\ for which only standard \ASCII{} codes will appear
+in the input and output files, you don't need to make any
+changes here.
+@^system dependencies@>
+
+Changes to the present module will make \.{TIE} more
+friendly on computers that have an extended character set,
+so that one can type things like \.^^Z.  If you have an
+extended set of characters that are easily incorporated into
+text files, you can assign codes arbitrarily here, giving an
+|xchr| equivalent to whatever characters the users of
+\.{TIE} are allowed to have in their input files, provided
+that unsuitable characters do not correspond to special
+codes like |tab_mark| that are listed above.
+
+@<Set init...@>=
+for (i=1;i<@' ';xchr[i++]=' ');
+xchr[tab_mark]='\t';
+xchr[form_feed]='\f';
+xchr[nl_mark]='\n';
+
+
+@ The following system-independent code makes the |xord|
+array contain a suitable inverse to the information in
+|xchr|.
+
+@<Set init...@>=
+for ( i=first_text_char ; i<=last_text_char ; xord[i++]=@' ' )  do_nothing;
+for ( i=1 ; i<=@'~' ; i++ )  xord[xchr[i]] = i;
+
+
+
+
+
+@* Input and output.
+
+\noindent Output for the user is done by writing on file |term_out|,
+which is assumed to consist of characters of type \&{text\_char}.  It
+should be linked to |stdout| usually.  Terminal input is not needed in
+this version of \.{TIE}.  |stdin| and |stdout| are predefined if we
+include the \.{stdio.h} definitions.  Although I/O redirection for
+|stdout| is usually available you may lead output to another file if
+you change the definition of |term_out|.  Also we define some macros
+for terminating an output line and writing strings to the user.
+
+@^system dependencies@>
+@d term_out  stdout
+@d print(a)  fprintf(term_out,a) /* `|print|' means write on the terminal */
+@d print2(a,b)  fprintf(term_out,a,b) /* same with two arguments */
+@d print3(a,b,c)  fprintf(term_out,a,b,c) /* same with three arguments */
+@d print_c(v)  fputc(v,term_out); /* print a single character */
+@d new_line(v)  fputc('\n',v) /* start new line */
+@d term_new_line  new_line(term_out)
+	/* start new line of the terminal */
+@d print_ln(v)  {fprintf(term_out,v);term_new_line;}
+	/* `|print|' and then start new line */
+@d print2_ln(a,b)  {print2(a,b);term_new_line;} /* same with two arguments */
+@d print3_ln(a,b,c)  {print3(a,b,c);term_new_line;} 
+	/* same with three arguments */
+@d print_nl(v) 	 {term_new_line; print(v);}
+	/* print information starting on a new line */
+@d print2_nl(a,b)  {term_new_line; print2(a,b);}
+	/* same for two arguments */
+
+@<Global |#include|s@>=
+#include <stdio.h>
+
+
+@ And we need dynamic memory allocation.
+This should cause no trouble in any \Cl\ program.
+@^system dependencies@>
+
+@<Global |#include|s@>=
+#ifdef __STDC__
+#include <stdlib.h>
+#else
+#include <malloc.h>
+#endif
+
+@ The |update_terminal| function is called when we want to
+make sure that everything we have output to the terminal so
+far has actually left the computer's internal buffers and
+been sent.
+@^system dependencies@>
+
+@d update_terminal  fflush(term_out) /* empty the terminal output buffer */
+
+
+
+
+
+@* Data structures.
+
+\noindent The multiple input files (master file and change
+files) are treated the same way.  To organize the
+simultaneous usage of several input files, we introduce the
+data type \&{in\_file\_modes}.
+
+The mode |search| indicates that \.{TIE} searches for a
+match of the input line with any line of an input file in
+|reading| mode.  |test| is used whenever a match is found
+and it has to be tested if the next input lines do match
+also.  |reading| describes that the lines can be read without
+any check for matching other lines.  |ignore| denotes
+that the file cannot be used.  This may happen because an
+error has been detected or because the end of the file has
+been found.
+
+\leavevmode |file_types| is used to describe whether a file
+is a master file or a change file. The value |unknown| is added
+to this type to set an initial mode for the output file.
+This enables us to check whether any option was used to select
+the kind of output. (this would even be necessary if we
+would assume a default action for missing options.)
+
+@<Global types@>=
+#define search 0
+#define test 1
+#define reading 2
+#define ignore 3
+typedef int in_file_modes; /* should be |enum(search,test,reading,ignore)| */
+#define unknown 0
+#define master 1
+#define chf 2
+typedef int file_types; /* should be |enum(unknown,master,chf)| */
+
+
+@ A variable of type |out_md_type| will tell us in what state the output
+change file is during processing. |normal| will be the state, when we
+did not yet start a change, |pre| will be set when we write the lines
+to be changes and |post| will indicate that the replacement lines are
+written.
+
+@<Global types@>=
+#define normal 0
+#define pre 1
+#define post 2
+typedef int out_md_type; /* should be |enum(normal,pre,post)| */
+
+
+@ Two more types will indicate variables used as an index into either
+the file buffer or the file table.
+
+@<Global types@>=
+typedef int buffer_index; /* |-1..buf_size| */
+typedef int file_index;  /* |-1..max_file_index+1| */
+
+
+@ The following data structure joins all informations needed to use
+these input files.
+%`line' is a normal identifier throughout this program 
+@f line dummy	
+@<Global types@>=
+typedef struct _idsc{
+    string name_of_file;
+    ASCII_Code buffer[buf_size];
+    in_file_modes mode;
+    long line;
+    file_types type_of_file;
+    buffer_index limit;
+    text_file the_file;
+    } input_description;
+
+
+@ These data types are used in the global variable section.
+They refer to the files in action, the number of change files,
+the mode of operation and the current output state.
+
+@<Global variables@>=
+static file_index actual_input,test_input,no_ch;
+static file_types prod_chf=unknown;
+static out_md_type out_mode;
+
+
+@ All input files (including the master file) are recorded
+in the following structure.
+Mostly the components are accessed through a local pointer variable.
+This corresponds to \PASCAL's \&{with}-statement
+and results in a one-time-computation of the index expression.
+
+@<Global variables@>=
+static input_description *input_organization[max_file_index+1];
+
+
+
+
+
+@* File I/O.
+
+\noindent The basic function |get_line| can be used to get a line from
+an input file.  The line is stored in the |buffer| part of the
+descriptor.  The components |limit| and |line| are updated.  If the
+end of the file is reached |mode| is set to |ignore|.  On some systems
+it might be useful to replace tab characters by a proper number of
+spaces since several editors used to create change files insert tab
+characters into a source file not under control of the user.  So it
+might be a problem to create a matching change file. 
+@^tab character expansion@>
+
+We define |get_line| to read a line from a file specified by
+the corresponding file descriptor.
+
+@<Internal functions@>=
+void get_line(i)
+	file_index i;
+{register input_description *inp_desc=input_organization[i];
+    if (inp_desc->mode==ignore) return;
+    if (feof(inp_desc->the_file))
+        @<Handle end of file and return@>@;
+    @<Get line into buffer@>@;
+}
+
+
+@ End of file is special if this file is the master file.
+Then we set the global flag variable |input_has_ended|.
+
+@<Handle end of file ...@>=
+{
+  inp_desc->mode=ignore;
+  inp_desc->limit=-1;  /* mark end-of-file */
+  if (inp_desc->type_of_file==master) input_has_ended=true;
+  return;
+}
+
+
+@ This variable must be declared for global access.
+
+@<Global variables@>=
+static boolean input_has_ended=false;
+
+
+@ Lines must fit into the buffer completely.
+We read all characters sequentially until an end of line is found
+(but do not forget to check for |EOF|!).
+Too long input lines will be truncated.
+This will result in a damaged output if they occur in the
+replacement part of a change file, or in an incomplerte check if the
+matching part is concerned.
+Tab character expansion might be done here.
+@^tab character expansion@>
+
+@<Get line into buffer@>=
+{int final_limit; /* used to delete trailing spaces */
+ int c; /* the actual character read */
+ @<Increment the line number and print a progess report at
+  certain times@>@;
+ inp_desc->limit=final_limit=0;
+ while (inp_desc->limit<buf_size) {
+   c=fgetc(inp_desc->the_file);
+   @<Check |c| for |EOF|, |return| if line was empty, otherwise
+	|break| to process last line@>@;
+   inp_desc->buffer[inp_desc->limit++]=c=map_xord(c);
+   if (c==nl_mark) break; /* end of line found */
+   if (c!=@' ' && c!=tab_mark)
+      final_limit=inp_desc->limit;
+ }
+ @<Test for truncated line, skip to end of line@>@;
+ inp_desc->limit=final_limit;
+}
+
+
+@ This section does what its name says. Every 100 lines
+in the master file we print a dot, every 500 lines the number
+of lines is shown.
+
+@<Increment the line number and print ...@>=
+incr(inp_desc->line);
+if (inp_desc->type_of_file==master && inp_desc->line % 100==0) {
+   if (inp_desc->line % 500 == 0)  print2("%ld",inp_desc->line);
+   else  print_c('.');
+   update_terminal;
+}
+
+
+@ There may be incomplete lines of the editor used does
+not make sure that the last character before end of file
+is an end of line. In such a case we must process the
+final line. Of the current line is empty, we just can \&{return}.
+Note that this test must be done {\sl before} the character read
+is translated.
+@^system dependencies@>
+
+@<Check |c| for |EOF|...@>=
+  if (c==EOF) {
+    if (inp_desc->limit<=0) {
+       inp_desc->mode=ignore;
+       inp_desc->limit=-1;  /* mark end-of-file */
+       if (inp_desc->type_of_file==master) input_has_ended=true;
+       return;
+    } else { /* add end of line mark */
+	c=nl_mark;
+	break;
+    }
+  }
+
+
+@ If the line is truncated we must skip the rest
+(and still watch for |EOF|!).
+@<Test for truncated line, skip to end of line@>=
+if (c!=nl_mark) {
+   err_print("! Input line too long")(i);
+@.Input line too long@>
+   while ( (c=fgetc(inp_desc->the_file)) != EOF  &&  map_xord(c) != nl_mark )
+      do_nothing; /* skip to end */
+   }
+
+
+
+
+
+@* Reporting errors to the user.
+
+\noindent There may be errors if a line in a given change
+file does not match a line in the master file or a
+replacement in a previous change file.  Such errors are
+reported to the user by saying
+$$
+   \hbox{|err_print("! Error message")(file_no)|;}
+$$
+where |file_no| is the number of the file which is concerned by the
+error.  Please note that no trailing dot is supplied by the error
+message because it is appended by |err_print|.
+
+This function is implemented as a macro.  It gives a message and an
+indication of the offending file.  The actions to determine the error
+location are provided by a function called |err_loc|. 
+
+@d error_loc(m)  err_loc(m); history=troublesome; @+ }
+@d err_print(m)  { @+ print_nl(m); error_loc
+
+@<Error handling...@>=
+void err_loc(i) /* prints location of error */
+        int i;
+{
+    print3_ln(" (file %s, l.%ld).",
+	input_organization[i]->name_of_file,
+	input_organization[i]->line);
+}
+
+
+@ Non recoverable errors are handled by calling |fatal_error| that
+outputs a message and then calls `|jump_out|'.  |err_print| will print
+the error message followed by an indication of where the error was
+spotted in the source files.  |fatal_error| cannot state any files
+because the problem is usually to access these. 
+
+@d fatal_error(m) {
+         print(m); print_c('.'); history=fatal;
+	 term_new_line; jump_out();
+	 }
+
+
+@ |jump_out| just cuts across all active procedure levels and jumps
+out of the program.  It is used when no recovery from a particular
+error has been provided.  The return code from this program should be
+regarded by the caller. 
+
+@d jump_out() exit(1)
+
+
+
+
+
+@* Handling multiple change files.
+
+\noindent In the standard version we take the name of the
+files from the command line.
+It is assumed that filenames can be used as given in the
+command line without changes.
+
+First there are some sections to open all files.
+If a file is not accessible, the run will be aborted.
+Otherwise the name of the open file will be displayed.
+
+@<Prepare the output file@>=
+{
+    out_file=fopen(out_name,"w");
+    if (out_file==NULL) {
+	 fatal_error("! Could not open/create output file");
+@.Could not open/create output file@>
+    }
+}
+
+
+@ The name of the file and the file desciptor are stored in
+global variables.
+
+@<Global variables@>=
+static text_file out_file;
+static string out_name;
+
+
+@ For the master file we start just reading its first line
+into the buffer, if we could open it.
+
+@<Get the master file started@>=
+{  input_organization[0]->the_file=
+	  fopen(input_organization[0]->name_of_file,"r");
+   if (input_organization[0]->the_file==NULL)
+    fatal_error("! Could not open master file");
+@.Could not open master file@>
+   print2("(%s)",input_organization[0]->name_of_file);
+   term_new_line;
+   input_organization[0]->type_of_file=master;
+   get_line(0);
+}
+
+@ For the change files we must skip the comment part and
+see, whether we can find any change in it.
+This is done by |init_change_file|.
+
+@<Prepare the change files@>=
+{file_index i;
+  i=1;
+  while (i<no_ch) {
+    input_organization[i]->the_file=
+	fopen(input_organization[i]->name_of_file,"r");
+    if (input_organization[i]->the_file==NULL)
+	fatal_error("!Could not open change file");
+@.Could not open change file@>
+    print2("(%s)",input_organization[i]->name_of_file);
+    term_new_line;
+    init_change_file(i,true);
+    incr(i);
+  }
+}
+
+
+
+
+
+@*Input/output organization.
+
+\noindent Here's a simple function that checks if two lines
+are different.
+
+@<Internal functions@>=
+boolean lines_dont_match(i,j) 
+	file_index i,j;
+{
+   buffer_index k,lmt;
+   if (input_organization[i]->limit != input_organization[j]->limit)
+      return(true);
+   lmt=input_organization[i]->limit;
+   for ( k=0 ; k<lmt ; k++ )
+      if (input_organization[i]->buffer[k] != input_organization[j]->buffer[k])
+         return(true);
+  return(false);
+}
+
+
+@ Function |init_change_file(i,b)| is used to ignore all
+lines of the input file with index |i| until the next change
+module is found.  The boolean parameter |b| indicates
+whether we do not want to see \.{@@x} or \.{@@y} entries during
+our skip.
+
+@<Internal functions@>=
+void init_change_file(i,b)
+	file_index i; boolean b;
+{register input_description *inp_desc=input_organization[i];
+  @<Skip over comment lines; |return| if end of file@>@;
+  @<Skip to the next nonblank line; |return| if end of file@>@;
+}
+
+
+@ While looking for a line that begins with \.{@@x} in the
+change file, we allow lines that begin with \.{@@}, as long
+as they don't begin with \.{@@y} or \.{@@z} (which would
+probably indicate that the change file is fouled up).
+
+@<Skip over comment lines...@>=
+loop@+  {ASCII_Code c;
+  get_line(i);
+  if (inp_desc->mode==ignore) return;
+  if (inp_desc->limit<2) continue;
+  if (inp_desc->buffer[0] != @'@@') continue;
+  c=inp_desc->buffer[1];
+  if (c>=@'X'  && c<=@'Z')
+    c+=@'z'-@'Z'; /*lowercasify*/
+  if (c==@'x') break;
+  if (c==@'y' || c==@'z')
+    if (b) /* scanning for start of change */
+          err_print("! Where is the matching @@x?")(i);
+@.Where is the match...@>
+}
+
+
+@ Here we are looking at lines following the \.{@@x}.
+
+@<Skip to the next nonblank line...@>=
+do{
+  get_line(i);
+  if (inp_desc->mode==ignore) {
+	  err_print("! Change file ended after @@x")(i);
+@.Change file ended...@>
+          return;
+  }
+} while (inp_desc->limit<=0);
+
+
+@ The |put_line| function is used to write a line from
+input buffer |j| to the output file.
+
+@<Internal functions@>=
+void put_line(j)
+	file_index j;
+{buffer_index i; /* index into the buffer */
+ buffer_index lmt; /* line length */
+ ASCII_Code *p; /* output pointer */
+  lmt=input_organization[j]->limit;
+  p=input_organization[j]->buffer;
+  for (i=0;i<lmt;i++) fputc(map_xchr(*p++),out_file);
+  new_line(out_file);
+}
+
+
+@ The function |e_of_ch_module| returns true if the input
+line from file |i| starts with \.{@@z}.
+
+@<Internal functions@>=
+boolean e_of_ch_module(i)
+	file_index i;
+{register input_description *inp_desc=input_organization[i];
+    if (inp_desc->limit<0) {
+      print_nl("! At the end of change file missing @@z ");
+@.At the end of change file...@>
+      print2("%s",input_organization[i]->name_of_file);
+      term_new_line;
+      return(true);
+    } else if (inp_desc->limit>=2)  if (inp_desc->buffer[0]==@'@@' &&
+	    (inp_desc->buffer[1]==@'Z' || inp_desc->buffer[1]==@'z'))
+        return(true);
+    return(false);
+}
+
+
+@ The function |e_of_ch_preamble| returns |true| if the input
+line from file |i| starts with \.{@@y}.
+
+@<Internal functions@>=
+boolean e_of_ch_preamble(i)
+	file_index i;
+{register input_description *inp_desc=input_organization[i];
+    if (inp_desc->limit>=2 && inp_desc->buffer[0]==@'@@')
+      if (inp_desc->buffer[1]==@'Y'||inp_desc->buffer[1]==@'y') return(true);
+    return(false);
+}
+
+
+
+@ To process the input file the next section
+reads a line of the actual input file and updates the
+|input_organization| for all files with index |test_file| greater
+|actual_input|.
+
+@<Process a line, |break| when end of source reached@>=
+{file_index test_file;
+  @<Check the current files for any ends of changes@>@;
+  if (input_has_ended && actual_input==0) break; /* all done */
+  @<Scan all other files for changes to be done@>@;
+  @<Handle output@>@;
+  @<Step to next line@>@;
+}
+
+
+@ Any of the current change files may have reached the end of change.
+In such a case intermediate lines must be skipped and the next start
+of change is to be found. This may make a change file inactive if
+it reaches end of file.
+
+@<Check the...@>=
+{register input_description *inp_desc;
+while (actual_input>0 && e_of_ch_module(actual_input)) {
+  inp_desc=input_organization[actual_input];
+  if (inp_desc->type_of_file==master) {
+        /* emergency exit, everything mixed up!*/
+        fatal_error("! This can't happen: change file is master file");
+@.This can't happen...@>
+  }
+  inp_desc->mode=search;
+  init_change_file(actual_input,true);
+  while ((input_organization[actual_input]->mode!=reading
+           && actual_input>0))  decr(actual_input);
+}
+}
+
+
+@ Now we will set |test_input| to the file that has another match
+for the current line. This depends on the state of the other
+change files. If no other file matches, |actual_input| refers to
+a line to write and |test_input| ist set to |none|.
+
+@d none  (max_file_index+1)
+
+@<Scan all other files...@>=
+test_input=none;
+test_file=actual_input;
+while (test_input==none && test_file<no_ch-1){
+  incr(test_file);
+  switch (input_organization[test_file]->mode) {
+  case search: if (lines_dont_match(actual_input,test_file)==false) {
+	      input_organization[test_file]->mode=test;
+	      test_input=test_file;
+               }
+              break;
+  case test:  if (lines_dont_match(actual_input, test_file)==true) {
+                /* error, sections do not match */
+		input_organization[test_file]->mode=search;
+                err_print("! Sections do not match")(actual_input);
+@.Sections do not match@>
+		err_loc(test_file);
+		init_change_file(test_file,false);
+	      } else test_input=test_file;
+              break;
+  case reading: do_nothing; /* this can't happen */
+	      break;
+  case ignore: do_nothing; /* nothing to do */
+	      break;
+  }
+}
+
+
+@ For the output we must distinguish whether we create a new change
+file or a new master file.  The change file creation needs some closer
+inspection because we may be before a change, in the pattern part or
+in the replacement part.  For a master file we have to write the line
+from the current actual input. 
+
+@<Handle output@>=
+if (prod_chf==chf) {
+  loop @+ {
+    @<Test for normal, |break| when done@>@;
+    @<Test for pre, |break| when done@>@;
+    @<Test for post, |break| when done@>@;
+  }
+} else
+if (test_input==none) put_line(actual_input);
+
+
+@ Check whether we have to start a change file entry.
+Without a match nothing must be done.
+
+@<Test for normal...@>=
+if (out_mode==normal) {
+    if (test_input!=none) {
+	fputc(map_xchr(@'@@'),out_file); fputc(map_xchr(@'x'),out_file);
+	new_line(out_file);
+        out_mode=pre;
+    } else break;
+}
+
+
+@ Check whether we have to start the replacement text.
+This is the case when we have no more matching line.
+Otherwise the master file source line must be copied to the
+change file.
+@<Test for pre...@>=
+
+  if (out_mode==pre) {
+    if (test_input==none) {
+      fputc(map_xchr(@'@@'),out_file); fputc(map_xchr(@'y'),out_file);
+      new_line(out_file);
+      out_mode=post;
+    } else {
+      if (input_organization[actual_input]->type_of_file==master)
+        put_line(actual_input);
+      break;
+    }
+  }
+
+
+@ Check whether an entry from a change file is complete.
+If the current change was a change for a change file in effect,
+then this change file line must be written.
+If the actual input has been reset to the master file we
+can finish this change.
+
+@<Test for post...@>=
+  if (out_mode==post) {
+    if (input_organization[actual_input]->type_of_file==chf) {
+	if (test_input==none)  put_line(actual_input);
+        break;
+    } else {
+	fputc(map_xchr(@'@@'),out_file); fputc(map_xchr(@'z'),out_file);
+	new_line(out_file);
+	new_line(out_file);
+        out_mode=normal;
+    }
+  }
+
+
+@ If we had a change, we must proceed in the actual file
+to be changed and in the change file in effect.
+
+@<Step to next line@>=
+get_line(actual_input);
+if (test_input!=none) {
+  get_line(test_input);
+  if (e_of_ch_preamble(test_input)==true) {
+    get_line(test_input); /* update current changing file */
+    input_organization[test_input]->mode=reading;
+    actual_input=test_input;
+    test_input=none;
+  }
+}
+
+
+@ To create the new output file we have to scan the whole
+master file and all changes in effect when it ends.
+At the very end it is wise to check for all changes
+to have completed--in case the last line of the master file
+was to be changed.
+
+@<Process the input@>=
+actual_input=0;
+input_has_ended=false;
+while (input_has_ended==false||actual_input!=0)
+   @<Process a line...@>@;
+if (out_mode==post) { /* last line has been changed */
+   fputc(map_xchr(@'@@'),out_file); fputc(map_xchr(@'z'),out_file);
+   new_line(out_file);
+   }
+
+
+@ At the end of the program, we will tell the user if the
+change file had a line that didn't match any relevant line
+in the master file or any of the change files.
+
+@<Check that all changes have been read@>=
+{file_index i;
+for (i=1;i<no_ch;i++) {/* all change files */
+   if (input_organization[i]->mode!=ignore)
+      err_print("! Change file entry did not match")(i);
+@.Change file entry ...@>
+   }
+}
+
+
+@ We want to tell the user about our command line options.  This is
+done by the |usage()| function.  It contains merely the necessary
+print statement and exits afterwards. 
+
+@<Intern...@>=
+void usage()
+{
+   print("Usage: tie -[mc] outfile master changefile(s)");
+   term_new_line;
+   jump_out();
+}
+
+
+@ We must scan through the list of parameters, given in |argv|.  The
+number is in |argc|.  We must pay attention to the flag parameter.  We
+need at least 5~parameters and can handle up to |max_file_index|
+change files.  The names fo the file parameters will be inserted into
+the structure of |input_organization|.  The first file is special.  It
+indicates the output file.  When we allow flags at any position, we
+must find out which name is for what purpose.  The master file is
+already part of the |input_organization| structure (index~0).  As long
+as the number of files found (counted in |no_ch|) is |-1| we have not
+yet found the output file name. 
+
+@<Scan the parameters@>=
+{int act_arg;
+    if ( argc < 5  ||  argc > max_file_index+4-1 )  usage();
+    no_ch = -1; /* fill this part of |input_organization| */
+    for ( act_arg=1 ; act_arg<argc ; act_arg++ ) {
+	if (argv[act_arg][0]=='-') @<Set a flag@>@;
+	else @<Get a file name@>@;
+    }
+    if (no_ch<=0|| prod_chf==unknown)  usage();
+}
+
+
+@ The flag is about to determine the processing mode.
+We must make sure that this flag has not been set before.
+Further flags might be introduced to avoid/force overwriting of
+output files.
+Currently we just have to set the processing flag properly.
+
+@<Set a flag@>=
+if (prod_chf!=unknown)  usage();
+else
+   switch (argv[act_arg][1]) {
+      case 'c':
+      case 'C': prod_chf=chf;  break;
+      case 'm':
+      case 'M':	prod_chf=master;  break;
+      default:  usage(); 
+      }
+
+
+@ We have to distinguish whether this is the very first file name
+(known if |no_ch==(-1)|) or if the next element of |input_organization|
+must be filled.
+
+@<Get a file name@>=
+{   if (no_ch==(-1)) {
+	out_name=argv[act_arg];
+    } else { register input_description *inp_desc;
+	inp_desc=(input_description *)
+		malloc(sizeof(input_description));
+	if (inp_desc==NULL)
+		fatal_error("! No memory for descriptor");
+@.No memory for descriptor@>
+	inp_desc->mode=search;
+	inp_desc->line=0;
+	inp_desc->type_of_file=chf;
+	inp_desc->limit=0;
+	inp_desc->name_of_file=argv[act_arg];
+	input_organization[no_ch]=inp_desc;
+    }
+    incr(no_ch);
+}
+
+
+@* The main program.
+
+\noindent Here is where \.{TIE} starts, and where it ends.
+
+@<The main function@>=
+main(argc,argv)
+        int argc; string *argv;
+{{@<Local variables for initialisation@>@;
+  @<Set initial...@>@;
+ }
+  print_ln(banner); /* print a ``banner line'' */
+  print_ln(copyright); /* include the copyright notice */
+  actual_input=0;
+  out_mode=normal;
+  @<Scan the parameters@>@;
+  @<Prepare the output file@>@;
+  @<Get the master file started@>@;
+  @<Prepare the change files@>@;
+  @<Process the input@>@;
+  @<Check that all changes have been read@>@;
+  @<Print the job |history|@>@;
+}
+
+@ We want to pass the |history| value to the operating system so that
+it can be used to govern whether or not other programs are started. 
+Additionaly we report the history to the user, although this may not
+be ``{\mc UNIX}'' style---but we are in best companion: \.{WEB} and
+\TeX{} do the same. 
+@^system dependencies@>
+
+@<Print the job |history|@>=
+{string msg;
+   switch (history) {
+      case spotless: msg="No errors were found"; break;
+      case troublesome: msg="Pardon me, but I think I spotted something wrong.";
+	        break;
+      case fatal: msg="That was a fatal error, my friend";  break;
+      } /* there are no other cases */
+   print2_nl("(%s.)",msg);  term_new_line;
+   exit ( history == spotless  ?  0 : 1 );
+}
+
+
+
+
+
+@* System-dependent changes.
+
+\noindent This section should be replaced, if necessary, by
+changes to the program that are necessary to make \.{TIE}
+work at a particular installation.  It is usually best to
+design your change file so that all changes to previous
+modules preserve the module numbering; then everybody's
+version will be consistent with the printed program.  More
+extensive changes, which introduce new modules, can be
+inserted here; then only the index itself will get a new
+module number.
+@^system dependencies@>
+
+
+
+
+
+@* Index.
+
+\noindent Here is the cross-reference table for the \.{TIE}
+processor.
Index: texk/web2c/tie/tiedoc.tex
diff -u /dev/null texk/web2c/tie/tiedoc.tex:1.1
--- /dev/null	Wed Nov  5 23:20:01 1997
+++ texk/web2c/tie/tiedoc.tex	Tue Sep  2 11:51:43 1997
@@ -0,0 +1,176 @@
+% tiedoc.tex   26 Oct 89
+%------------------------
+
+% 89-10-26 js: changed description of user interface which was altered
+%              in the rewrite of TIE in CWEB.
+% 88-12-?? kg: first release
+
+
+
+\documentstyle{article}
+
+\let\mc=\small
+\def\TANGLE{{\tt TANGLE}}
+\def\TIE{{\tt TIE}}
+\def\WEAVE{{\tt WEAVE}}
+\def\WEB{{\tt WEB}}
+\def\CWEB{{\mc CWEB}}
+\def\PASCAL{Pascal}
+
+
+\begin{document}
+
+\title{The \TIE{} Processor}
+\author{Klaus Guntermann\\
+TH Darmstadt\\
+Fachbereich Informatik\\
+Institut f\"ur Theoretische Informatik}
+\date{October 1989}
+
+\maketitle
+
+
+
+\section{Introduction}
+
+To install a program on a computer usually
+system dependent changes are needed.
+The systems of the \WEB{} family allows to describe these changes in a
+so called change file.
+To incorporate the changes into the program \TANGLE\ processes
+the original source file and inserts the changes into the proper places.
+
+Sometimes it is good practice to develop a set of change files to be able to
+distinguish between different changes like
+program enhancements, bug fixes, system dependent changes 
+and output device dependent modifications.
+Additionally this allows combinations of changes that can be used with a set of 
+programs that share some common features.
+
+The processors \TANGLE\ and \WEAVE\ can handle only one change file.
+The combination of change files is done best in another preprocessing step.
+\TIE\ is able to create either a new master file or a single change file that 
+comprises the effect of all change files.
+
+Since \TIE\ does not know anything about \WEB\ programs but only about the 
+structure of change files, it is possible to use this program for other 
+programming languages as well.
+You just pretend that you want to create a new master file and \TIE\ will go 
+and insert all the changes from your change files.
+
+
+
+\section{Application}
+
+The current version of \TIE\ accepts a master file and up to 9 change files.
+Because in general it is important to use the changes in their proper sequence 
+the order of the files must be chosen carefully.
+
+\TIE{} must be called with at least 4~parameters:
+%
+\begin{enumerate}
+
+\item either the option {\tt -c\/} or {\tt -m}. This option controls if
+a change file or a master file is created.
+
+\item the name of the output file.
+
+\item the name of the master file.
+
+\item the name(s) of the change file(s). At least one must be present.
+
+\end{enumerate}
+
+The multiple change files are used as if the single change files were
+merged into the master files step by step.  Thus more than 9 change
+files might be incorporated by repeated application of \TIE.  Of
+course you may change the constant {\it max\_file\_index\/} in \TIE{}
+which defines the maximum number of change files, too. 
+
+Please note that even when multiple change files are processed each of
+the files is read only once.  For each of the change files and for the
+master file there is only one line in memory at a time (neglecting
+operating system buffering).  Thus the storage requirement of \TIE\
+does not depend on the size of the change files or the size of a
+single changed section. 
+
+
+\newpage
+
+
+\def\eof{$\langle${\mc EOF}$\rangle$}
+\tabcolsep=1em
+
+
+\section{Example}
+
+To illustrate the actions \TIE\ performs you may inspect the following
+example that exercises some of the border line cases. 
+
+\begin{center}
+\begin{tabular}{llll}
+\multicolumn1{c}{\sc Master}&
+      \multicolumn1{c}{\tt CF1}&
+      \multicolumn1{c}{\tt CF2}&
+      \multicolumn1{c}{\tt CF3}\\[1pt]
+\hline
+line 1		&@x		&@x		&@x\\
+line 2		&line 2		&line 1		&changed line 4\\
+line 3		&line 3		&changed line 2	&@y\\
+line 4		&@y		&changed line 3	&final line 4\\
+line 5		&changed line 2	&inserted line	&@z\\
+line 6		&changed line 3	&line 4		&\eof\\
+line 7		&inserted line	&@y\\
+line 8		&@z		&final line 2\\
+line 9		&		&final line 3\\
+line 10		&@x		&changed line 4\\
+\eof		&line 7		&@z\\
+		&@y\\
+		&changed line 7	&@x\\
+		&@z		&changed line 7\\
+		&\eof		&line 8\\
+		&		&@y\\
+		&		&final line 7\\
+		&		&final line 8\\
+		&		&@z\\
+		&		&\eof\\
+\end{tabular}
+\end{center}
+
+
+\newpage
+
+
+Using these input files and running \TIE\ twice to create a new master
+file and a new change file will result in the following output files:
+
+\begin{center}
+\begin{tabular}{ll}
+\multicolumn1{c}{\sc Master}&
+      \multicolumn1{c}{\sc Change}\\[1pt]
+\hline
+final line 2	&@x\\
+final line 3	&line 1\\
+final line 4	&line 2\\
+line 5		&line 3\\
+line 6		&line 4\\
+final line 7	&@y\\
+final line 8	&final line 2\\
+line 9		&final line 3\\
+line 10		&final line 4\\
+\eof		&@z\\
+		&\\
+		&@x\\
+		&line 7\\
+		&line 8\\
+		&@y\\
+		&final line 7\\
+		&final line 8\\
+		&@z\\
+		&\eof\\
+\end{tabular}
+\end{center}
+
+
+
+\end{document}
Index: texk/web2c/triptrap/texmf.cnf
diff -u texk/web2c/triptrap/texmf.cnf:1.1.1.1 texk/web2c/triptrap/texmf.cnf:1.2
--- texk/web2c/triptrap/texmf.cnf:1.1.1.1	Fri Jul 18 17:02:49 1997
+++ texk/web2c/triptrap/texmf.cnf	Wed Oct 22 01:17:02 1997
@@ -30,7 +30,8 @@
 max_strings.inimpost = 2500
 
 string_vacancies = 8000
-pool_size = 32000
+% pool_size = 32000
+pool_size = 40000
 
 % TeX only.
 font_mem_size = 20000
Index: texk/web2c/window/x11-Xt.c
diff -u texk/web2c/window/x11-Xt.c:1.1.1.1 texk/web2c/window/x11-Xt.c:1.2
--- texk/web2c/window/x11-Xt.c:1.1.1.1	Fri Jul 18 17:02:39 1997
+++ texk/web2c/window/x11-Xt.c	Tue Oct 14 16:36:04 1997
@@ -10,7 +10,7 @@
 #include <kpathsea/systypes.h>
 
 /* See the kpathsea/INSTALL file for the purpose of the FOIL...  */
-#ifndef FOIL_X_WCHAR_T
+#if !defined(FOIL_X_WCHAR_T) && !defined(__sgi__)
 #define wchar_t foil_x_defining_wchar_t
 #define X_WCHAR
 #endif
Index: texk/xdvik/configure
diff -u texk/xdvik/configure:1.1.1.1 texk/xdvik/configure:1.3
--- texk/xdvik/configure:1.1.1.1	Fri Jul 18 17:05:31 1997
+++ texk/xdvik/configure	Mon Sep  8 23:40:52 1997
@@ -1609,10 +1609,10 @@
   withval="$with_maketexmf_default"
   :
 else
-  enableval=yes
+  withval=yes
 fi
 
-if test $enableval = yes; then
+if test $withval = yes; then
   cat >> confdefs.h <<\EOF
 #define MAKE_TEX_MF_BY_DEFAULT 1
 EOF
@@ -1623,10 +1623,10 @@
   withval="$with_maketexpk_default"
   :
 else
-  enableval=yes
+  withval=yes
 fi
 
-if test $enableval = yes; then
+if test $withval = yes; then
   cat >> confdefs.h <<\EOF
 #define MAKE_TEX_PK_BY_DEFAULT 1
 EOF
@@ -1637,10 +1637,10 @@
   withval="$with_maketextfm_default"
   :
 else
-  enableval=yes
+  withval=yes
 fi
 
-if test $enableval = yes; then
+if test $withval = yes; then
   cat >> confdefs.h <<\EOF
 #define MAKE_TEX_TFM_BY_DEFAULT 1
 EOF
Index: texk/xdvik/events.c
diff -u texk/xdvik/events.c:1.1.1.1 texk/xdvik/events.c:1.2
--- texk/xdvik/events.c:1.1.1.1	Fri Jul 18 17:05:23 1997
+++ texk/xdvik/events.c	Mon Sep  8 19:23:31 1997
@@ -160,15 +160,17 @@
 		{"Again",	"again",	'\001',		BPOS(4)},
 		{"Help",	"help",		'?',		BPOS(4)},
 		{"Reread",	"reread",	'R',		BPOS(5)},
-		{"100%",	"sh1",		1 << 8 | 's',	BPOS(7)},
-#define LOWRES_s_COMMANDS	6
+#define LOWRES_s_COMMANDS	5
+		{"100%", "sh1",		1 << 8 | 's',	BPOS(7)},
 		{"50%",	"sh2",		2 << 8 | 's',	BPOS(8)},
 		{"33%",	"sh3",		3 << 8 | 's',	BPOS(9)},
 		{"25%",	"sh4",		4 << 8 | 's',	BPOS(10)},
 #define HIRES_s_COMMANDS	9
-		{"33%",	"sh3",		3 << 8 | 's',	BPOS(8)},
-		{"25%",	"sh4",		4 << 8 | 's',	BPOS(9)},
-		{"17%",	"sh6",		6 << 8 | 's',	BPOS(10)},
+		{"50%",	"sh2",		2 << 8 | 's',	BPOS(7)},
+		{"25%",	"sh4",		4 << 8 | 's',	BPOS(8)},
+		{"17%",	"sh6",		6 << 8 | 's',	BPOS(9)},
+		{"13%", "sh8",		8 << 8 | 's',	BPOS(10)},
+#define NUMBER_s_COMMANDS	(HIRES_s_COMMANDS - LOWRES_s_COMMANDS)
 
 		{"First",	"next0",	1 << 8 | 'g',   BPOS(12)},
 		{"Page-10",	"prev10",	10 << 8 | 'p',	BPOS(13)},
@@ -352,7 +354,8 @@
 	command_args[2].value = (XtArgVal) vport_widget;
 	for (i = 0; i < XtNumber(command_table); ++i) {
 	    if ( ((i==HIRES_s_COMMANDS)&&(pixels_per_inch<600)) ||
-	        ((i==LOWRES_s_COMMANDS)&&(pixels_per_inch>=600)) ) i+=3;
+	        ((i==LOWRES_s_COMMANDS)&&(pixels_per_inch>=600)) )
+	      i+=NUMBER_s_COMMANDS;
 	    command_args[0].value = (XtArgVal) command_table[i].label;
 	    command_args[2].value = (XtArgVal) command_table[i].y_pos;
 	    command_call[0].closure = (XtPointer) &command_table[i].closure;
Index: texk/xdvik/xdvi.c
diff -u texk/xdvik/xdvi.c:1.1.1.1 texk/xdvik/xdvi.c:1.2
--- texk/xdvik/xdvi.c:1.1.1.1	Fri Jul 18 17:05:26 1997
+++ texk/xdvik/xdvi.c	Mon Sep  8 19:26:56 1997
@@ -373,7 +373,7 @@
 {"delayRulers", "DelayRulers", XtRBoolean, sizeof(Boolean),
  offset(_delay_rulers), XtRString, "true"},
 {"densityPercent", "DensityPercent", XtRInt, sizeof(int),
-  offset(_density), XtRString, "40"},
+  offset(_density), XtRString, "20"},
 #ifdef  GREY
 {"gamma", "Gamma", XtRFloat, sizeof(float),
   offset(_gamma), XtRString, "1"},
Index: texk/xdvik/xdvi.h
diff -u texk/xdvik/xdvi.h:1.1.1.1 texk/xdvik/xdvi.h:1.2
--- texk/xdvik/xdvi.h:1.1.1.1	Fri Jul 18 17:05:22 1997
+++ texk/xdvik/xdvi.h	Mon Sep  8 19:29:33 1997
@@ -127,7 +127,7 @@
 
 #ifndef	NORETURN
 #ifdef	__GNUC__
-#define	NORETURN	volatile
+#define	NORETURN	__volatile__
 #else
 #define	NORETURN	/* nothing */
 #endif
