This file is part of web2w.
Copyright 2017 Martin Ruckert

web2w is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

web2w is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with web2w.  If not, see <http://www.gnu.org/licenses/>.
 
Martin Ruckert, Hochschule Muenchen, Lothstrasse 64, 80336 Muenchen
--- hint.w	2017-07-28 10:40:38.023223082 +0200
+++ tex.w	2017-07-28 10:43:49.801661332 +0200
@@ -73,11 +73,6 @@
 \def\(#1){} % this is used to make section names sort themselves better
 \def\9#1{} % this is used for sort keys in the index via @@:sort key}{entry@@>
 
-\outer\def\N#1. \[#2]#3.{\MN#1.\vfil\eject % begin starred section
-  \def\rhead{PART #2:\uppercase{#3}} % define running headline
-  \message{*\modno} % progress report
-  \edef\next{\write\cont{\Z{\?#2]#3}{\modno}{\the\pageno}}}\next
-  \ifon\startsection{\bf\ignorespaces#3.\quad}\ignorespaces}
 \let\?=\relax % we want to be able to \write a \?
 
 \def\title{\TeX82}
@@ -90,6 +85,22 @@
 \def\glob{13} % this should be the section number of "<Global...>"
 \def\gglob{20, 26} % this should be the next two sections of "<Global...>"
 
+\def\.#1{\leavevmode\hbox{\tentex % typewriter type for strings
+  \let\\=\BS % backslash in a string
+  \let\'=\RQ % right quote in a string
+  \let\`=\LQ % left quote in a string
+  \let\{=\LB % left brace in a string
+  \let\}=\RB % right brace in a string
+  \let\~=\TL % tilde in a string
+  \let\ =\SP % space in a string
+  \let\_=\UL % underline in a string
+  \let\&=\AM % ampersand in a string
+  #1\kern.05em}}
+\def\^{\ifmmode\mathchar"222 \else\char`^ \fi} % pointer or hat
+\def\LQ{{\tt\char'22}} % left quote in a string
+\def\RQ{{\tt\char'23}} % right quote in a string
+\def\dotdot{\mathrel{.\,.}} % double dot, used only in math mode
+@s dotdot TeX
 @* Introduction.
 This is \TeX, a document compiler intended to produce typesetting of high
 quality.
@@ -188,7 +199,7 @@
 known as `\TeX' [cf.~Stanford Computer Science report CS1027,
 November 1984].
 
-@d banner	"This is TeX, Version 3.14159265" /*printed when \TeX\ starts*/ 
+@d banner	"This is TeX, Version 3.14159265 (HINT)" /*printed when \TeX\ starts*/ 
 
 @ Different \PASCAL s have slightly different conventions, and the present
 @!@:PASCAL H}{\ph@>
@@ -318,12 +329,33 @@
 @^system dependencies@>
 @^overflow in arithmetic@>
 
+@s int8_t int
+@s uint8_t int
+@s uint16_t int
+@s halfword int
+@s in TeX
+@s line normal
+@s to   do
+
 @<Compiler directives@>=
-/*@&$C-,A+,D-*/ /*no range check, catch arithmetic overflow, no debug overhead*/ 
-#ifdef @!DEBUG
-/*@&$C+,D+*/
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#define odd(X)       ((X)&1)
+#define chr(X)       ((unsigned char)(X))
+#define ord(X)       ((int)(X))
+
+#if __SIZEOF_FLOAT__==4
+typedef float float32_t;
+#else
+#error  float type must have size 4
 #endif
- /*but turn everything on when debugging*/ 
+
+@h
 
 @ This \TeX\ implementation conforms to the rules of the {\sl Pascal User
 @:PASCAL}{\PASCAL@>
@@ -757,7 +789,7 @@
 @^system dependencies@>
 
 @<Glob...@>=
-uint8_t @!name_of_file0[file_name_size], *const @!name_of_file = @!name_of_file0-1;@;@/
+uint8_t @!name_of_file0[file_name_size+1]={0}, *const @!name_of_file = @!name_of_file0-1;@;@/
    /*on some systems this may be a \&{record} variable*/ 
 uint8_t @!name_length;@/ /*this many characters are actually
   relevant in |name_of_file| (the rest are blank)*/ 
@@ -790,32 +822,32 @@
 
 @p bool a_open_in(alpha_file *f)
    /*open a text file for input*/ 
-{@+reset((*f), name_of_file,"/O");return reset_OK((*f));
+{@+reset((*f), name_of_file,"r");return reset_OK((*f));
 } 
 @#
 bool a_open_out(alpha_file *f)
    /*open a text file for output*/ 
-{@+rewrite((*f), name_of_file,"/O");return rewrite_OK((*f));
+{@+rewrite((*f), name_of_file,"w");return rewrite_OK((*f));
 } 
 @#
 bool b_open_in(byte_file *f)
    /*open a binary file for input*/ 
-{@+reset((*f), name_of_file,"/O");return reset_OK((*f));
+{@+reset((*f), name_of_file,"rb");return reset_OK((*f));
 } 
 @#
 bool b_open_out(byte_file *f)
    /*open a binary file for output*/ 
-{@+rewrite((*f), name_of_file,"/O");return rewrite_OK((*f));
+{@+rewrite((*f), name_of_file,"wb");return rewrite_OK((*f));
 } 
 @#
 bool w_open_in(word_file *f)
    /*open a word file for input*/ 
-{@+reset((*f), name_of_file,"/O");return reset_OK((*f));
+{@+reset((*f), name_of_file,"rb");return reset_OK((*f));
 } 
 @#
 bool w_open_out(word_file *f)
    /*open a word file for output*/ 
-{@+rewrite((*f), name_of_file,"/O");return rewrite_OK((*f));
+{@+rewrite((*f), name_of_file,"wb");return rewrite_OK((*f));
 } 
 
 @ Files can be closed with the \ph\ routine `|close(f)|', which
@@ -938,8 +970,8 @@
 @:PASCAL H}{\ph@>
 @^system dependencies@>
 
-@d t_open_in	reset(term_in,"TTY:","/O/I") /*open the terminal for text input*/ 
-@d t_open_out	rewrite(term_out,"TTY:","/O") /*open the terminal for text output*/ 
+@d t_open_in	term_in.f=stdin /*open the terminal for text input*/ 
+@d t_open_out   term_out.f=stdout /*open the terminal for text output*/ 
 
 @ Sometimes it is necessary to synchronize the input/output mixture that
 happens on the user's terminal, and three system-dependent
@@ -956,8 +988,8 @@
 @:PASCAL H}{\ph@>
 @^system dependencies@>
 
-@d update_terminal	break(term_out) /*empty the terminal output buffer*/ 
-@d clear_terminal	break_in(term_in, true) /*clear the terminal input buffer*/ 
+@d update_terminal	fflush(term_out.f) /*empty the terminal output buffer*/ 
+@d clear_terminal	fflush(term_in.f) /*clear the terminal input buffer*/ 
 @d wake_up_terminal	do_nothing /*cancel the user's cancellation of output*/ 
 
 @ We need a special routine to read the first line of \TeX\ input from
@@ -1103,10 +1135,11 @@
 typedef uint8_t packed_ASCII_code; /*elements of |str_pool| array*/ 
 
 @ @<Glob...@>=
-packed_ASCII_code @!str_pool[pool_size+1]; /*the characters*/ 
-pool_pointer @!str_start[max_strings+1]; /*the starting pointers*/ 
-pool_pointer @!pool_ptr; /*first unused position in |str_pool|*/ 
-str_number @!str_ptr; /*number of the current string being created*/ 
+@<prepare for string pool initialization@>@;
+packed_ASCII_code @!str_pool[pool_size+1]= @<|str_pool| initialization@>; /*the characters*/ 
+pool_pointer @!str_start[max_strings+1]= {@<|str_start| initialization@>}; /*the starting pointers*/ 
+pool_pointer @!pool_ptr=@<|pool_ptr| initialization@>; /*first unused position in |str_pool|*/ 
+str_number @!str_ptr=@<|str_ptr| initialization@>; /*number of the current string being created*/
 pool_pointer @!init_pool_ptr; /*the starting value of |pool_ptr|*/ 
 str_number @!init_str_ptr; /*the starting value of |str_ptr|*/ 
 
@@ -1231,11 +1264,11 @@
 
 @<Make the first 256...@>=
 for (k=0; k<=255; k++) 
-  {@+if ((@<Character |k| cannot be printed@>)) 
-    {@+append_char('^');append_char('^');
+  { if (@[@<Character |k| cannot be printed@>@]) 
+    { append_char('^');append_char('^');
     if (k < 0100) append_char(k+0100)@;
     else if (k < 0200) append_char(k-0100)@;
-    else{@+app_lc_hex(k/16);app_lc_hex(k%16);
+    else{ app_lc_hex(k/16);app_lc_hex(k%16);
       } 
     } 
   else append_char(k);
@@ -1289,7 +1322,7 @@
   a_close(&pool_file);return false;
   } 
 @<Read the other strings...@>=
-name_of_file=pool_name; /*we needn't set |name_length|*/ 
+{@+int k;@+for(k=1; k<=file_name_size;k++)name_of_file[k]=pool_name[k-1];@+} /*we needn't set |name_length|*/ 
 if (a_open_in(&pool_file)) 
   {@+c=false;
   @/do@+{@<Read one string, but return |false| if the string memory space is getting
@@ -1303,7 +1336,7 @@
 @ @<Read one string...@>=
 {@+if (eof(pool_file)) bad_pool("! TEX.POOL has no check sum.");
 @.TEX.POOL has no check sum@>
-read(pool_file, m, n); /*read two digits of string length*/ 
+read(pool_file, m);@+read(pool_file, n); /*read two digits of string length*/ 
 if (m== '*' ) @<Check the pool check sum@>@;
 else{@+if ((xord[m] < '0')||(xord[m] > '9')||@|
       (xord[n] < '0')||(xord[n] > '9')) 
@@ -1411,12 +1444,30 @@
 by changing |wterm|, |wterm_ln|, and |wterm_cr| in this section.
 @^system dependencies@>
 
-@d wterm(X)	write(term_out, X)
-@d wterm_ln(...)	write_ln(term_out,__VA_ARGS__)
-@d wterm_cr	write_ln(term_out)
-@d wlog(...)	write(log_file,__VA_ARGS__)
-@d wlog_ln(...)	write_ln(log_file,__VA_ARGS__)
-@d wlog_cr	write_ln(log_file)
+@<Compiler directives@>=
+#define put(file)    @[fwrite(&((file).d),sizeof((file).d),1,(file).f)@]
+#define get(file)    @[fread(&((file).d),sizeof((file).d),1,(file).f)@]
+
+#define reset(file,name,mode)   @[((file).f=fopen((char *)(name)+1,mode),\
+                                 (file).f!=NULL?get(file):0)@]
+#define rewrite(file,name,mode) @[((file).f=fopen((char *)(name)+1,mode))@]
+#define close(file)    @[fclose((file).f)@]
+#define eof(file)    @[feof((file).f)@]
+#define eoln(file)    @[((file).d=='\n'||eof(file))@]
+#define erstat(file)   @[((file).f==NULL?-1:ferror((file).f))@]
+
+#define read(file,x) @[((x)=(file).d,get(file))@]
+#define read_ln(file)  @[do get(file); while (!eoln(file))@]
+
+#define write(file, format,...)    @[fprintf(file.f,format,## __VA_ARGS__)@]
+#define write_ln(file,...)	   @[write(file,__VA_ARGS__"\n")@]
+
+#define wterm(format,...)	@[write(term_out,format, ## __VA_ARGS__)@]
+#define wterm_ln(format,...)	@[wterm(format "\n", ## __VA_ARGS__)@]
+#define wterm_cr	        @[write(term_out,"\n")@]
+#define wlog(format, ...)	@[write(log_file,format, ## __VA_ARGS__)@]
+#define wlog_ln(format, ...)   @[wlog(format "\n", ## __VA_ARGS__)@]
+#define wlog_cr	        @[write(log_file,"\n")@]
 
 @ To end a line of text output, we call |print_ln|.
 
@@ -1447,7 +1498,7 @@
   {@+print_ln();return;
   } 
 switch (selector) {
-case term_and_log: {@+wterm(xchr[s]);wlog(xchr[s]);
+case term_and_log: {@+wterm("%c",xchr[s]);wlog("%c",xchr[s]);
   incr(term_offset);incr(file_offset);
   if (term_offset==max_print_line) 
     {@+wterm_cr;term_offset=0;
@@ -1456,17 +1507,17 @@
     {@+wlog_cr;file_offset=0;
     } 
   } @+break;
-case log_only: {@+wlog(xchr[s]);incr(file_offset);
+case log_only: {@+wlog("%c",xchr[s]);incr(file_offset);
   if (file_offset==max_print_line) print_ln();
   } @+break;
-case term_only: {@+wterm(xchr[s]);incr(term_offset);
+case term_only: {@+wterm("%c",xchr[s]);incr(term_offset);
   if (term_offset==max_print_line) print_ln();
   } @+break;
 case no_print: do_nothing;@+break;
 case pseudo: if (tally < trick_count) trick_buf[tally%error_line]=s;@+break;
 case new_string: {@+if (pool_ptr < pool_size) append_char(s);
   } @+break; /*we drop characters if the string space is full*/ 
-default:write(write_file[selector], xchr[s]);
+default:write(write_file[selector],"%c", xchr[s]);
 } @/
 incr(tally);
 } 
@@ -1509,6 +1560,10 @@
   } 
 } 
 
+void print_str(char *s) /* the simple version */
+{while (*s!=0) print_char(*s++);@+
+} 
+
 @ Control sequence names, file names, and strings constructed with
 \.{\\string} might contain |ASCII_code| values that can't
 be printed using |print_char|. Therefore we use |slow_print| for them:
@@ -1531,7 +1586,7 @@
 character positions.
 
 @<Initialize the output...@>=
-wterm(banner);
+wterm("%s",banner);
 if (format_ident==0) wterm_ln(" (no format preloaded)");
 else{@+slow_print(format_ident);print_ln();
   } 
@@ -1541,10 +1596,10 @@
 string appears at the beginning of a new line.
 
 @<Basic print...@>=
-void print_nl(str_number @!s) /*prints string |s| at beginning of line*/ 
+void print_nl(char *@!s) /*prints string |s| at beginning of line*/ 
 {@+if (((term_offset > 0)&&(odd(selector)))||@|
   ((file_offset > 0)&&(selector >= log_only))) print_ln();
-print(s);
+print_str(s);
 } 
 
 @ The procedure |print_esc| prints a string that is preceded by
@@ -1681,10 +1736,10 @@
 @* Reporting errors.
 When something anomalous is detected, \TeX\ typically does something like this:
 $$\vbox{\halign{#\hfil\cr
-|print_err(@[@<|"Something anomalous has been detected"|@>@]);|\cr
-|help3(@[@<|"This is the first line of my offer to help."|@>@])|\cr
-|(@[@<|"This is the second line. I'm trying to"|@>@])|\cr
-|(@[@<|"explain the best way for you to proceed."|@>@]);|\cr
+|print_err("Something anomalous has been detected");|\cr
+|help3("This is the first line of my offer to help.")|\cr
+|("This is the second line. I'm trying to")|\cr
+|("explain the best way for you to proceed.");|\cr
 |error;|\cr}}$$
 A two-line help message would be given using |help2|, etc.; these informal
 helps should use simple vocabulary that complements the words used in the
@@ -1788,10 +1843,10 @@
 void close_files_and_terminate(void);@/
 void clear_for_error_prompt(void);@/
 void give_err_help(void);@/
-@t\4\hskip-\fontdimen2\font@>@;
 #ifdef @!DEBUG
-@+void debug_help(void)
-  ;@;
+void debug_help(void);
+#else
+#define debug_help() do_nothing
 #endif
 
 @ Individual lines of help are recorded in the array |help_line|, which
@@ -1813,7 +1868,7 @@
 @d help6	@+{@+help_ptr=6;hlp6 /*use this with six help lines*/ 
 
 @<Glob...@>=
-str_number @!help_line[6]; /*helps for the next |error|*/ 
+char *@!help_line[6]; /*helps for the next |error|*/ 
 uint8_t @!help_ptr; /*the number of help lines present*/ 
 bool @!use_err_help; /*should the |err_help| list be shown?*/ 
 
@@ -1832,7 +1887,7 @@
 
 @<Error hand...@>=
 void jump_out(void)
-{@+goto end_of_TEX;
+{@+ close_files_and_terminate(); exit(0);
 } 
 
 @ Here now is the general |error| routine.
@@ -1972,7 +2027,7 @@
 else{@+if (help_ptr==0) 
     help2("Sorry, I don't know how to help in this situation.")@/
     @t\kern1em@>("Maybe you should try asking a human?");
-  @/do@+{decr(help_ptr);print(help_line[help_ptr]);print_ln();
+  @/do@+{decr(help_ptr);print_str(help_line[help_ptr]);print_ln();
   }@+ while (!(help_ptr==0));
   } 
 help4("Sorry, I already gave what help I could...")@/
@@ -2017,16 +2072,12 @@
 @d succumb	{@+if (interaction==error_stop_mode) 
     interaction=scroll_mode; /*no more interaction*/ 
   if (log_opened) error();
-  
-#ifdef @!DEBUG
-if (interaction > batch_mode) debug_help();
-#endif
-@;@/
+  if (interaction > batch_mode) debug_help();
   history=fatal_error_stop;jump_out(); /*irrecoverable error*/ 
   } 
 
 @<Error hand...@>=
-void fatal_error(str_number @!s) /*prints |s|, and that's it*/ 
+void fatal_error(char *@!s) /*prints |s|, and that's it*/ 
 {@+normalize_selector();@/
 print_err("Emergency stop");help1(s);succumb;
 @.Emergency stop@>
@@ -2035,11 +2086,11 @@
 @ Here is the most dreaded error message.
 
 @<Error hand...@>=
-void overflow(str_number @!s, int @!n) /*stop due to finiteness*/ 
+void overflow(char *@!s, int @!n) /*stop due to finiteness*/ 
 {@+normalize_selector();
 print_err("TeX capacity exceeded, sorry [");
 @.TeX capacity exceeded ...@>
-print(s);print_char('=');print_int(n);print_char(']');
+print_str(s);print_char('=');print_int(n);print_char(']');
 help2("If you really absolutely need more capacity,")@/
   ("you can ask a wizard to enlarge me.");
 succumb;
@@ -2202,7 +2253,7 @@
 The present implementation of \TeX\ does not check for overflow when
 @^overflow in arithmetic@>
 dimensions are added or subtracted. This could be done by inserting a
-few dozen tests of the form `\ignorespaces|if (x >= 010000000000) 
+few dozen tests of the form `\ignorespaces|if (x >= 010000000000)@/
 @t\\{report\_overflow}@>|', but the chance of overflow is so remote that
 such tests do not seem worthwhile.
 
@@ -2332,12 +2383,12 @@
 
 @d set_glue_ratio_zero(X)	X=0.0 /*store the representation of zero ratio*/ 
 @d set_glue_ratio_one(X)	X=1.0 /*store the representation of unit ratio*/ 
-@d float(X)	X /*convert from |glue_ratio| to type |double|*/ 
-@d unfloat(X)	X /*convert from |double| to type |glue_ratio|*/ 
-@d float_constant(X)	X.0 /*convert |int| constant to |double|*/ 
+@d float(X)	((double)(X)) /*convert from |glue_ratio| to type |double|*/ 
+@d unfloat(X)	((glue_ratio)(X)) /*convert from |double| to type |glue_ratio|*/ 
+@d float_constant(X)	((double)(X)) /*convert |int| constant to |double|*/ 
 
 @<Types...@>=
-typedef double glue_ratio; /*one-word representation of a glue expansion factor*/ 
+typedef float32_t @!glue_ratio; /*one-word representation of a glue expansion factor*/ 
 
 @* Packed data.
 In order to make efficient use of storage space, \TeX\ bases its major data
@@ -2500,6 +2551,7 @@
 value represents a null pointer. \TeX\ does not assume that |mem[null]| exists.
 
 @d pointer	halfword /*a flag or a location in |mem| or |eqtb|*/ 
+@s pointer int
 @d null	min_halfword /*the null pointer*/ 
 
 @<Glob...@>=
@@ -2549,7 +2601,14 @@
 
 @<Glob...@>=
 int @!var_used, @!dyn_used; /*how much memory is in use*/ 
-
+#ifdef @!DEBUG
+#define incr_dyn_used @[incr(dyn_used)@]
+#define decr_dyn_used @[decr(dyn_used)@]
+#else
+#define incr_dyn_used
+#define decr_dyn_used
+#endif
+ 
 @ Let's consider the one-word memory region first, since it's the
 simplest. The pointer variable |mem_end| holds the highest-numbered location
 of |mem| that has ever been used. The free locations of |mem| that
@@ -2599,10 +2658,7 @@
     } 
   } 
 link(p)=null; /*provide an oft-desired initialization of the new node*/ 
-#ifdef @!STAT
-incr(dyn_used);
-#endif
-@; /*maintain statistics*/ 
+incr_dyn_used; /*maintain statistics*/ 
 return p;
 } 
 
@@ -2612,10 +2668,7 @@
 
 @d free_avail(X)	 /*single-word node liberation*/ 
   {@+link(X)=avail;avail=X;
-  
-#ifdef @!STAT
-decr(dyn_used);
-#endif
+    decr_dyn_used;
   } 
 
 @ There's also a |fast_get_avail| routine, which saves the procedure-call
@@ -2627,10 +2680,7 @@
   {@+X=avail; /*avoid |get_avail| if possible, to save time*/ 
   if (X==null) X=get_avail();
   else{@+avail=link(X);link(X)=null;
-    
-#ifdef @!STAT
-incr(dyn_used);
-#endif
+        incr_dyn_used;
     } 
   } 
 
@@ -2644,9 +2694,7 @@
 if (p!=null) 
   {@+r=p;
   @/do@+{q=r;r=link(r);
-#ifdef @!STAT
-decr(dyn_used);
-#endif
+  decr_dyn_used;
   }@+ while (!(r==null)); /*now |q| is the last node on the list*/ 
   link(q)=avail;avail=p;
   } 
@@ -8168,7 +8216,7 @@
 else pstack[n]=link(temp_head);
 incr(n);
 if (tracing_macros > 0) 
-  {@+begin_diagnostic();print_nl(match_chr);print_int(n);
+  {@+begin_diagnostic();print_nl("");print(match_chr);print_int(n);
   print_str("<-");show_token_list(pstack[n-1], null, 1000);
   end_diagnostic(false);
   } 
@@ -9997,10 +10045,7 @@
 |TEX_font_area|.  These system area names will, of course, vary from place
 to place.
 @^system dependencies@>
-
-@d TEX_area	TEX_area
 @.TeXinputs@>
-@d TEX_font_area	TEX_font_area
 @.TeXfonts@>
 
 @ Here now is the first of the system-dependent routines for file name scanning.
@@ -10076,7 +10121,7 @@
 for (j=str_start[n]; j<=str_start[n+1]-1; j++) append_to_name(so(str_pool[j]));
 for (j=str_start[e]; j<=str_start[e+1]-1; j++) append_to_name(so(str_pool[j]));
 if (k <= file_name_size) name_length=k;@+else name_length=file_name_size;
-for (k=name_length+1; k<=file_name_size; k++) name_of_file[k]= ' ' ;
+name_of_file[name_length+1]=0;
 } 
 
 @ A messier routine is also needed, since format file names must be scanned
@@ -10088,13 +10133,10 @@
 @d format_default_length	20 /*length of the |TEX_format_default| string*/ 
 @d format_area_length	11 /*length of its area part*/ 
 @d format_ext_length	4 /*length of its `\.{.fmt}' part*/ 
-@d format_extension	format_extension /*the extension, as a \.{WEB} constant*/ 
+@d format_extension_str ".fmt" /*the extension, as a \.{WEB} constant*/ 
 
 @<Glob...@>=
-uint8_t @!TEX_format_default0[format_default_length], *const @!TEX_format_default = @!TEX_format_default0-1;
-
-@ @<Set init...@>=
-TEX_format_default="TeXformats:plain.fmt";
+ASCII_code @!TEX_format_default[1+format_default_length+1]=" TeXformats/plain.fmt";
 @.TeXformats@>
 @.plain@>
 @^system dependencies@>
@@ -10125,7 +10167,7 @@
 for (j=format_default_length-format_ext_length+1; j<=format_default_length; j++) 
   append_to_name(xord[TEX_format_default[j]]);
 if (k <= file_name_size) name_length=k;@+else name_length=file_name_size;
-for (k=name_length+1; k<=file_name_size; k++) name_of_file[k]= ' ' ;
+name_of_file[name_length+1]=0;
 } 
 
 @ Here is the only place we use |pack_buffered_name|. This part of the program
@@ -10149,7 +10191,7 @@
      /*now try the system format file area*/ 
   if (w_open_in(&fmt_file)) goto found;
   wake_up_terminal;
-  wterm_ln("Sorry, I can't find that format;"," will try PLAIN.");
+  wterm_ln("Sorry, I can't find that format; will try PLAIN.");
 @.Sorry, I can't find...@>
   update_terminal;
   } 
@@ -10255,17 +10297,17 @@
 variables |cur_name|, |cur_area|, |cur_ext|, and |name_of_file| are
 ready for another attempt at file opening.
 
-@p void prompt_file_name(str_number @!s, str_number @!e)
+@p void prompt_file_name(char *@!s, str_number @!e)
 {@+
 uint16_t k; /*index into |buffer|*/ 
 if (interaction==scroll_mode) wake_up_terminal;
-if (s==@[@<|"input file name"|@>@]) print_err("I can't find file `")@;
+if (strcmp(s,"input file name")==0) print_err("I can't find file `")@;
 @.I can't find file x@>
 else print_err("I can't write on file `");
 @.I can't write on file x@>
 print_file_name(cur_name, cur_area, cur_ext);print_str("'.");
 if (e==@[@<|".tex"|@>@]) show_context();
-print_nl("Please type another ");print(s);
+print_nl("Please type another ");print_str(s);
 @.Please type...@>
 if (interaction < scroll_mode) 
   fatal_error("*** (job aborted, file error in nonstop mode)");
@@ -10286,9 +10328,10 @@
 } 
 
 @ Here's an example of how these conventions are used. Whenever it is time to
-ship out a box of stuff, we shall use the macro |ensure_dvi_open|.
+ship out a box of stuff, we shall use |@<ensure dvi open@>|.
 
-@d ensure_dvi_open	if (output_file_name==0) 
+@<ensure dvi open@>=
+if (output_file_name==0) 
   {@+if (job_name==0) open_log_file();
   pack_job_name(@[@<|".dvi"|@>@]);
   while (!b_open_out(&dvi_file)) 
@@ -10296,7 +10339,7 @@
   output_file_name=b_make_name_string(&dvi_file);
   } 
 
-@<Glob...@>=
+@ @<Glob...@>=
 byte_file @!dvi_file; /*the device-independent output goes here*/ 
 str_number @!output_file_name; /*full name of the output file*/ 
 str_number @!log_name; /*full name of the log file*/ 
@@ -10310,7 +10353,7 @@
 {@+uint8_t old_setting; /*previous |selector| setting*/ 
 int @!k; /*index into |months| and |buffer|*/ 
 uint16_t @!l; /*end of first input line*/ 
-uint8_t @!months0[36], *const @!months = @!months0-1; /*abbreviations of month names*/ 
+@!ASCII_code @!months[]=" JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"; /*abbreviations of month names*/ 
 old_setting=selector;
 if (job_name==0) job_name=@[@<|"texput"|@>@];
 @.texput@>
@@ -10349,11 +10392,10 @@
 } 
 
 @ @<Print the banner...@>=
-{@+wlog(banner);
+{@+wlog("%s",banner);
 slow_print(format_ident);print_str("  ");
 print_int(day);print_char(' ');
-months="JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
-for (k=3*month-2; k<=3*month; k++) wlog(months[k]);
+for (k=3*month-2; k<=3*month; k++) wlog("%c",months[k]);
 print_char(' ');print_int(year);print_char(' ');
 print_two(time/60);print_char(':');print_two(time%60);
 } 
@@ -10453,7 +10495,8 @@
 @ The rest of the \.{TFM} file may be regarded as a sequence of ten data
 arrays having the informal specification
 $$\def\arr$[#1]#2${\&{array} $[#1]$ \&{of} #2}
-\vbox{\halign{\hfil\\{#}&$\,:\,$\arr#\hfil\cr
+\def\PB#1{\arr#1}
+\vbox{\halign{\hfil\\{#}&$\,:\,$#\hfil\cr
 header&|[0 dotdot lh-1]@t\\{stuff}@>|\cr
 char\_info&|[bc dotdot ec]char_info_word|\cr
 width&|[0 dotdot nw-1]fix_word|\cr
@@ -11913,7 +11956,7 @@
 
 @p void write_dvi(dvi_index @!a, dvi_index @!b)
 {@+int k;
-for (k=a; k<=b; k++) write(dvi_file, dvi_buf[k]);
+for (k=a; k<=b; k++) write(dvi_file, "%c", dvi_buf[k]);
 } 
 
 @ To put a byte in the buffer without paying the cost of invoking a procedure
@@ -12279,7 +12322,7 @@
 
 @ @<Initialize variables as |ship_out| begins@>=
 dvi_h=0;dvi_v=0;cur_h=h_offset;dvi_f=null_font;
-ensure_dvi_open;
+@<ensure dvi open@>;
 if (total_pages==0) 
   {@+dvi_out(pre);dvi_out(id_byte); /*output the preamble*/ 
 @^preamble of \.{DVI} file@>
@@ -13135,10 +13178,11 @@
 computed by the normal rules; if it exceeds this limit, the reference
 point is simply moved down until the limiting depth is attained.
 
-@d vpack(...)	vpackage(__VA_ARGS__, max_dimen) /*special case of unconstrained depth*/ 
-
 @p
-  pointer vpackage(pointer @!p, scaled @!h, small_number @!m, scaled @!l)
+#define vpack(...)	@[vpackage(__VA_ARGS__, max_dimen)@]
+    /*special case of unconstrained depth*/ 
+
+pointer vpackage(pointer @!p, scaled @!h, small_number @!m, scaled @!l)
 {@+
 pointer r; /*the box node that will be returned*/ 
 scaled @!w, @!d, @!x; /*width, depth, and natural height*/ 
@@ -15023,9 +15067,9 @@
 the program would not have been so strange.
 @:PASCAL}{\PASCAL@>
 
-@d math_spacing	@;@/
+@d math_spacing_str	@;@/
 @t\hskip-35pt@>
-math_spacing
+"math_spacing"
 @t$ \hskip-35pt$@>
 
 @<Glob...@>=
@@ -16337,7 +16381,7 @@
 should no longer be active; then |goto continue| if a line from |r| to |cur_p| is
 infeasible, otherwise record a new feasible break@>;
   } 
-end: 
+end: ;
 #ifdef @!STAT
 @<Update the value of |printed_node| for symbolic displays@>;
 #endif
@@ -16358,7 +16402,9 @@
 halfword @!b; /*badness of test line*/ 
 int @!d; /*demerits of test line*/ 
 bool @!artificial_demerits; /*has |d| been forced to zero?*/ 
+#ifdef @!STAT
 pointer @!save_link; /*temporarily holds value of |link(cur_p)|*/ 
+#endif
 scaled @!shortfall; /*used in badness calculations*/ 
 
 @ @<Make sure that |pi| is in the proper range@>=
@@ -17790,7 +17836,7 @@
 ligature and a |lig_ptr| field that points to a |char_node| or is |null|.
 We have
 $$|cur_r|=\cases{|character(lig_stack)|,&if |lig_stack > null|;\cr
-  |qi(hu[j+1])|,&if |lig_stack==null| and |j < n|;\cr
+  \hbox{|qi(hu[j+1])|},&if |lig_stack==null| and |j < n|;\cr
   bchar,&if |lig_stack==null| and |j==n|.\cr}$$
 
 @<Glob...@>=
@@ -23733,7 +23779,7 @@
 incompatible with the present \TeX\ table sizes, etc.
 
 @d too_small(X)	{@+wake_up_terminal;
-  wterm_ln("---! Must increase the ", X);
+  wterm_ln("---! Must increase the %s", X);
 @.Must increase the x@>
   goto bad_fmt;
   } 
@@ -24246,14 +24292,13 @@
 if (ready_already==314159) goto start_of_TEX;
 @<Check the ``constant'' values...@>@;
 if (bad > 0) 
-  {@+wterm_ln("Ouch---my internal constants have been clobbered!",
-    "---case ", bad: 1);
+  {@+wterm_ln("Ouch---my internal constants have been clobbered!"
+    "---case %d", bad);
 @.Ouch...clobbered@>
   exit(0);
   } 
 initialize(); /*set global variables to their starting values*/ 
 #ifdef @!INIT
-if (!get_strings_started()) exit(0);
 init_prim(); /*call |primitive| for each primitive*/ 
 init_str_ptr=str_ptr;init_pool_ptr=pool_ptr;fix_date_and_time();
 #endif
@@ -24263,7 +24308,7 @@
 history=spotless; /*ready to go!*/ 
 main_control(); /*come to life*/ 
 final_cleanup(); /*prepare for death*/ 
-end_of_TEX: close_files_and_terminate();
+close_files_and_terminate();
 ready_already=0;
 return 0; }
 
@@ -24305,34 +24350,33 @@
 
 @<Output statistics...@>=
 if (log_opened) 
-  {@+wlog_ln( ' ' );
-  wlog_ln("Here is how much of TeX's memory"," you used:");
+  {@+wlog_ln(" ");
+  wlog_ln("Here is how much of TeX's memory you used:");
 @.Here is how much...@>
-  wlog( ' ' , str_ptr-init_str_ptr: 1," string");
-  if (str_ptr!=init_str_ptr+1) wlog( 's' );
-  wlog_ln(" out of ", max_strings-init_str_ptr: 1);@/
-  wlog_ln( ' ' , pool_ptr-init_pool_ptr: 1," string characters out of ",
-    pool_size-init_pool_ptr: 1);@/
-  wlog_ln( ' ' , lo_mem_max-mem_min+mem_end-hi_mem_min+2: 1,@|
-    " words of memory out of ", mem_end+1-mem_min: 1);@/
-  wlog_ln( ' ' , cs_count: 1," multiletter control sequences out of ",
-    hash_size: 1);@/
-  wlog( ' ' , fmem_ptr: 1," words of font info for ",
-    font_ptr-font_base: 1," font");
-  if (font_ptr!=font_base+1) wlog( 's' );
-  wlog_ln(", out of ", font_mem_size: 1," for ", font_max-font_base: 1);@/
-  wlog( ' ' , hyph_count: 1," hyphenation exception");
-  if (hyph_count!=1) wlog( 's' );
-  wlog_ln(" out of ", hyph_size: 1);@/
-  wlog_ln( ' ' , max_in_stack: 1,"i,", max_nest_stack: 1,"n,",@|
-    max_param_stack: 1,"p,",@|
-    max_buf_stack+1: 1,"b,",@|
-    max_save_stack+6: 1,"s stack positions out of ",@|
-    stack_size: 1,"i,",
-    nest_size: 1,"n,",
-    param_size: 1,"p,",
-    buf_size: 1,"b,",
-    save_size: 1, 's' );
+  wlog(" %d string", str_ptr-init_str_ptr);
+  if (str_ptr!=init_str_ptr+1) wlog( "s" );
+  wlog_ln( " out of %d", max_strings-init_str_ptr);@/
+  wlog_ln( " %d string characters out of %d", pool_ptr-init_pool_ptr,
+    pool_size-init_pool_ptr);@/
+  wlog_ln(" %d words of memory out of %d", lo_mem_max-mem_min+mem_end-hi_mem_min+2,@|
+    mem_end+1-mem_min);@/
+  wlog_ln(" %d multiletter control sequences out of %d", cs_count, hash_size);@/
+  wlog(" %d words of font info for %d font", fmem_ptr, font_ptr-font_base);
+  if (font_ptr!=font_base+1) wlog("s");
+  wlog_ln( ", out of %d for %d", font_mem_size, font_max-font_base);@/
+  wlog(" %d hyphenation exception", hyph_count);
+  if (hyph_count!=1) wlog("s");
+  wlog_ln( " out of %d", hyph_size);@/
+  wlog_ln(" %di,%dn,%dp,%db,%ds stack positions out of %di,%dn,%dp,%db,%ds", 
+    max_in_stack, max_nest_stack,@|
+    max_param_stack,@|
+    max_buf_stack+1,@|
+    max_save_stack+6,@|
+    stack_size,
+    nest_size,
+    param_size,
+    buf_size,
+    save_size );
   } 
 
 @ We get to the |final_cleanup| routine when \.{\\end} or \.{\\dump} has
@@ -24452,13 +24496,13 @@
 loop{@+wake_up_terminal;
   print_nl("debug # (-1 to exit):");update_terminal;
 @.debug \#@>
-  read(term_in, m);
-  if (m < 0) return;
+  if (fscanf(term_in.f," %d",&m)<1 ||
+      m < 0) return;
   else if (m==0) 
     {@+goto breakpoint; /*go to every label at least once*/ 
     breakpoint: m=0;/*'BREAKPOINT'*/
     } 
-  else{@+read(term_in, n);
+  else{@+fscanf(term_in.f," %d",&n);
     switch (m) {
     @t\4@>@<Numbered cases for |debug_help|@>@;
     default:print_str("?");
@@ -24484,7 +24528,7 @@
 case 10: slow_print(n);@+break;
 case 11: check_mem(n > 0);@+break; /*check wellformedness; print new busy locations if |n > 0|*/ 
 case 12: search_mem(n);@+break; /*look for pointers to |n|*/ 
-case 13: {@+read(term_in, l);print_cmd_chr(n, l);
+case 13: {@+fscanf(term_in.f," %d",&l);print_cmd_chr(n, l);
   } @+break;
 case 14: for (k=0; k<=n; k++) print(buffer[k]);@+break;
 case 15: {@+font_in_short_display=null_font;short_display(n);
@@ -24619,8 +24663,8 @@
 @ @<Declare act...@>=
 @t\4@>@<Declare procedures needed in |do_extension|@>@;
 void do_extension(void)
-{@+int i, @!j, @!k; /*all-purpose integers*/ 
-pointer @!p, @!q, @!r; /*all-purpose pointers*/ 
+{@+int @!k; /*all-purpose integer*/ 
+pointer @!p; /*all-purpose pointer*/ 
 switch (cur_chr) {
 case open_node: @<Implement \.{\\openout}@>@;@+break;
 case write_node: @<Implement \.{\\write}@>@;@+break;
@@ -24957,22 +25001,6 @@
 itself will get a new section number.
 @^system dependencies@>
 
-@* Index.
-Here is where you can find all uses of each identifier in the program,
-with underlined entries pointing to where the identifier was defined.
-If the identifier is only one letter long, however, you get to see only
-the underlined entries. {\sl All references are to section numbers instead of
-page numbers.}
-
-This index also lists error messages and other aspects of the program
-that you might want to look up some day. For example, the entry
-for ``system dependencies'' lists all sections that should receive
-special attention from people who are installing \TeX\ in a new
-operating environment. A list of various things that can't happen appears
-under ``this can't happen''. Approximately 40 sections are listed under
-``inner loop''; these account for about 60\pct! of \TeX's running time,
-exclusive of input and output.
-
 @ Appendix: Replacement of the string pool file.
 @d str_0_255 	"^^@@^^A^^B^^C^^D^^E^^F^^G^^H^^I^^J^^K^^L^^M^^N^^O"@/
 	"^^P^^Q^^R^^S^^T^^U^^V^^W^^X^^Y^^Z^^[^^\\^^]^^^^^_"@/
@@ -25757,10 +25785,10 @@
 @d str_505 "else"
 @<|"else"|@>=@+505
 @ 
-@d str_506 "TeXinputs:"
+@d str_506 "TeXinputs/"
 @d TEX_area 506
 @ 
-@d str_507 "TeXfonts:"
+@d str_507 "TeXfonts/"
 @d TEX_font_area 507
 @ 
 @d str_508 ".fmt"
@@ -26827,3 +26855,19 @@
 @ @<|pool_ptr| initialization@>= str_start_668
 
 @ @<|str_ptr| initialization@>= 668
+
+@* Index.
+Here is where you can find all uses of each identifier in the program,
+with underlined entries pointing to where the identifier was defined.
+If the identifier is only one letter long, however, you get to see only
+the underlined entries. {\sl All references are to section numbers instead of
+page numbers.}
+
+This index also lists error messages and other aspects of the program
+that you might want to look up some day. For example, the entry
+for ``system dependencies'' lists all sections that should receive
+special attention from people who are installing \TeX\ in a new
+operating environment. A list of various things that can't happen appears
+under ``this can't happen''. Approximately 40 sections are listed under
+``inner loop''; these account for about 60\pct! of \TeX's running time,
+exclusive of input and output.
