402  INTRODUCTION  MFT changes for Berkeley UNIX §1

2* . uses a few features of the local Pascal compiler that may need to be changed in other installations:

1) Case statements have a default.

2) Input-output routines may need to be adapted for use with a particular character set and/or for printing messages on the user’s terminal.

These features are also present in the Pascal version of TEX, where they are used in a similar (but more complex) way. System-dependent portions of can be identified by looking at the entries for ‘system dependencies’ in the index below.

The “banner line” defined here should be changed whenever is modified.

define banner ≡ ´ ␣ ␣ ␣ ␣ ␣ ´

3* . The program begins with a fairly normal header, made up of pieces that will mostly be filled in later. The input comes from files mf file, change file, and style file; the TEX output goes to file tex file.

If it is necessary to abort the job because of a fatal error, the program calls the ‘jump out ’ procedure, which goes to the label end of MFT . ⟨ Compiler directives 4* ⟩ program MFT ;

const ⟨ Constants in the outer block 8 ⟩

type ⟨ Types in the outer block 12 ⟩

var ⟨ Globals in the outer block 9 ⟩ ⟨ Error handling procedures 29 ⟩ ⟨ scan args procedure 115* ⟩

procedure initialize; var ⟨ Local variables for initialization 14 ⟩ begin ⟨ Set initial values 10 ⟩ end;

4* . The Pascal compiler used to develop this system has “compiler directives” that can appear in comments whose first character is a dollar sign. In our case these directives tell the compiler to detect things that are out of range. ⟨ Compiler directives 4* ⟩ ≡

This code is used in section 3*.

§11  MFT changes for Berkeley UNIX  THE CHARACTER SET 403

13* . The original Pascal compiler was designed in the late 60s, when six-bit character sets were common, so it did not make provision for lowercase letters. Nowadays, of course, we need to deal with both capital and small letters in a convenient way, especially in a program for font design; so the present specification of has been written under the assumption that the Pascal compiler and run-time system permit the use of text files with more than 64 distinguishable characters. More precisely, we assume that the character set contains at least the letters and symbols associated with ASCII codes ´ 40 through ´ 176 . If additional characters are present, can be configured to work with them too.

Since we are dealing with more characters than were present in the first Pascal compilers, we have to decide what to call the associated data type. Some Pascals use the original name char for the characters in text files, even though there now are more than 64 such characters, while other Pascals consider char to be a 64-element subrange of a larger data type that has some other name.

In order to accommodate this difference, we shall use the name text char to stand for the data type of the characters that are converted to and from ASCII code when they are input and output. We shall also assume that text char consists of the elements chr (first text char ) through chr (last text char ), inclusive. The following definitions should be adjusted if necessary.

define text char ≡ ASCII code { the data type of characters in text files }

define first text char = 0 { ordinal number of the smallest element of text char }

define last text char = 255 { ordinal number of the largest element of text char } ⟨ Types in the outer block 12 ⟩ +≡

text file = packed file of text char ;

17* . The ASCII code is “standard” only to a certain extent, since many computer installations have found it advantageous to have ready access to more than 94 printing characters. If is being used on a gardenvariety Pascal for which only standard ASCII codes will appear in the input and output files, it doesn’t really matter what codes are specified in xchr [0 . . ´ 37 ], but the safest policy is to blank everything out by using the code shown below.

However, other settings of xchr will make more friendly on computers that have an extended character set, so that users can type things like ‘ ’ instead of ‘ ’, and so that can echo the page breaks found in its input. People with extended character sets can assign codes arbitrarily, giving an xchr equivalent to whatever characters the users of are allowed to have in their input files. Appropriate changes to ’s char class table should then be made. (Unlike TEX, each installation of has a fixed assignment of category codes, called the char class .) Such changes make portability of programs more difficult, so they should be introduced cautiously if at all. ⟨ Set initial values 10 ⟩ +≡

for i ← 1 to ´ 37 do xchr [i] ← chr (i);

for i ← ´ 177 to ´ 377 do xchr [i] ← chr (i);

404  INPUT AND OUTPUT  MFT changes for Berkeley UNIX §19

20* . Terminal output is done by writing on file term out , which is assumed to consist of characters of type text char :

define term out ≡ stdout define print (#) ≡ write(term out , #) { ‘print ’ means write on the terminal } define print ln(#) ≡ write ln(term out , #) { ‘print ’ and then start new line } define new line ≡ write ln(term out ) { start new line on the terminal } define print nl (#) ≡ { print information starting on a new line }

begin new line; print (#); end

21* . Different systems have different ways of specifying that the output on a certain file will appear on the user’s terminal. ⟨ Set initial values 10 ⟩ +≡

{ nothing need be done }

22* . The update terminal procedure 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.

define update terminal ≡ flush(term out ) { empty the terminal output buffer }

24* . The following code opens the input files. This is called after scan args has set the file name variables appropriately. procedure open input ; { prepare to read inputs }

begin if test read access (mf file name, MF INPUT PATH ) then reset (mf file, mf file name) else begin print pascal string (mf file name); print (´ ␣ ␣ ␣ ␣ ␣ ´ ); uexit (1);

end; reset (change file, change file name); if test read access (style file name, TEX INPUT PATH ) then reset (style file, style file name) else begin print pascal string (style file name); print (´ ␣ ␣ ␣ ␣ ´ ); uexit (1);

end; end;

26* . The following code opens tex file. The scan args procedure is used to set up tex file name as required. ⟨ Set initial values 10 ⟩ +≡

scan args ; rewrite(tex file, tex file name);

§28  MFT changes for Berkeley UNIX  INPUT AND OUTPUT 405

28* . The input ln procedure brings the next line of input from the specified file into the buffer array and returns the value true, unless the file has already been entirely read, in which case it returns false. The conventions of TEX are followed; i.e., ASCII code numbers representing the next line of the file are input into buffer [0], buffer [1], …, buffer [limit − 1]; trailing blanks are ignored; and the global variable limit is set to the length of the line. The value of limit must be strictly less than buf size. function input ln(var f : text file): boolean; { inputs a line or returns false }

var final limit : 0 . . buf size; { limit without trailing blanks } begin limit ← 0; final limit ← 0; if eof (f) then input ln ← false else begin while ¬eoln(f) do

begin buffer [limit ] ← xord [getc(f)]; incr (limit ); if buffer [limit − 1] ≠ ␣ then final limit ← limit ; if limit = buf size then

begin while ¬eoln(f) do vgetc(f);

decr (limit ); { keep buffer [buf size] empty } if final limit > limit then final limit ← limit ; print nl (´ ␣ ␣ ␣ ␣ ´ ); loc ← 0; error ; end; end;

read ln(f); limit ← final limit ; input ln ← true; end;

end;

406  REPORTING ERRORS TO THE USER  MFT changes for Berkeley UNIX §29

31* . The jump out procedure cleans up, prints appropriate messages, and exits back to the operating system.

define fatal error (#) ≡ begin new line; print (#); error ; mark fatal ; jump out ; end

⟨ Error handling procedures 29 ⟩ +≡ procedure jump out ;

begin { here files should be closed if the operating system requires it } ⟨ Print the job history 113 ⟩; new line; if (history ≠ spotless ) ∧ (history ≠ harmless message) then uexit (1) else uexit (0); end;

§34  MFT changes for Berkeley UNIX  THE MAIN PROGRAM 407

112* . The main program. Let’s put it all together now: starts and ends here.

begin initialize; { beginning of the main program } print ln(banner ); { print a “banner line” } ⟨ Store all the primitives 65 ⟩; ⟨ Store all the translations 73 ⟩; ⟨ Initialize the input system 44 ⟩; do the translation; ⟨ Check that all changes have been read 49 ⟩; ⟨ Print the job history 113 ⟩; new line; if (history ≠ spotless ) ∧ (history ≠ harmless message) then uexit (1) else uexit (0); end.

408  SYSTEM-DEPENDENT CHANGES  MFT changes for Berkeley UNIX §114

114* . System-dependent changes.

The user calls with arguments on the command line. These are either file names or flags (beginning with ‘ ’). The following globals are for communicating the user’s desires to the rest of the program. The various file name variables contain strings with the full names of those files, as UNIX knows them.

The flags that affect are and , whose statuses is kept in no change and no style, respectively. ⟨ Globals in the outer block 9 ⟩ +≡ mf file name, change file name, style file name, tex file name: packed array [1 . . FILENAMESIZE ] of

§115  MFT changes for Berkeley UNIX  SYSTEM-DEPENDENT CHANGES 409

char ; no change, no style: boolean; 115* . The scan args procedure looks at the command line arguments and sets the file name variables accordingly.

At least one file name must be present as the first argument: the file. It may have an extension, or it may omit it to get ´ ´ added. If there is only one file name, the output file name is formed by replacing

the file name extension by ´  ´ . Thus, the command line  implies the use of the
input file  and the output file  . If this style of command line, with only one argument is used,

the default style file, plain.mft , will be used to provide basic formatting.

An argument beginning with a hyphen is a flag. Any letters following the minus sign may cause global flag variables to be set. Currently, a means that there is a change file, and an means that there is a style file. The auxiliary files must of course appear in the same order as the flags. For example, the flag must be followed by the name of the style file first, and then the name of the change file. ⟨ scan args procedure 115* ⟩ ≡ procedure scan args ;

var dot pos , slash pos , i, a: integer ; { indices } which file next : char ; fname: array [1 . . FILENAMESIZE ] of char ; { temporary argument holder } found mf , found change, found style: boolean; { true when those file names have been seen }

begin { get style file path from the environment variable } set paths (MF INPUT PATH BIT + TEX INPUT PATH BIT ); found mf ← false; ⟨ Set up null change file 119* ⟩; found change ← true; { default to no change file } ⟨ Set up plain style file 120* ⟩; found style ← true; { default to plain style file } for a ← 1 to argc − 1 do

begin argv (a, fname); { put argument number a into fname }

if fname[1] ≠ ´ ´ then begin if ¬found mf then ⟨ Get mf file name from fname, and set up tex file name 116* ⟩ else if ¬found change then

begin if which file next ≠ ´ ´ then begin ⟨ Get change file name from fname 117* ⟩; which file next ← ´ ´ end

else ⟨ Get style file name from fname 118* ⟩ end

else if ¬found style then

begin if which file next = ´ ´ then begin ⟨ Get style file name from fname 118* ⟩; which file next ← ´ ´ end; end

else ⟨ Print usage error message and quit 122* ⟩; end

else ⟨ Handle flag argument in fname 121* ⟩;

end; if ¬found mf then ⟨ Print usage error message and quit 122* ⟩; end;

This code is used in section 3*.

116* . Use all of fname for the mf file name if there is a ´ ´ in it, otherwise add ´ ´ . The TEX file name comes from adding things after the dot. The argv procedure will not put more than FILENAMESIZE − 5 characters into fname, and this leaves enough room in the file name variables to add the extensions. We declared fname to be of size FILENAMESIZE instead of FILENAMESIZE − 5 because the latter implies FILENAMESIZE must be a numeric constant—and we don’t want to repeat the value from just to save five bytes of memory.

The end of a file name is marked with a ´ ␣´ , the convention assumed by the reset and rewrite procedures. ⟨ Get mf file name from fname, and set up tex file name 116* ⟩ ≡

begin dot pos ← −1; slash pos ← −1; i ← 1; while (fname[i] ≠ ´ ␣´ ) ∧ (i ≤ FILENAMESIZE − 5) do

begin mf file name[i] ← fname[i]; if fname[i] = ´ ´ then dot pos ← i; if fname[i] = ´ ´ then slash pos ← i; incr (i); end;

if (dot pos = −1)|(dot pos < slash pos ) then begin dot pos ← i; mf file name[dot pos ] ← ´ ´ ; mf file name[dot pos + 1] ← ´ ´ ; mf file name[dot pos + 2] ← ´ ´ ; mf file name[dot pos + 3] ← ´ ␣´ ; end;

for i ← 1 to dot pos do begin tex file name[i] ← mf file name[i]; end;

tex file name[dot pos + 1] ← ´ ´ ; tex file name[dot pos + 2] ← ´ ´ ; tex file name[dot pos + 3] ← ´ ´ ; tex file name[dot pos + 4] ← ´ ␣´ ; which file next ← ´ ´ ; found mf ← true; end

This code is used in section 115*.

117* . Use all of fname for the change file name if there is a ´ ´ in it, otherwise add ´ ´ . ⟨ Get change file name from fname 117* ⟩ ≡

begin dot pos ← −1; slash pos ← −1; i ← 1; while (fname[i] ≠ ´ ␣´ ) ∧ (i ≤ FILENAMESIZE − 5) do

begin change file name[i] ← fname[i]; if fname[i] = ´ ´ then dot pos ← i; if fname[i] = ´ ´ then slash pos ← i; incr (i); end;

if (dot pos = −1)|(dot pos < slash pos ) then begin dot pos ← i; change file name[dot pos ] ← ´ ´ ; change file name[dot pos + 1] ← ´ ´ ; change file name[dot pos + 2] ← ´ ´ ; change file name[dot pos + 3] ← ´ ␣´ ; end;

which file next ← ´ ´ ; found change ← true; end

This code is used in section 115*.

118* . Use all of fname for the style file name if there is a ´ ´ in it; otherwise, add ´ ´ . ⟨ Get style file name from fname 118* ⟩ ≡

begin dot pos ← −1; slash pos ← −1; i ← 1; while (fname[i] ≠ ´ ␣´ ) ∧ (i ≤ FILENAMESIZE − 5) do

begin style file name[i] ← fname[i];

if fname[i] = ´ ´ then dot pos ← i;

if fname[i] = ´ ´ then slash pos ← i;

incr (i);

end; if (dot pos = −1)|(dot pos < slash pos ) then

begin dot pos ← i; style file name[dot pos ] ← ´ ´ ; style file name[dot pos + 1] ← ´ ´ ; style file name[dot pos + 2] ← ´ ´ ; style file name[dot pos + 3] ← ´ ´ ; style file name[dot pos + 4] ← ´ ␣´ ; end;

which file next ← ´ ´ ; found style ← true; end

This code is used in sections 115* and 115*.

119* . ⟨ Set up null change file 119* ⟩ ≡

begin change file name[1] ← ´ ´ ; change file name[2] ← ´ ´ ; change file name[3] ← ´ ´ ; change file name[4] ← ´ ´ ; change file name[5] ← ´ ´ ; change file name[6] ← ´ ´ ; change file name[7] ← ´ ´ ; change file name[8] ← ´ ´ ; change file name[9] ← ´ ´ ; change file name[10] ← ´ ␣´ ; end

This code is used in section 115*.

120* . ⟨ Set up plain style file 120* ⟩ ≡

begin style file name[1] ← ´ ´ ; style file name[2] ← ´ ´ ; style file name[3] ← ´ ´ ; style file name[4] ← ´ ´ ; style file name[5] ← ´ ´ ; style file name[6] ← ´ ´ ; style file name[7] ← ´ ´ ; style file name[8] ← ´ ´ ; style file name[9] ← ´ ´ ; style file name[10] ← ´ ␣´ ; end

This code is used in section 115*.

121* . ⟨ Handle flag argument in fname 121* ⟩ ≡

begin i ← 2; while (fname[i] ≠ ´ ␣´ ) ∧ (i ≤ FILENAMESIZE − 5) do

begin if fname[i] = ´ ´ then begin found change ← false; if which file next ≠ ´ ´ then which file next ← ´ ´ end

else if fname[i] = ´ ´ then begin found style ← false; if which file next ≠ ´ ´ then which file next ← ´ ´ end

else print nl (´ ␣ ␣´ , xchr [xord [fname[i]]], ´ ´ ); incr (i); end;

end

This code is used in section 115*.

122* . ⟨ Print usage error message and quit 122* ⟩ ≡

begin print ln(´ ␣ ␣ ␣ ␣ ␣ ´ ); uexit (1); end

This code is used in sections 115* and 115*.

§123  MFT changes for Berkeley UNIX  INDEX 413

123* . Index.

The following sections were changed by the change file: 2, 3, 4, 13, 17, 20, 21, 22, 24, 26, 28, 31, 112, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123.

: 98. : 106, 107. : 101. : 100. : 106. : 101. : 73. : 105. : 88. : 108, 110. : 100. : 100. : 100. : 100. : 100. : 100. : 99. : 100. : 108. : 98. abinary : \underline{63}, 70, 98, 101. ampersand : \underline{63}, 70, 98, 102. argc: 115* . argv : 115* , 116* . as is : \underline{63}, 65, 66, 70, 101. ASCII code: 11. ASCII code: \underline{12}, 13* , 15, 27, 28* , 36, 51, 72, 78,

80, 86, 91, 95. b: \underline{87}. backslash: \underline{63}, 65, 102. banner : \underline{2*} , 112* . bbinary : \underline{63}, 65, 98, 100. binary : \underline{63}, 66, 70, 98, 100. bold : \underline{63}, 66, 71, 100. boolean: 28* , 34, 37, 77, 87, 114* , 115* . break out : 89, 90, \underline{91}. buf size: \underline{8}, 27, 28* , 29, 34, 36, 37, 38, 42, 55,

58, 96, 97. buffer : \underline{27}, 28* , 29, 30, 37, 39, 41, 42, 43, 44, 46,

48, 49, 55, 58, 59, 61, 62, 64, 79, 80, 81, 82, 85, 96, 104, 105, 108.

byte mem: 50, \underline{51}, 52, 53, 58, 61, 62, 72, 93,

94, 106, 107. byte ptr : 52, \underline{53}, 54, 62, 72. byte start : 50, \underline{51}, 52, 53, 54, 55, 61, 62, 72,

93, 94, 106, 107. c: \underline{80}. carriage return: \underline{79}, 85, 104, 108. : 40, 42, 48.

: 49. change buffer : \underline{36}, 37, 38, 41, 42, 46, 49. change changing : \underline{35}, 42, 44, 48. change file: 3* , \underline{23}, 24* , 30, 34, 36, 39, 40, 42,

48, 115* . change file name: 24* , \underline{114*} , 117* , 119* . change limit : \underline{36}, 37, 38, 41, 42, 46, 49. changing : 30, \underline{34}, 35, 36, 38, 42, 44, 45, 49. char : 13* , 114* , 115* . char class : 17* , \underline{78}, 79, 80, 81, 105, 107. character set dependencies: 17* , 79. check change: \underline{42}, 46. chr : 13* , 15, 17* , 18. class : \underline{80}, 81. colon: \underline{63}, 65, 100. command : \underline{63}, 65, 66, 70, 71, 100. comment : \underline{63}, 71, 97, 108. confusion: \underline{32}. continue: \underline{5}, 38, 39. copy : \underline{96}, 99, 105, 107, 108, 109. cur tok : 64, 72, 73, \underline{75}, 76, 80, 81, 99, 100, 101,

102, 103, 105, 106, 107, 111. cur type: \underline{75}, 76, 80, 81, 97, 98, 101, 106, 107,

414  INDEX  MFT changes for Berkeley UNIX §123

108, 110, 111. d: \underline{91}. decr : \underline{6}, 28* , 87, 91. digit class : \underline{78}, 79, 81, 105. do nothing : \underline{6}, 81, 98. do the translation: \underline{97}, 112* . done: \underline{5}, 38, 39, 80, 81, 87, 97, 107. dot pos : \underline{115*} , 116* , 117* , 118* . double back : \underline{63}, 65, 101. eight bits : \underline{50}, 75, 87. else: 7. emit : \underline{81}, 82, 85. empty buffer : \underline{77}, 80, 85, 97, 111. end: 7. end line class : \underline{78}, 79, 81. end of file: \underline{63}, 85, 97. end of line: \underline{63}, 76, 81, 97, 98, 101, 110, 111. end of MFT : 3* . endcases: \underline{7}. endit : \underline{63}, 65, 66, 71, 98, 100, 101. eof : 28* . eoln: 28* . err print : \underline{29}, 35, 39, 40, 42, 43, 48, 49, 83, 84, 111. error : 28* , \underline{29}, 31* . error message: \underline{9}, 113. exit : \underline{5}, 6, 37, 38, 42, 80, 91, 97. f: \underline{28*} . false: 28* , 35, 36, 37, 42, 44, 47, 85, 87, 88, 91,

97, 98, 111, 115* , 121* . fatal error : \underline{31*} , 32, 33. fatal message: \underline{9}, 113. file name: 114* , 115* , 116* . FILENAMESIZE : 114* , 115* , 116* , 117* , 118* , 121* . final limit : \underline{28*} . first loc: \underline{96}. first text char : \underline{13*} , 18. flush: 22* . flush buffer : \underline{87}, 88, 91, 92, 97. fname: \underline{115*} , 116* , 117* , 118* , 121* . found : \underline{5}, 58, 60, 61, 80, 81. found change: \underline{115*} , 117* , 121* . found mf : \underline{115*} , 116* . found style: 115* , 118* , 121* . get line: 34, \underline{45}, 85. get next : 75, 77, \underline{80}, 97, 101, 104, 105, 106,

107, 111. getc: 28* . greater or equal : \underline{63}, 70, 102. h: \underline{56}, \underline{58}. harmless message: \underline{9}, 31* , 112* , 113. hash: 52, \underline{55}, 57, 60. hash size: \underline{8}, 55, 56, 57, 58, 59. history : \underline{9}, 10, 31* , 112* , 113. : 43. i: \underline{14}, \underline{58}, \underline{72}. id first : \underline{55}, 58, 59, 61, 62, 64, 80, 81, 108, 109. id loc: \underline{55}, 58, 59, 61, 62, 65, 80. ilk : 50, \underline{51}, 63, 64, 80, 111. : 83. incr : \underline{6}, 28* , 39, 40, 42, 46, 47, 48, 59, 61, 62, 72,

80, 81, 82, 87, 89, 104, 108, 116* , 117* , 118* , 121* . indentation: \underline{63}, 81, 97. initialize: \underline{3*} , 112* . : 28* . input command : \underline{63}, 66, 103. input has ended : \underline{34}, 42, 44, 46, 85. input ln: \underline{28*} , 39, 40, 42, 46, 47, 48. integer : 34, 42, 75, 86, 96, 97, 115* . internal : \underline{63}, 68, 69, 97, 106. : 84. invalid class : \underline{78}, 79, 81. isolated classes : \underline{78}, 81. j: \underline{87}. jump out : 3* , \underline{31*} . k: \underline{29}, \underline{37}, \underline{38}, \underline{42}, \underline{58}, \underline{87}, \underline{91}, \underline{93}, \underline{94}, \underline{96}, \underline{97}. Knuth, Donald Ervin: 1. l: \underline{29}, \underline{58}. last text char : \underline{13*} , 18. left bracket class : \underline{78}, 79. length: \underline{52}, 60, 95, 106. less or equal : \underline{63}, 70, 102. letter class : \underline{78}, 79. limit : 28* , 30, \underline{34}, 37, 39, 40, 41, 43, 44, 45, 46, 48,

49, 79, 82, 85, 104, 108, 109, 110. line: 30, \underline{34}, 35, 39, 40, 42, 44, 46, 47, 48, 49. : 92. line length: \underline{8}, 86, 87, 89, 91. lines dont match: \underline{37}, 42. link : 50, \underline{51}, 52, 60. loc: 28* , 30, \underline{34}, 39, 43, 44, 45, 48, 49, 80, 81, 82,

85, 96, 104, 105, 108, 109, 110. lookup: 55, \underline{58}, 64, 80. loop: \underline{6}. mark error : \underline{9}, 29. mark fatal : \underline{9}, 31* . mark harmless : \underline{9}, 92. max bytes : \underline{8}, 51, 53, 58, 62, 93, 94. max class : \underline{78}. max names : \underline{8}, 51, 52, 62. : 42. mf file: 3* , \underline{23}, 24* , 30, 34, 36, 42, 46, 49. mf file name: 24* , \underline{114*} , 116* . MF INPUT PATH : 24* . MF INPUT PATH BIT : 115* . mft : 115* . MFT : \underline{3*} . mft comment : \underline{63}, 71, 97, 98, 111. : 1, 88. min action type: \underline{63}, 98. min suffix : \underline{63}, 106, 107. min symbolic token: \underline{63}, 111. n: \underline{42}, \underline{95}. name pointer : \underline{52}, 53, 58, 72, 74, 93, 94, 95. name ptr : 52, \underline{53}, 54, 58, 60, 62, 72. new line: \underline{20*} , 29, 30, 31* , 92, 112* . nil: 6. no change: \underline{114*} . no style: \underline{114*} . not equal : \underline{63}, 70, 102. not found : \underline{5}. numeric token: \underline{63}, 81, 97, 106, 107. : 111. oot : \underline{89}. oot1 : \underline{89}. oot2 : \underline{89}. oot3 : \underline{89}. oot4 : \underline{89}. oot5 : \underline{89}. op: \underline{63}, 65, 67, 100. open input : \underline{24*} , 44. ord : 15. other line: \underline{34}, 35, 44, 49. othercases: \underline{7}. others : 7. out : \underline{89}, 93, 94, 95, 96, 98, 104, 105, 106,

107, 108, 110. out buf : \underline{86}, 87, 88, 89, 90, 91, 92, 108, 109. out line: \underline{86}, 87, 88, 92. out mac and name: \underline{95}, 100, 103, 106. out name: \underline{94}, 95, 101, 106, 107. out ptr : \underline{86}, 87, 88, 89, 91, 92, 97, 108, 109. out str : \underline{93}, 94, 97, 98, 102, 106. out2 : \underline{89}, 98, 99, 101, 105, 106, 107, 108. out3 : \underline{89}. out4 : \underline{89}, 108, 110. out5 : \underline{89}, 103, 104, 105. overflow : \underline{33}, 62. p: \underline{58}, \underline{93}, \underline{94}, \underline{95}. pass digits : \underline{80}, 81. pass fraction: \underline{80}, 81. path join: \underline{63}, 65, 100. per cent : \underline{87}. percent class : \underline{78}, 79. period class : \underline{78}, 79, 81. plain: 115* . prev tok : \underline{75}, 80, 106, 107. prev type: \underline{75}, 80, 100, 106, 107. prime the change buffer : \underline{38}, 44, 48. print : \underline{20*} , 24* , 29, 30, 31* , 92. print ln: \underline{20*} , 30, 92, 112* , 122* . print nl : \underline{20*} , 28* , 92, 113, 121* . print pascal string : 24* . pr1 : \underline{64}, 65, 70, 71. pr10 : \underline{64}, 65, 66, 67, 69, 70, 71. pr11 : \underline{64}, 65, 66, 67, 68, 69, 70, 71. pr12 : \underline{64}, 66, 68, 69, 71. pr13 : \underline{64}, 67, 68, 70, 71. pr14 : \underline{64}, 67, 68. pr15 : \underline{64}, 68. pr16 : \underline{64}, 68, 71. pr17 : \underline{64}, 70. pr2 : \underline{64}, 65, 66, 70, 71. pr3 : \underline{64}, 65, 66, 67, 69, 70, 71. pr4 : \underline{64}, 65, 66, 67, 69, 70, 71. pr5 : \underline{64}, 65, 66, 67, 69, 70, 71. pr6 : \underline{64}, 65, 66, 67, 69, 70. pr7 : \underline{64}, 65, 66, 67, 69, 70, 71. pr8 : \underline{64}, 65, 66, 67, 69, 71. pr9 : \underline{64}, 66, 69, 70, 71. pyth sub: \underline{63}, 70, 98, 102. read ln: 28* . recomment : \underline{63}, 97, 110. reset : 24* , 116* . restart : \underline{5}, 45, 97, 98, 108, 109, 110, 111. reswitch: \underline{5}, 97, 101, 106, 107, 110, 111. return: 5, \underline{6}. rewrite: 26* , 116* . right bracket class : \underline{78}, 79. right paren class : \underline{78}, 79. scan args : 24* , 26* , \underline{115*} . semicolon: \underline{63}, 65, 101. set format : \underline{63}, 71, 97. set paths : 115* . sharp: \underline{63}, 71, 101, 106. sixteen bits : \underline{50}, 51, 55. slash pos : \underline{115*} , 116* , 117* , 118* . : 33. space class : \underline{78}, 79, 81. special tag : \underline{63}, 66, 97, 106, 107. spotless : \underline{9}, 10, 31* , 112* , 113. spr1 : \underline{64}. spr10 : \underline{64}. spr11 : \underline{64}. spr12 : \underline{64}. spr13 : \underline{64}. spr14 : \underline{64}. spr15 : \underline{64}. spr16 : \underline{64}. spr17 : \underline{64}. spr2 : \underline{64}. spr3 : \underline{64}. spr4 : \underline{64}. spr5 : \underline{64}. spr6 : \underline{64}. spr7 : \underline{64}. spr8 : \underline{64}. spr9 : \underline{64}. start of line: \underline{77}, 81, 85, 97, 98, 108, 111. stdout : 20* . string class : \underline{78}, 79, 81. string token: \underline{63}, 82, 97. style file: 3* , \underline{23}, 24* , 30, 34, 47, 115* . style file name: 24* , \underline{114*} , 118* , 120* . styling : 30, \underline{34}, 44, 45, 47. switch: \underline{80}, 81, 83, 84. system dependencies: \underline{2*} , 3* , 4* , 7, 13* , 16, 17* , 20* , 21* ,

22* , 24* , 26* , 28* , 30, 79, 112* , 113. t: \underline{94}, \underline{97}. tag : \underline{63}, 97, 106. temp line: \underline{34}, 35. term out : \underline{20*} , 22* . test read access : 24* . tex file: 3* , \underline{25}, 26* , 87, 88. tex file name: 26* , \underline{114*} , 116* .

TEX INPUT PATH : 24* . TEX INPUT PATH BIT : 115* . text char : \underline{13*} , 15, 20* . text file: \underline{13*} , 23, 25, 28* . : 32. tr amp: 73, \underline{74}, 102. tr ge: 73, \underline{74}, 102. tr le: 73, \underline{74}, 102. tr ne: 73, \underline{74}, 102. tr ps : 73, \underline{74}, 102. tr quad : 73, \underline{74}, 97. tr sharp: 73, \underline{74}, 106. tr skip: 73, \underline{74}, 98. translation: \underline{72}, 73, 94, 102. true: 6, 28* , 34, 35, 37, 42, 44, 46, 49, 77, 85, 87,

91, 92, 97, 108, 111, 115* , 116* , 117* , 118* . tr1 : \underline{72}. tr2 : \underline{72}, 73. tr3 : \underline{72}. tr4 : \underline{72}, 73. tr5 : \underline{72}, 73. ttr1 : \underline{72}. ttr2 : \underline{72}. ttr3 : \underline{72}. ttr4 : \underline{72}. ttr5 : \underline{72}. type name: \underline{63}, 70, 100. uexit : 24* , 31* , 112* , 122* . update terminal : \underline{22*} , 29. user manual: 1. verbatim: \underline{63}, 71, 97. vgetc: 28* . : 39, 43, 48. which file next : \underline{115*} , 116* , 117* , 118* , 121* . write: 20* , 87, 88. write ln: 20* , 87. xchr : \underline{15}, 16, 17* , 18, 30, 87, 92, 121* . xclause: 6. xord : \underline{15}, 18, 28* , 121* .

§123  MFT changes for Berkeley UNIX  NAMES OF THE SECTIONS 417

⟨ Assign the default value to ilk [p] 63 ⟩ Used in section 62. ⟨ Branch on the class , scan the token; return directly if the token is special, or goto found if it needs to

be looked up 81 ⟩ Used in section 80.

⟨ Bring in a new line of input; return if the file has ended 85 ⟩ Used in section 80. ⟨ Cases that translate primitive tokens 100, 101, 102, 103 ⟩ Used in section 97. ⟨ Change the translation format of tokens, and goto restart or reswitch 111 ⟩ Used in section 97. ⟨ Check that all changes have been read 49 ⟩ Used in section 112*. ⟨ Compare name p with current token, goto found if equal 61 ⟩ Used in section 60. ⟨ Compiler directives 4* ⟩ Used in section 3*. ⟨ Compute the hash code h 59 ⟩ Used in section 58. ⟨ Compute the name location p 60 ⟩ Used in section 58. ⟨ Constants in the outer block 8 ⟩ Used in section 3*. ⟨ Copy the rest of the current input line to the output, then goto restart 109 ⟩ Used in section 97. ⟨ Decry the invalid character and goto switch 84 ⟩ Used in section 81. ⟨ Decry the missing string delimiter and goto switch 83 ⟩ Used in section 82. ⟨ Do special actions at the start of a line 98 ⟩ Used in section 97. ⟨ Enter a new name into the table at position p 62 ⟩ Used in section 58. ⟨ Error handling procedures 29, 31* ⟩ Used in section 3*. ⟨ Get a string token and return 82 ⟩ Used in section 81.

⟨ Get change file name from fname 117* ⟩ Used in section 115*. ⟨ Get mf file name from fname, and set up tex file name 116* ⟩ Used in section 115*. ⟨ Get style file name from fname 118* ⟩ Used in sections 115* and 115*. ⟨ Globals in the outer block 9, 15, 23, 25, 27, 34, 36, 51, 53, 55, 72, 74, 75, 77, 78, 86, 114* ⟩ Used in section 3*. ⟨ Handle flag argument in fname 121* ⟩ Used in section 115*.

⟨ If the current line starts with , report any discrepancies and return 43 ⟩ Used in section 42. ⟨ Initialize the input system 44 ⟩ Used in section 112*. ⟨ Local variables for initialization 14, 56 ⟩ Used in section 3*.

⟨ Move buffer and limit to change buffer and change limit 41 ⟩ Used in sections 38 and 42.

⟨ Print error location based on input buffer 30 ⟩ Used in section 29.

⟨ Print the job history 113 ⟩ Used in sections 31* and 112*.

⟨ Print usage error message and quit 122* ⟩ Used in sections 115* and 115*. ⟨ Print warning message, break the line, return 92 ⟩ Used in section 91. ⟨ Read from change file and maybe turn off changing 48 ⟩ Used in section 45. ⟨ Read from mf file and maybe turn on changing 46 ⟩ Used in section 45. ⟨ Read from style file and maybe turn off styling 47 ⟩ Used in section 45. ⟨ Scan the file name and output it in 104 ⟩ Used in section 103.

⟨ Set initial values 10, 16, 17*, 18, 21*, 26*, 54, 57, 76, 79, 88, 90 ⟩ Used in section 3*. ⟨ Set up null change file 119* ⟩ Used in section 115*. ⟨ Set up plain style file 120* ⟩ Used in section 115*.

⟨ Skip over comment lines in the change file; return if end of file 39 ⟩ Used in section 38. ⟨ Skip to the next nonblank line; return if end of file 40 ⟩ Used in section 38.

⟨ Store all the primitives 65, 66, 67, 68, 69, 70, 71 ⟩ Used in section 112*.

⟨ Store all the translations 73 ⟩ Used in section 112*. ⟨ Translate a comment and goto restart , unless there’s a … segment 108 ⟩ Used in section 97. ⟨ Translate a numeric token or a fraction 105 ⟩ Used in section 97. ⟨ Translate a string token 99 ⟩ Used in section 97. ⟨ Translate a subscript 107 ⟩ Used in section 106. ⟨ Translate a tag and possible subscript 106 ⟩ Used in section 97.

⟨ Types in the outer block 12, 13*, 50, 52 ⟩ Used in section 3*.

⟨ Wind up a line of translation and goto restart , or finish a … segment and goto reswitch 110 ⟩

Used in section 97. ⟨ scan args procedure 115* ⟩ Used in section 3*.

The MFT processor

(Version 2.0, October 1989)

Section Page

Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 402 The character set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 403 Input and output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 404 Reporting errors to the user . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 406 Inserting the changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 407 Data structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 407 Initializing the primitive tokens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 407 Inputting the next token . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 407 Low-level output routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 407 Translation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 407 The main program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 407 System-dependent changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 408 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 413

The preparation of this report was supported in part by the National Science Foundation under grants IST-8201926, MCS-8300984, and CCR-8610181, and by the System Development Foundation. ‘TEX’ is a trademark of the American Mathematical Society. ‘ ’ is a trademark of Addison-Wesley Publishing Company.