summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/mp.ch
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/mp.ch')
-rw-r--r--Build/source/texk/web2c/mp.ch2100
1 files changed, 0 insertions, 2100 deletions
diff --git a/Build/source/texk/web2c/mp.ch b/Build/source/texk/web2c/mp.ch
deleted file mode 100644
index 0d914ee9a4f..00000000000
--- a/Build/source/texk/web2c/mp.ch
+++ /dev/null
@@ -1,2100 +0,0 @@
-% $Id: mp.ch,v 1.8 2005/03/18 19:49:05 taco Exp $
-% mp.ch for C compilation with web2c. Public domain.
-%
-% Derived from mf.ch and John Hobby's mp.ch (the change file for the C
-% version of mf).
-%
-% Numbers of the form [pp.nnn] refer to the corresponding part and
-% module number of mp.web as implementors who read this change file are
-% much better advised to use a current WEB listing of MetaPost.
-%
-% (more recent changes in ChangeLog)
-% Revision 0.62 Jan 4 '95 by John Hobby
-% (Changes that only affect the banner line are not listed here)
-%
-% Updated for web2c-6.1/kpathsea-2.6 Jan 29 '95 by Ulrik Vieth
-% according to the current version of mf.ch.
-%
-% - produce separate binaries for INIMP, VIRMF (no '-I' flag!)
-% - make a big version of MP by default (cf. TeX and METAFONT)
-% - allow any input characters (0..255) (cf. TeX and METAFONT)
-% - use web2c/kpathsea routines in file opening and searching
-%
-% Updated for Revision 0.63 Apr 12 '95 by Ulrik Vieth
-%
-% - fixed the parsing routines for ps_tab_file to be able to handle
-% comments and blank lines in dvipsk's version of psfonts.map.
-% - increased max_read_files to 30 to avoid running out of read files
-% when reading stops before reaching EOF. (Better solution: write
-% a 'closefrom' macro that reads to EOF, which causes file closing.)
-
-@x [0] WEAVE: print changes only.
-\def\botofcontents{\vskip 0pt plus 1fil minus 1.5in}
-@y
-\def\botofcontents{\vskip 0pt plus 1fil minus 1.5in}
-\let\maybe=\iffalse
-\def\title{\MP\ changes for C}
-\def\glob{13}\def\gglob{20, 25} % these are defined in module 1
-\font\mc=cmr9
-@z
-
-@x [1.7] Convert `debug..gubed' and `stat..tats' into #ifdefs.
-@d debug==@{ {change this to `$\\{debug}\equiv\null$' when debugging}
-@d gubed==@t@>@} {change this to `$\\{gubed}\equiv\null$' when debugging}
-@y
-@d debug==ifdef('TEXMF_DEBUG')
-@d gubed==endif('TEXMF_DEBUG')
-@z
-
-@x
-@d stat==@{ {change this to `$\\{stat}\equiv\null$' when gathering
- usage statistics}
-@d tats==@t@>@} {change this to `$\\{tats}\equiv\null$' when gathering
- usage statistics}
-@y
-@d stat==ifdef('STAT')
-@d tats==endif('STAT')
-@z
-
-@x [1.8] Same, for `init..tini'.
-@d init== {change this to `$\\{init}\equiv\.{@@\{}$' in the production version}
-@d tini== {change this to `$\\{tini}\equiv\.{@@\}}$' in the production version}
-@y
-@d init==ifdef('INIMP')
-@d tini==endif('INIMP')
-@z
-
-% [1.11] Compile-time constants. Although we only change a few of
-% these, listing them all makes the patch file for a big MetaPost simpler.
-% 16K for BSD I/O; file_name_size is set from the system constant.
-@x
-@<Constants...@>=
-@!mem_max=30000; {greatest index in \MP's internal |mem| array;
- must be strictly less than |max_halfword|;
- must be equal to |mem_top| in \.{INIMP}, otherwise |>=mem_top|}
-@!max_internal=100; {maximum number of internal quantities}
-@!buf_size=500; {maximum number of characters simultaneously present in
- current lines of open files; must not exceed |max_halfword|}
-@!error_line=72; {width of context lines on terminal error messages}
-@!half_error_line=42; {width of first lines of contexts in terminal
- error messages; should be between 30 and |error_line-15|}
-@!max_print_line=79; {width of longest text lines output; should be at least 60}
-@!emergency_line_length=255;
- {\ps\ output lines can be this long in unusual circumstances}
-@!stack_size=30; {maximum number of simultaneous input sources}
-@!max_read_files=4; {maximum number of simultaneously open \&{readfrom} files}
-@!max_strings=2500; {maximum number of strings; must not exceed |max_halfword|}
-@!string_vacancies=9000; {the minimum number of characters that should be
- available for the user's identifier names and strings,
- after \MP's own error messages are stored}
-@!strings_vacant=1000; {the minimum number of strings that should be available}
-@!pool_size=32000; {maximum number of characters in strings, including all
- error messages and help texts, and the names of all identifiers;
- must exceed |string_vacancies| by the total
- length of \MP's own strings, which is currently about 22000}
-@!font_max=50; {maximum font number for included text fonts}
-@!font_mem_size=10000; {number of words for \.{TFM} information for text fonts}
-@!file_name_size=40; {file names shouldn't be longer than this}
-@!pool_name='MPlib:MP.POOL ';
- {string of length |file_name_size|; tells where the string pool appears}
-@.MPlib@>
-@!ps_tab_name='MPlib:PSFONTS.MAP ';
- {string of length |file_name_size|; locates font name translation table}
-@!path_size=300; {maximum number of knots between breakpoints of a path}
-@!bistack_size=785; {size of stack for bisection algorithms;
- should probably be left at this value}
-@!header_size=100; {maximum number of \.{TFM} header words, times~4}
-@!lig_table_size=5000; {maximum number of ligature/kern steps, must be
- at least 255 and at most 32510}
-@!max_kerns=500; {maximum number of distinct kern amounts}
-@!max_font_dimen=50; {maximum number of \&{fontdimen} parameters}
-@y
-@d file_name_size == maxint
-@d ssup_error_line = 255
-@d ssup_max_strings = 32767 {max value allowed by \.{TANGLE}}
-
-@<Constants...@>=
-@!max_internal=300; {maximum number of internal quantities}
-@!emergency_line_length=255;
- {\ps\ output lines can be this long in unusual circumstances}
-@!stack_size=300; {maximum number of simultaneous input sources}
-@!max_read_files=30; {maximum number of simultaneously open \&{readfrom} files}
-@!strings_vacant=1000; {the minimum number of strings that should be available}
-@!font_max=50; {maximum font number for included text fonts}
-@!font_mem_size=10000; {number of words for \.{TFM} information for text fonts}
-@!pool_name=TEXMF_POOL_NAME;
- {string of length |file_name_size|; tells where the string pool appears}
-@!engine_name=TEXMF_ENGINE_NAME; {the name of this engine}
-@.MPlib@>
-@!ps_tab_name='psfonts.map';
- {string of length |file_name_size|; locates font name translation table}
-@!bistack_size=1500; {size of stack for bisection algorithms;
- should probably be left at this value}
-@!header_size=100; {maximum number of \.{TFM} header words, times~4}
-@!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}
-@#
-@!inf_main_memory = 3000;
-@!sup_main_memory = 8000000;
-
-@!inf_max_strings = 2500;
-@!sup_max_strings = ssup_max_strings;
-
-@!inf_buf_size = 500;
-@!sup_buf_size = 300000;
-
-@!inf_path_size = 1000;
-@!sup_path_size = 300000;
-
-@!inf_pool_size = 32000;
-@!sup_pool_size = 10000000;
-@!inf_pool_free = 1000;
-@!sup_pool_free = sup_pool_size;
-@!inf_string_vacancies = 8000;
-@!sup_string_vacancies = sup_pool_size - 23000;
-@z
-
-@x [1.12] Constants defined as WEB macros.
-@d mem_min=0 {smallest index in the |mem| array, must not be less
- than |min_halfword|}
-@d mem_top==30000 {largest index in the |mem| array dumped by \.{INIMP};
- must be substantially larger than |mem_min|
- and not greater than |mem_max|}
-@d hash_size=2100 {maximum number of symbolic tokens,
- must be less than |max_halfword-3*param_size|}
-@d hash_prime=1777 {a prime number equal to about 85\pct! of |hash_size|}
-@d max_in_open=6 {maximum number of input files and error insertions that
- can be going on simultaneously}
-@d param_size=150 {maximum number of simultaneous macro parameters}
-@d max_write_files=4 {maximum number of simultaneously open \&{write} files}
-@y
-@d mem_min=0 {smallest index in the |mem| array, must not be less
- than |min_halfword|}
-@d hash_size=9500 {maximum number of symbolic tokens,
- must be less than |max_halfword-3*param_size|}
-@d hash_prime=7919 {a prime number equal to about 85\pct! of |hash_size|}
-@d max_in_open=25 {maximum number of input files and error insertions that
- can be going on simultaneously}
-@d param_size=1500 {maximum number of simultaneous macro parameters}
-@d max_write_files=10 {maximum number of simultaneously open \&{write} files}
-@z
-
-@x [1.13] Global parameters that can be changed in texmf.cnf.
-@<Glob...@>=
-@!bad:integer; {is some ``constant'' wrong?}
-@y
-@<Glob...@>=
-@!bad:integer; {is some ``constant'' wrong?}
-@#
-@!init
-@!ini_version:boolean; {are we \.{INIMP}? Set in \.{lib/texmfmp.c}}
-@!dump_option:boolean; {was the dump name option used?}
-@!dump_line:boolean; {was a \.{\%\AM mem} line seen?}
-tini@/
-@#
-@!bound_default:integer; {temporary for setup}
-@!bound_name:^char; {temporary for setup}
-@#
-@!main_memory:integer; {total memory words allocated in initex}
-@!mem_top:integer; {largest index in the |mem| array dumped by \.{INIMP};
- must be substantially larger than |mem_min|
- and not greater than |mem_max|}
-@!extra_mem_top:integer; {|mem_max:=mem_top+extra_mem_top| except in \.{INIMP}}
-@!mem_max:integer; {greatest index in \MP's internal |mem| array;
- must be strictly less than |max_halfword|;
- must be equal to |mem_top| in \.{INIMP}, otherwise |>=mem_top|}
-@!error_line:integer; {width of context lines on terminal error messages}
-@!half_error_line:integer; {width of first lines of contexts in terminal
- error messages; should be between 30 and |error_line-15|}
-@!max_print_line:integer; {width of longest text lines output;
- should be at least 60}
-@!pool_size:integer; {maximum number of characters in strings, including all
- error messages and help texts, and the names of all identifiers;
- must exceed |string_vacancies| by the total
- length of \MP's own strings, which is currently about 22000}
-@!string_vacancies:integer; {the minimum number of characters that should be
- available for the user's identifier names and strings,
- after \MP's own error messages are stored}
-@!buf_size:integer; {maximum number of characters simultaneously present in
- current lines of open files and in control sequences between
- \.{\\csname} and \.{\\endcsname}; must not exceed |max_halfword|}
-@!path_size:integer; {maximum number of knots between breakpoints of a path}
-@!pool_free:integer;{minimum pool space free after format loaded}
-@!max_strings:integer; {maximum number of strings; must not exceed |max_halfword|}
-@!parse_first_line_p:c_int_type; {parse the first line for options}
-@!file_line_error_style_p:c_int_type; {file:line:error style messages.}
-@!eight_bit_p:c_int_type; {make all characters printable by default}
-@!halt_on_error_p:c_int_type; {stop at first error}
-@!quoted_filename:boolean; {current filename is quoted}
-@z
-
-@x [1.16] Use C macros for `incr' and `decr'.
-@d incr(#) == #:=#+1 {increase a variable by unity}
-@d decr(#) == #:=#-1 {decrease a variable by unity}
-@y
-@z
-
-% [2.19] The text_char type is used as an array index into xord. The
-% default type `char' produces signed integers, which are bad array
-% indices in C.
-@x
-@d text_char == char {the data type of characters in text files}
-@y
-@d text_char == ASCII_code {the data type of characters in text files}
-@z
-
-@x [2.22] Allow any character as input.
-@^character set dependencies@>
-@^system dependencies@>
-
-@<Set init...@>=
-for i:=0 to @'37 do xchr[i]:=' ';
-for i:=@'177 to @'377 do xchr[i]:=' ';
-@y
-@^character set dependencies@>
-@^system dependencies@>
-
-@d tab = @'11 { ASCII horizontal tab }
-@d form_feed = @'14 { ASCII form feed }
-
-@<Set init...@>=
-{Initialize |xchr| to the identity mapping.}
-for i:=0 to @'37 do xchr[i]:=i;
-for i:=@'177 to @'377 do xchr[i]:=i;
-@z
-
-@x [2.23]
-for i:=0 to @'176 do xord[xchr[i]]:=i;
-@y
-for i:=0 to @'176 do xord[xchr[i]]:=i;
-{Set |xprn| for printable ASCII, unless |eight_bit_p| is set.}
-for i:=0 to 255 do xprn[i]:=(eight_bit_p or ((i>=" ")and(i<="~")));
-
-{The idea for this dynamic translation comes from the patch by
- Libor Skarvada \.{<libor@@informatics.muni.cz>}
- and Petr Sojka \.{<sojka@@informatics.muni.cz>}. I didn't use any of the
- actual code, though, preferring a more general approach.}
-
-{This sets the |xchr|, |xord|, and |xprn| arrays. We overwrite the
- |xchr| assignments from module 21, just in case someone wants to do strange
- character translations. See the function definition in \.{texmfmp.c} for
- more comments.}
-if translate_filename then read_tcx_file;
-@z
-
-% [3.25] Declare name_of_file as a C string. See comments in tex.ch for
-% why we change the element type to text_char.
-@x
-@!name_of_file:packed array[1..file_name_size] of char;@;@/
- {on some systems this may be a \&{record} variable}
-@y
-@!name_of_file:^text_char;
-@z
-
-@x [3.26] Do file opening in C.
-@ The \ph\ compiler with which the original version of \MF\ was prepared
-extends the rules of \PASCAL\ in a very convenient way. To open file~|f|,
-we can write
-$$\vbox{\halign{#\hfil\qquad&#\hfil\cr
-|reset(f,@t\\{name}@>,'/O')|&for input;\cr
-|rewrite(f,@t\\{name}@>,'/O')|&for output.\cr}}$$
-The `\\{name}' parameter, which is of type `\ignorespaces|packed
-array[@t\<\\{any}>@>] of text_char|', stands for the name of
-the external file that is being opened for input or output.
-Blank spaces that might appear in \\{name} are ignored.
-
-The `\.{/O}' parameter tells the operating system not to issue its own
-error messages if something goes wrong. If a file of the specified name
-cannot be found, or if such a file cannot be opened for some other reason
-(e.g., someone may already be trying to write the same file), we will have
-|@!erstat(f)<>0| after an unsuccessful |reset| or |rewrite|. This allows
-\MP\ to undertake appropriate corrective action.
-@:PASCAL H}{\ph@>
-@^system dependencies@>
-
-\MP's file-opening procedures return |false| if no file identified by
-|name_of_file| could be opened.
-
-@d reset_OK(#)==erstat(#)=0
-@d rewrite_OK(#)==erstat(#)=0
-
-@p function a_open_in(var @!f:alpha_file):boolean;
- {open a text file for input}
-begin reset(f,name_of_file,'/O'); a_open_in:=reset_OK(f);
-end;
-@#
-function a_open_out(var @!f:alpha_file):boolean;
- {open a text file for output}
-begin rewrite(f,name_of_file,'/O'); a_open_out:=rewrite_OK(f);
-end;
-@#
-function b_open_in(var @!f:byte_file):boolean;
- {open a binary file for input}
-begin reset(f,name_of_file,'/O'); b_open_in:=reset_OK(f);
-end;
-@#
-function b_open_out(var @!f:byte_file):boolean;
- {open a binary file for output}
-begin rewrite(f,name_of_file,'/O'); b_open_out:=rewrite_OK(f);
-end;
-@#
-function w_open_in(var @!f:word_file):boolean;
- {open a word file for input}
-begin reset(f,name_of_file,'/O'); w_open_in:=reset_OK(f);
-end;
-@#
-function w_open_out(var @!f:word_file):boolean;
- {open a word file for output}
-begin rewrite(f,name_of_file,'/O'); w_open_out:=rewrite_OK(f);
-end;
-@y
-@ All of the file opening functions are defined in C.
-@d no_file_path = -1
-@z
-
-@x [3.27] Do file closing in C.
-@ Files can be closed with the \ph\ routine `|close(f)|', which
-@:PASCAL H}{\ph@>
-@^system dependencies@>
-should be used when all input or output with respect to |f| has been completed.
-This makes |f| available to be opened again, if desired; and if |f| was used for
-output, the |close| operation makes the corresponding external file appear
-on the user's area, ready to be read.
-
-@p procedure a_close(var @!f:alpha_file); {close a text file}
-begin close(f);
-end;
-@#
-procedure b_close(var @!f:byte_file); {close a binary file}
-begin close(f);
-end;
-@#
-procedure w_close(var @!f:word_file); {close a word file}
-begin close(f);
-end;
-@y
-@ And all the file closing routines as well.
-@z
-
-@x [3.29] l.888 - Array size of input buffer is determined at runtime.
-@!buffer:array[0..buf_size] of ASCII_code; {lines of characters being read}
-@y
-@!buffer:^ASCII_code; {lines of characters being read}
-@z
-
-@x [3.30] Do `input_ln' in C.
-Standard \PASCAL\ says that a file should have |eoln| immediately
-before |eof|, but \MP\ needs only a weaker restriction: If |eof|
-occurs in the middle of a line, the system function |eoln| should return
-a |true| result (even though |f^| will be undefined).
-
-@p function input_ln(var @!f:alpha_file;@!bypass_eoln:boolean):boolean;
- {inputs the next line or returns |false|}
-var @!last_nonblank:0..buf_size; {|last| with trailing blanks removed}
-begin if bypass_eoln then if not eof(f) then get(f);
- {input the first character of the line into |f^|}
-last:=first; {cf.\ Matthew 19\thinspace:\thinspace30}
-if eof(f) then input_ln:=false
-else begin last_nonblank:=first;
- while not eoln(f) do
- begin if last>=max_buf_stack then
- begin max_buf_stack:=last+1;
- if max_buf_stack=buf_size then
- @<Report overflow of the input buffer, and abort@>;
- end;
- buffer[last]:=xord[f^]; get(f); incr(last);
- if buffer[last-1]<>" " then last_nonblank:=last;
- end;
- last:=last_nonblank; input_ln:=true;
- end;
-end;
-@y
-We define |input_ln| in C, for efficiency. Nevertheless we quote the module
-`Report overflow of the input buffer, and abort' here in order to make
-\.{WEAVE} happy.
-
-@p @{ @<Report overflow of the input buffer, and abort@> @}
-@z
-
-@x [3.31] `term_in' and `term_out' are standard input and output.
-@<Glob...@>=
-@!term_in:alpha_file; {the terminal as an input file}
-@!term_out:alpha_file; {the terminal as an output file}
-@y
-@d term_in==stdin {the terminal as an input file}
-@d term_out==stdout {the terminal as an output file}
-@z
-
-@x [3.32] We don't need to open the terminal files.
-@ Here is how to open the terminal files
-in \ph. The `\.{/I}' switch suppresses the first |get|.
-@: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}
-@y
-@ Here is how to open the terminal files. |t_open_out| does nothing.
-|t_open_in|, on the other hand, does the work of ``rescanning,'' or getting
-any command line arguments the user has provided. It's defined in C.
-
-@d t_open_out == {output already open for text output}
-@z
-
-@x [3.33] Flushing output.
-these operations can be specified in \ph:
-@: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}
-@y
-these operations can be specified with {\mc UNIX}. |update_terminal|
-does an |fflush| (via the macro |flush|). |clear_terminal| is redefined
-to do nothing, since the user should control the terminal.
-@^system dependencies@>
-
-@d update_terminal == fflush(term_out)
-@d clear_terminal == do_nothing
-@z
-
-@x [3.36] Reading the command line.
-@ The following program does the required initialization
-without retrieving a possible command line.
-It should be clear how to modify this routine to deal with command lines,
-if the system permits them.
-@^system dependencies@>
-
-@p function init_terminal:boolean; {gets the terminal input started}
-label exit;
-begin t_open_in;
-loop@+begin wake_up_terminal; write(term_out,'**'); update_terminal;
-@.**@>
- if not input_ln(term_in,true) then {this shouldn't happen}
- begin write_ln(term_out);
- write(term_out,'! End of file on the terminal... why?');
-@.End of file on the terminal@>
- init_terminal:=false; return;
- end;
- loc:=first;
- while (loc<last)and(buffer[loc]=" ") do incr(loc);
- if loc<last then
- begin init_terminal:=true;
- return; {return unless the line was all blank}
- end;
- write_ln(term_out,'Please type the name of your input file.');
- end;
-exit:end;
-@y
-@ The following program does the required initialization.
-Iff anything has been specified on the command line, then |t_open_in|
-will return with |last > first|.
-@^system dependencies@>
-
-@p
-function init_terminal:boolean; {gets the terminal input started}
-label exit;
-begin
- t_open_in;
- if last > first then begin
- loc := first;
- while (loc < last) and (buffer[loc]=' ') do
- incr(loc);
- if loc < last then begin
- init_terminal := true;
- goto exit;
- end;
- end;
- loop@+begin
- wake_up_terminal; write(term_out, '**'); update_terminal;
-@.**@>
- if not input_ln(term_in,true) then begin {this shouldn't happen}
- write_ln(term_out);
- write_ln(term_out, '! End of file on the terminal... why?');
-@.End of file on the terminal@>
- init_terminal:=false;
- return;
- end;
-
- loc:=first;
- while (loc<last)and(buffer[loc]=" ") do
- incr(loc);
-
- if loc<last then begin
- init_terminal:=true;
- return; {return unless the line was all blank}
- end;
- write_ln(term_out, 'Please type the name of your input file.');
- end;
-exit:
-end;
-@z
-
-@x [4.38] Dynamically allocate pool arrays.
-@!str_pool:packed array[pool_pointer] of pool_ASCII_code; {the characters}
-@!str_start : array[str_number] of pool_pointer; {the starting pointers}
-@!next_str : array[str_number] of str_number; {for linking strings in order}
-@y
-@!str_pool:^pool_ASCII_code; {the characters}
-@!str_start : ^pool_pointer; {the starting pointers}
-@!next_str : ^str_number; {for linking strings in order}
-@z
-
-@x [4.44] One more array.
-@!str_ref:array[str_number] of 0..max_str_ref;
-@y
-@!str_ref:^str_ref_type; {web2c only does |^identifier|}
-@z
-
-@x [4.64] l.1430 -- Do not hardwire printable ASCII.
- (k<" ")or(k>"~")
-@y
- not xprn[k]
-@z
-
-@x [5.69] error_line is a variable, so can't be a subrange array bound
-@!trick_buf:array[0..error_line] of ASCII_code; {circular buffer for
-@y
-@!trick_buf:array[0..ssup_error_line] of ASCII_code; {circular buffer for
-@z
-
-@x [5.76] Print rest of banner, eliminate misleading `no preloaded'
-@ By popular demand, \MP\ prints the banner line only on the transcript file.
-Thus there is nothing special to be printed here.
-
-@<Initialize the output...@>=
-update_terminal;
-@y
-@ Here is the very first thing that \MP\ prints: a headline that identifies
-the version number and base name. The |term_offset| variable is temporarily
-incorrect, but the discrepancy is not serious since we assume that the banner
-and mem identifier together will occupy at most |max_print_line|
-character positions.
-
-@<Initialize the output...@>=
-wterm (banner);
-wterm (version_string);
-if mem_ident>0 then print(mem_ident); print_ln;
-if translate_filename then begin
- wterm('(');
- fputs(translate_filename, stdout);
- wterm_ln(')');
-end;
-update_terminal;
-@z
-
-@x [6.83] l.1815 - Add unspecified_mode.
-@d error_stop_mode=3 {stops at every opportunity to interact}
-@y
-@d error_stop_mode=3 {stops at every opportunity to interact}
-@d unspecified_mode=4 {extra value for command-line switch}
-@z
-
-@x [6.83] l.1825 - file:line:error style messages.
- print_nl("! "); print(#);
-@y
- if (file_line_error_style_p and not terminal_input) then
- begin
- print_nl ("");
- print (full_source_filename_stack[in_open]);
- print (":"); print_int (line); print (": ");
- print (#);
- end
- else begin print_nl("! "); print(#) end;
-@z
-
-@x [6.83] l.1822 - Add interaction_option.
-@!interaction:batch_mode..error_stop_mode; {current level of interaction}
-@y
-@!interaction:batch_mode..error_stop_mode; {current level of interaction}
-@!interaction_option:batch_mode..unspecified_mode; {set from command line}
-@z
-
-@x [6.84] l.1824 - Allow override by command line switch.
-@ @<Set init...@>=interaction:=error_stop_mode;
-@y
-@ @<Set init...@>=if interaction_option=unspecified_mode then
- interaction:=error_stop_mode
-else
- interaction:=interaction_option;
-@z
-
-@x [6.90] Eliminate non-local goto.
-@<Error hand...@>=
-procedure jump_out;
-begin goto end_of_MP;
-end;
-@y
-@d do_final_end==begin
- update_terminal;
- ready_already:=0;
- if (history <> spotless) and (history <> warning_issued) then
- uexit(1)
- else
- uexit(0);
- end
-@<Error hand...@>=
-procedure jump_out;
-begin
-close_files_and_terminate;
-do_final_end;
-end;
-@z
-
-@x [6.92] l.1956 - halt on error?
-print_char("."); show_context;
-@y
-print_char("."); show_context;
-if (halt_on_error_p) then begin
- history:=fatal_error_stop; jump_out;
-end;
-@z
-
-@x [6.93] Handle the switch-to-editor option.
-line ready to be edited. But such an extension requires some system
-wizardry, so the present implementation simply types out the name of the
-file that should be
-edited and the relevant line number.
-@^system dependencies@>
-
-There is a secret `\.D' option available when the debugging routines haven't
-been commented~out.
-@^debugging@>
-@y
-line ready to be edited.
-We do this by calling the external procedure |call_edit| with a pointer to
-the filename, its length, and the line number.
-However, here we just set up the variables that will be used as arguments,
-since we don't want to do the switch-to-editor until after \MP\ has closed
-its files.
-@^system dependencies@>
-
-There is a secret `\.D' option available when the debugging routines have
-not been commented out.
-@^debugging@>
-@d edit_file==input_stack[file_ptr]
-@z
-@x
-"E": if file_ptr>0 then
- begin print_nl("You want to edit file ");
-@.You want to edit file x@>
- print(input_stack[file_ptr].name_field);
- print(" at line "); print_int(true_line);@/
- interaction:=scroll_mode; jump_out;
-@y
-"E": if file_ptr>0 then
- begin
- edit_name_start:=str_start[edit_file.name_field];
- edit_name_length:=length(edit_file.name_field);
- edit_line:=true_line;
- jump_out;
-@z
-
-@x [7.111] Do half and halfp in cpascal.h.
-@d half(#)==(#) div 2
-@d halfp(#)==(#) div 2
-@y
-@z
-
-@x [7.122-7.130] Optionally replace make_fraction etc. with external routines.
-@p function make_fraction(@!p,@!q:integer):fraction;
-@y
-In the C version, there are external routines that use double precision
-floating point to simulate functions such as |make_fraction|. This is carefully
-done to be virtually machine-independent and it gives up to 12 times speed-up
-on machines with hardware floating point. Since some machines do not have fast
-double-precision floating point, we provide a C preprocessor switch that allows
-selecting the standard versions given below.
-
-@p ifdef('FIXPT')@/
-function make_fraction(@!p,@!q:integer):fraction;
-@z
-@x
- if negative then make_fraction:=-(f+n)@+else make_fraction:=f+n;
- end;
-end;
-@y
- if negative then make_fraction:=-(f+n)@+else make_fraction:=f+n;
- end;
-end;@/
-endif('FIXPT')
-@z
-@x
-@p function take_fraction(@!q:integer;@!f:fraction):integer;
-@y
-@p ifdef('FIXPT')@/
-function take_fraction(@!q:integer;@!f:fraction):integer;
-@z
-@x
-else take_fraction:=n+p;
-end;
-@y
-else take_fraction:=n+p;
-end;@/
-endif('FIXPT')
-@z
-@x
-@p function take_scaled(@!q:integer;@!f:scaled):integer;
-@y
-@p ifdef('FIXPT')@/
-function take_scaled(@!q:integer;@!f:scaled):integer;
-@z
-@x
-else take_scaled:=n+p;
-end;
-@y
-else take_scaled:=n+p;
-end;@/
-endif('FIXPT')
-@z
-@x
-operands are positive. \ (This procedure is not used especially often,
-so it is not part of \MP's inner loop.)
-
-@p function make_scaled(@!p,@!q:integer):scaled;
-@y
-operands are positive. \ (This procedure is not used especially often,
-so it is not part of \MP's inner loop, but we might as well allow for
-an external C routine.)
-
-@p ifdef('FIXPT')@/
-function make_scaled(@!p,@!q:integer):scaled;
-@z
-@x
- if negative then make_scaled:=-(f+n)@+else make_scaled:=f+n;
- end;
-end;
-@y
- if negative then make_scaled:=-(f+n)@+else make_scaled:=f+n;
- end;
-end;@/
-endif('FIXPT')
-@z
-
-@x [7.134] Do floor_scaled, floor_unscaled, round_unscaled, round_fraction in C.
-@p function floor_scaled(@!x:scaled):scaled;
- {$2^{16}\lfloor x/2^{16}\rfloor$}
-var @!be_careful:integer; {temporary register}
-begin if x>=0 then floor_scaled:=x-(x mod unity)
-else begin be_careful:=x+1;
- floor_scaled:=x+((-be_careful) mod unity)+1-unity;
- end;
-end;
-@#
-function round_unscaled(@!x:scaled):integer;
- {$\lfloor x/2^{16}+.5\rfloor$}
-var @!be_careful:integer; {temporary register}
-begin if x>=half_unit then round_unscaled:=1+((x-half_unit) div unity)
-else if x>=-half_unit then round_unscaled:=0
-else begin be_careful:=x+1;
- round_unscaled:=-(1+((-be_careful-half_unit) div unity));
- end;
-end;
-@#
-function round_fraction(@!x:fraction):scaled;
- {$\lfloor x/2^{12}+.5\rfloor$}
-var @!be_careful:integer; {temporary register}
-begin if x>=2048 then round_fraction:=1+((x-2048) div 4096)
-else if x>=-2048 then round_fraction:=0
-else begin be_careful:=x+1;
- round_fraction:=-(1+((-be_careful-2048) div 4096));
- end;
-end;
-@y
-@z
-
-@x [9.168] Increase memory size.
-@d min_quarterword=0 {smallest allowable value in a |quarterword|}
-@d max_quarterword=255 {largest allowable value in a |quarterword|}
-@d min_halfword==0 {smallest allowable value in a |halfword|}
-@d max_halfword==65535 {largest allowable value in a |halfword|}
-@y
-@d min_quarterword=0 {smallest allowable value in a |quarterword|}
-@d max_quarterword=255 {largest allowable value in a |quarterword|}
-@d min_halfword==0 {smallest allowable value in a |halfword|}
-@d max_halfword==@"FFFFFFF {largest allowable value in a |halfword|}
-@z
-
-@x [9.170] Don't bother to subtract zero.
-@d ho(#)==#-min_halfword
- {to take a sixteen-bit item from a halfword}
-@d qo(#)==#-min_quarterword {to read eight bits from a quarterword}
-@d qi(#)==#+min_quarterword {to store eight bits in a quarterword}
-@y
-@d ho(#)==#
-@d qo(#)==#
-@d qi(#)==#
-@z
-
-@x [9.171] memory_word is defined externally.
-@!two_halves = packed record@;@/
- @!rh:halfword;
- case two_choices of
- 1: (@!lh:halfword);
- 2: (@!b0:quarterword; @!b1:quarterword);
- end;
-@!four_quarters = packed record@;@/
- @!b0:quarterword;
- @!b1:quarterword;
- @!b2:quarterword;
- @!b3:quarterword;
- end;
-@!memory_word = record@;@/
- case three_choices of
- 1: (@!int:integer);
- 2: (@!hh:two_halves);
- 3: (@!qqqq:four_quarters);
- end;
-@y
-@=#include "texmfmem.h";@>
-@z
-
-@x [9.174] mem is dynamically allocated.
-@!mem : array[mem_min..mem_max] of memory_word; {the big dynamic storage area}
-@y
-@!mem : ^memory_word; {the big dynamic storage area}
-@z
-
-@x [10.184] Fix an unsigned/signed problem in getnode.
-if r>p+1 then @<Allocate from the top of node |p| and |goto found|@>;
-@y
-if r>intcast(p+1) then @<Allocate from the top of node |p| and |goto found|@>;
-@z
-
-% [11.193] Change the word `free' so that it doesn't conflict with the
-% standard C library routine of the same name. Also change arrays that
-% use mem_max, since that's a variable now, effectively disabling the feature.
-@x
-are debugging.)
-
-@<Glob...@>=
-@!debug @!free: packed array [mem_min..mem_max] of boolean; {free cells}
-@t\hskip1em@>@!was_free: packed array [mem_min..mem_max] of boolean;
-@y
-are debugging.)
-
-@d free==free_arr
-
-@<Glob...@>=
-@!debug @!free: packed array [0..1] of boolean; {free cells}
-@t\hskip1em@>@!was_free: packed array [0..1] of boolean;
-@z
-
-@x [11.197] Eliminate unsigned comparisons to zero.
-repeat if (p>=lo_mem_max)or(p<mem_min) then clobbered:=true
- else if (rlink(p)>=lo_mem_max)or(rlink(p)<mem_min) then clobbered:=true
-@y
-repeat if (p>=lo_mem_max) then clobbered:=true
- else if (rlink(p)>=lo_mem_max) then clobbered:=true
-@z
-
-@x [12.212] Do `fix_date_and_time' in C.
-@ The following procedure, which is called just before \MP\ initializes its
-input and output, establishes the initial values of the date and time.
-@^system dependencies@>
-Since standard \PASCAL\ cannot provide such information, something special
-is needed. The program here simply specifies July 4, 1776, at noon; but
-users probably want a better approximation to the truth.
-
-Note that the values are |scaled| integers. Hence \MP\ can no longer
-be used after the year 32767.
-
-@p procedure fix_date_and_time;
-begin internal[time]:=12*60*unity; {minutes since midnight}
-internal[day]:=4*unity; {fourth day of the month}
-internal[month]:=7*unity; {seventh month of the year}
-internal[year]:=1776*unity; {Anno Domini}
-end;
-@y
-@ The following procedure, which is called just before \MP\ initializes its
-input and output, establishes the initial values of the date and time.
-It is calls an externally defined |date_and_time|, even though it could
-be done from Pascal.
-The external procedure also sets up interrupt catching.
-@^system dependencies@>
-
-Note that the values are |scaled| integers. Hence \MP\ can no longer
-be used after the year 32767.
-
-@p procedure fix_date_and_time;
-begin
- date_and_time(internal[time],internal[day],internal[month],internal[year]);
- internal[time] := internal[time] * unity;
- internal[day] := internal[day] * unity;
- internal[month] := internal[month] * unity;
- internal[year] := internal[year] * unity;
-end;
-@z
-
-@x Replace class with c_class to avoid C++ keyword.
-@d max_class=20 {the largest class number}
-@y
-@d max_class=20 {the largest class number}
-@d class==c_class
-@z
-
-@x [12.217] Allow tab and form feed as input.
-for k:=127 to 255 do char_class[k]:=invalid_class;
-@y
-for k:=127 to 255 do char_class[k]:=invalid_class;
-char_class[tab]:=space_class;
-char_class[form_feed]:=space_class;
-@z
-
-@x [18.300,301] l.6451 - Make path_size a configuration option.
-@!delta_x,@!delta_y,@!delta:array[0..path_size] of scaled; {knot differences}
-@!psi:array[1..path_size] of angle; {turning angles}
-
-@ @<Other local variables for |make_choices|@>=
-@!k,@!n:0..path_size; {current and final knot numbers}
-@y
-@!delta_x:^scaled; {knot differences}
-@!delta_y:^scaled; {knot differences}
-@!delta:^scaled; {knot differences}
-@!psi:^angle; {turning angles}
-
-@ @<Other local variables for |make_choices|@>=
-@!k,@!n:0..sup_path_size; {current and final knot numbers}
-@z
-
-@x [18.304] l.6544 - Make path_size a configuration option.
-@!theta:array[0..path_size] of angle; {values of $\theta_k$}
-@!uu:array[0..path_size] of fraction; {values of $u_k$}
-@!vv:array[0..path_size] of angle; {values of $v_k$}
-@!ww:array[0..path_size] of fraction; {values of $w_k$}
-
-@ Our immediate problem is to get the ball rolling by setting up the
-first equation or by realizing that no equations are needed, and to fit
-this initialization into a framework suitable for the overall computation.
-
-@<Declare the procedure called |solve_choices|@>=
-@t\4@>@<Declare subroutines needed by |solve_choices|@>@;
-procedure solve_choices(@!p,@!q:pointer;@!n:halfword);
-label found,exit;
-var @!k:0..path_size; {current knot number}
-@y
-@!theta:^angle; {values of $\theta_k$}
-@!uu:^fraction; {values of $u_k$}
-@!vv:^angle; {values of $v_k$}
-@!ww:^fraction; {values of $w_k$}
-
-@ Our immediate problem is to get the ball rolling by setting up the
-first equation or by realizing that no equations are needed, and to fit
-this initialization into a framework suitable for the overall computation.
-
-@<Declare the procedure called |solve_choices|@>=
-@t\4@>@<Declare subroutines needed by |solve_choices|@>@;
-procedure solve_choices(@!p,@!q:pointer;@!n:halfword);
-label found,exit;
-var @!k:0..sup_path_size; {current knot number}
-@z
-
-@x [27.585] l.11443 - data for file:line:error style.
-@!mpx_name : array[0..max_in_open] of halfword;
-@y
-@!mpx_name : array[0..max_in_open] of halfword;
-@!source_filename_stack : ^str_number;
-@!full_source_filename_stack : ^str_number;
-@z
-
-@x [35.745] area and extension rules.
-@ The file names we shall deal with for illustrative purposes have the
-following structure: If the name contains `\.>' or `\.:', the file area
-consists of all characters up to and including the final such character;
-otherwise the file area is null. If the remaining file name contains
-`\..', the file extension consists of all such characters from the first
-remaining `\..' to the end, otherwise the file extension is null.
-@^system dependencies@>
-
-We can scan such file names easily by using two global variables that keep track
-of the occurrences of area and extension delimiters. Note that these variables
-cannot be of type |pool_pointer| because a string pool compaction could occur
-while scanning a file name.
-
-@<Glob...@>=
-@!area_delimiter:integer;
- {most recent `\.>' or `\.:' relative to |str_start[str_ptr]|}
-@!ext_delimiter:integer; {the relevant `\..', if any}
-@y
-@ The file names we shall deal with have the
-following structure: If the name contains `\./', the file area
-consists of all characters up to and including the final such character;
-otherwise the file area is null. If the remaining file name contains
-`\..', the file extension consists of all such characters from the first
-remaining `\..' to the end, otherwise the file extension is null.
-@^system dependencies@>
-
-We can scan such file names easily by using two global variables that keep track
-of the occurrences of area and extension delimiters. Note that these variables
-cannot be of type |pool_pointer| because a string pool compaction could occur
-while scanning a file name.
-
-@<Glob...@>=
-@!area_delimiter:integer; {most recent `\./' relative to |str_start[str_ptr]|}
-@!ext_delimiter:integer; {the relevant `\..', if any}
-@z
-
-@x [35.746] MP and MF area directories.
-@d MP_area=="MPinputs:"
-@.MPinputs@>
-@d MF_area=="MFinputs:"
-@.MFinputs@>
-@d MP_font_area=="TeXfonts:"
-@.TeXfonts@>
-@y
-In C, the default paths are specified separately.
-@z
-
-@x [35.747] filenames: quoted
-area_delimiter:=-1; ext_delimiter:=-1;
-@y
-area_delimiter:=-1; ext_delimiter:=-1; quoted_filename:=false;
-@z
-
-@x [35.748] (more_name) Generalize directory separators.
-begin if c=" " then more_name:=false
-else begin if (c=">")or(c=":") then
-@y
-begin
-if c="""" then begin
- quoted_filename:=not quoted_filename;
- more_name:=true;
- end
-else if ((c=" ")or(c=tab)) and stop_at_space and (not quoted_filename) then
- more_name:=false
-else begin
- if IS_DIR_SEP (c) then
-@z
-@x [still 35.748] Last (not first) . is extension.
- else if (c=".")and(ext_delimiter<0) then
-@y
- else if (c=".") then
-@z
-
-@x [35.749] (end_name) Quote name if necessary.
-procedure end_name;
-var a,@!n,@!e:pool_pointer; {length of area, name, and extension}
-begin e:=pool_ptr-str_start[str_ptr]; {total length}
-@y
-procedure end_name;
-var a,@!n,@!e:pool_pointer; {length of area, name, and extension}
-@!j,@!s,@!t:pool_pointer; {running indices}
-@!must_quote:boolean; {whether we need to quote a string}
-begin str_room(6); {room for quotes}
-if area_delimiter<>-1 then begin
- {maybe quote |cur_area|}
- must_quote:=false;
- s:=str_start[str_ptr];
- t:=str_start[str_ptr]+area_delimiter+1;
- j:=s;
- while (not must_quote) and (j<>t) do begin
- must_quote:=str_pool[j]=" "; incr(j);
- end;
- if must_quote then begin
- for j:=pool_ptr-1 downto t do str_pool[j+2]:=str_pool[j];
- str_pool[t+1]:="""";
- for j:=t-1 downto s do str_pool[j+1]:=str_pool[j];
- str_pool[s]:="""";
- if ext_delimiter<>-1 then ext_delimiter:=ext_delimiter+2;
- area_delimiter:=area_delimiter+2;
- pool_ptr:=pool_ptr+2;
- end;
- s:=str_start[str_ptr]+area_delimiter+1;
- end
-else begin
- s:=str_start[str_ptr];
- end;
-{maybe quote |cur_name|}
-if ext_delimiter=-1 then t:=pool_ptr else t:=str_start[str_ptr]+ext_delimiter;
-must_quote:=false;
-j:=s;
-while (not must_quote) and (j<>t) do begin
- must_quote:=str_pool[j]=" "; incr(j);
- end;
-if must_quote then begin
- for j:=pool_ptr-1 downto t do str_pool[j+2]:=str_pool[j];
- str_pool[t+1]:="""";
- for j:=t-1 downto s do str_pool[j+1]:=str_pool[j];
- str_pool[s]:="""";
- if ext_delimiter<>-1 then ext_delimiter:=ext_delimiter+2;
- pool_ptr:=pool_ptr+2;
- end;
-if ext_delimiter<>-1 then begin
- {maybe quote |cur_ext|}
- s:=str_start[str_ptr]+ext_delimiter;
- t:=pool_ptr;
- must_quote:=false;
- j:=s;
- while (not must_quote) and (j<>t) do begin
- must_quote:=str_pool[j]=" "; incr(j);
- end;
- if must_quote then begin
- str_pool[t+1]:="""";
- for j:=t-1 downto s do str_pool[j+1]:=str_pool[j];
- str_pool[s]:="""";
- pool_ptr:=pool_ptr+2;
- end;
- end;
-e:=pool_ptr-str_start[str_ptr]; {total length}
-@z
-
-@x [35.750] print_file_name
-begin print(a); print(n); print(e);
-@y
-var must_quote: boolean; {whether to quote the filename}
-@!j:pool_pointer; {index into |str_pool|}
-begin
-must_quote:=false;
-if a>0 then begin
- j:=str_start[a];
- while (not must_quote) and (j<>str_stop(a)) do begin
- must_quote:=str_pool[j]=" "; incr(j);
- end;
-end;
-if n>0 then begin
- j:=str_start[n];
- while (not must_quote) and (j<>str_stop(n)) do begin
- must_quote:=str_pool[j]=" "; incr(j);
- end;
-end;
-if e>0 then begin
- j:=str_start[e];
- while (not must_quote) and (j<>str_stop(e)) do begin
- must_quote:=str_pool[j]=" "; incr(j);
- end;
-end;
-if must_quote then print("""");
-if a>0 then
- for j:=str_start[a] to str_stop(a)-1 do
- if so(str_pool[j])<>"""" then
- print(so(str_pool[j]));
-if n>0 then
- for j:=str_start[n] to str_stop(n)-1 do
- if so(str_pool[j])<>"""" then
- print(so(str_pool[j]));
-if e>0 then
- for j:=str_start[e] to str_stop(e)-1 do
- if so(str_pool[j])<>"""" then
- print(so(str_pool[j]));
-if must_quote then print("""");
-@z
-
-@x [35.751] macro used in pack_file_name
-@d append_to_name(#)==begin c:=#; incr(k);
- if k<=file_name_size then name_of_file[k]:=xchr[c];
- end
-@y
-@d append_to_name(#)==begin c:=#; if not (c="""") then begin incr(k);
- if k<=file_name_size then name_of_file[k]:=xchr[c];
- end end
-@z
-
-@x [35.751] (pack_file_name) malloc and null terminate name_of_file.
-for j:=str_start[a] to str_stop(a)-1 do append_to_name(so(str_pool[j]));
-@y
-if name_of_file then libc_free (name_of_file);
-name_of_file := xmalloc_array (ASCII_code, length(a)+length(n)+length(e)+1);
-for j:=str_start[a] to str_stop(a)-1 do append_to_name(so(str_pool[j]));
-@z
-@x
-for k:=name_length+1 to file_name_size do name_of_file[k]:=' ';
-@y
-name_of_file[name_length + 1] := 0;
-@z
-
-@x [35.752] default mem area is nonexistent
-@d mem_default_length=15 {length of the |MP_mem_default| string}
-@d mem_area_length=6 {length of its area part}
-@y
-@d mem_area_length=0 {no fixed area in C}
-@z
-
-@x [35.753] Where `plain.mem' is.
-@!MP_mem_default:packed array[1..mem_default_length] of char;
-
-@ @<Set init...@>=
-MP_mem_default:='MPlib:plain.mem';
-@.MPlib@>
-@.plain@>
-@^system dependencies@>
-@y
-@!mem_default_length: integer;
-@!MP_mem_default: ^char;
-@!troff_mode:boolean; {has the user requested \.{troff} mode?}
-
-@ We set the name of the default format file and the length of that name
-in \.{texmfmp.c}, since we want them to depend on the name of the
-program.
-@z
-
-@x [35.755] Change to pack_buffered_name as with pack_file_name.
-for j:=1 to n do append_to_name(xord[MP_mem_default[j]]);
-@y
-if name_of_file then libc_free (name_of_file);
-name_of_file := xmalloc_array (ASCII_code, n+(b-a+1)+mem_ext_length+1);
-for j:=1 to n do append_to_name(xord[MP_mem_default[j]]);
-@z
-% @x [35.755] Set program name to match format.
-% for j:=a to b do append_to_name(buffer[j]);
-% @y
-% for j:=a to b do append_to_name(buffer[j]);
-% name_of_file[k+1]:=0;
-% kpse_reset_program_name(name_of_file+1);{set search path to match format}
-% @z
-@x [35.755] Change to pack_buffered_name as with pack_file_name.
-for k:=name_length+1 to file_name_size do name_of_file[k]:=' ';
-@y
-name_of_file[name_length + 1] := 0;
-@z
-
-@x [35.756] Mem file opening: only try once, with path searching.
- pack_buffered_name(0,loc,j-1); {try first without the system file area}
- if w_open_in(mem_file) then goto found;
- pack_buffered_name(mem_area_length,loc,j-1);
- {now try the system mem file area}
- if w_open_in(mem_file) then goto found;
-@y
- pack_buffered_name(0,loc,j-1);
- if w_open_in(mem_file) then goto found;
-@z
-
-@x [still 35.756] Replace `PLAIN' in error messages with `default'.
- wterm_ln('Sorry, I can''t find that mem file;',' will try PLAIN.');
-@y
- wterm ('Sorry, I can''t find the mem file `');
- fputs (stringcast(name_of_file + 1), stdout);
- wterm ('''; will try `');
- fputs (MP_mem_default + 1, stdout);
- wterm_ln ('''.');
-@z
-@x
- wterm_ln('I can''t find the PLAIN mem file!');
-@.I can't find PLAIN...@>
-@y
- wterm ('I can''t find the mem file `');
- fputs (MP_mem_default + 1, stdout);
- wterm_ln ('''!');
-@.I can't find the mem...@>
-@z
-
-@x [35.758] Make scan_file_name ignore leading tabs as well as spaces.
-@p procedure scan_file_name;
-label done;
-begin begin_name;
-while buffer[loc]=" " do incr(loc);
-@y
-@p procedure scan_file_name;
-label done;
-begin begin_name;
-while (buffer[loc]=" ")or(buffer[loc]=tab) do incr(loc);
-@z
-
-@x [35.760] `logname' is declared in <unistd.h> on some systems.
-`\.{.mem}' and `\.{.tfm}' in order to make the names of \MP's output files.
-@y
-`\.{.mem}' and `\.{.tfm}' in order to make the names of \MP's output files.
-@d log_name == texmf_log_name
-@z
-
-@x [35.763] prompt_file_name: avoid empty filenames.
-var @!k:0..buf_size; {index into |buffer|}
-@y
-var @!k:0..buf_size; {index into |buffer|}
-@!saved_cur_name:str_number; {to catch empty terminal input}
-@z
-
-@x [35.763] prompt_file_name: avoid empty filenames.
-clear_terminal; prompt_input(": "); @<Scan file name in the buffer@>;
-if cur_ext="" then cur_ext:=e;
-@y
-saved_cur_name:=cur_name;
-clear_terminal; prompt_input(": "); @<Scan file name in the buffer@>;
-if cur_ext="" then cur_ext:=e;
-if length(cur_name)=0 then cur_name:=saved_cur_name;
-@z
-
-@x [35.764] <Scan file name...> needs similar leading tab treatment.
-@ @<Scan file name in the buffer@>=
-begin begin_name; k:=first;
-while (buffer[k]=" ")and(k<last) do incr(k);
-@y
-@ @<Scan file name in the buffer@>=
-begin begin_name; k:=first;
-while ((buffer[k]=" ")or(buffer[k]=tab))and(k<last) do incr(k);
-@z
-
-@x [35.765] Adjust for C string conventions.
-@!months:packed array [1..36] of char; {abbreviations of month names}
-@y
-@!months:^char;
-@z
-
-@x [35.765] Change name of recorder file.
-if job_name=0 then job_name:="mpout";
-pack_job_name(".log");
-@y
-if job_name=0 then job_name:=get_job_name("mpout");
-pack_job_name(".fls");
-recorder_change_filename(stringcast(name_of_file+1));
-pack_job_name(".log");
-@z
-
-@x [35.767]
-begin wlog(banner);
-print(mem_ident); print(" ");
-print_int(round_unscaled(internal[day])); print_char(" ");
-months:='JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC';
-@y
-begin wlog(banner);
-wlog (version_string);
-print(mem_ident); print(" ");
-print_int(round_unscaled(internal[day])); print_char(" ");
-months := ' JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC';
-@z
-
-@x [35.767] l.14341 - Print name of TCX, if given.
-end
-@y
-if translate_filename then begin
- wlog_cr;
- wlog('(');
- fputs(translate_filename, log_file);
- wlog(')');
-end;
-end
-@z
-
-@x [35.768] (try_extension) a_open_in of input file needs path specifier.
-begin pack_file_name(cur_name,cur_area,ext);
-in_name:=cur_name; in_area:=cur_area;
-if a_open_in(cur_file) then try_extension:=true
-else begin if str_vs_str(ext,".mf")=0 then in_area:=MF_area
- else in_area:=MP_area;
- pack_file_name(cur_name,in_area,ext);
- try_extension:=a_open_in(cur_file);
- end;
-@y
-{|cur_ext| will be \.{two} if the filename was \.{one.two}.}
-begin pack_file_name(cur_name,cur_area,cur_ext);
-in_name:=cur_name; in_area:=cur_area;
-{The extension is not relevant for determining whether we're allowed to
- open the file.}
-if not open_in_name_ok(stringcast(name_of_file+1)) then try_extension:=false
-else if str_vs_str(ext,".mf")=0 then
- try_extension:=a_open_in(cur_file, kpse_mf_format)
-else try_extension:=a_open_in(cur_file, kpse_mp_format);
-@z
-
-@x [35.770] We need another loop variable.
-@p procedure start_input; {\MP\ will \.{input} something}
-label done;
-@y
-@p procedure start_input; {\MP\ will \.{input} something}
-label done;
-var j:integer;
-@z
-
-@x [still 35.770] Kpathsea already tries with no extension.
- if cur_ext="" then
- if try_extension(".mp") then goto done
- else if try_extension("") then goto done
- else if try_extension(".mf") then goto done
- else do_nothing
- else if try_extension(cur_ext) then goto done;
-@y
- if try_extension(".mp") then goto done
- else if try_extension(".mf") then goto done
- else do_nothing;
-@z
-
-@x [still 35.770] Allow jobname to be `one.two'.
- begin job_name:=cur_name; str_ref[job_name]:=max_str_ref;
-@y
- begin
- j:=1;
- begin_name;
- stop_at_space:=false;
- while (j<=name_length)and(more_name(name_of_file[j])) do
- incr(j);
- stop_at_space:=true;
- end_name;
- job_name:=get_job_name(cur_name);
- str_ref[job_name] := max_str_ref;
-@z
-
-@x [35.771] Cannot return name to string pool, for the e option?
-flush_string(name); name:=cur_name; cur_name:=0
-@y
-@z
-
-@x [35.774] (copy_old_name) Allocate old_file_name dynamically.
-for j:=str_start[s] to str_stop(s)-1 do
-@y
-if old_file_name then libc_free (old_file_name);
-old_file_name := xmalloc_array (ASCII_code, length(s)+1);
-for j:=str_start[s] to str_stop(s)-1 do
-@z
-@x [still 35.774] Avoid blanking rest of nonexistent array.
-for k:=old_name_length+1 to file_name_size do @+old_file_name[k]:=' ';
-@y
-old_file_name[old_name_length + 1] := 0;
-@z
-
-@x [35.775] Declare old_file_name as a regular C string.
-@!old_file_name : packed array[1..file_name_size] of char;
-@y
-@!old_file_name : ^text_char;
-@z
-
-@x [35.776] [Unique to MP] Path selector for |a_open_in| of mpx file.
-if not a_open_in(cur_file) then
- begin end_file_reading;
-@y
-if not a_open_in(cur_file,no_file_path) then
- begin end_file_reading;
-@z
-
-@x [35.777] [Unique to MP] Invoke |makempx|.
-copy_old_name(name)
-{System-dependent code should be added here}
-@y
-copy_old_name (name);
-if not call_make_mpx (stringcast(old_file_name+1), stringcast(name_of_file+1))
- then goto not_found
-@z
-
-@x [35.778] [Unique to MP] Fix help message for our implementation.
- ("try running it manually through MPtoTeX, TeX, and DVItoMP");
-@y
- ("try running it manually through MPto -tex, TeX, and DVItoMP.");
-@z
-
-@x [35.782] [Unique to MP] Path selector for |a_open_in| of readfrom file.
-if not a_open_in(rd_file[n]) then goto not_found;
-@y
-if not open_in_name_ok(stringcast(name_of_file+1))
- or not a_open_in(rd_file[n],kpse_mp_format) then goto not_found;
-@z
-
-@x [35.783] The Amiga needs a different open_write_file.
-@ Open |wr_file[n]| using file name~|s| and update |wr_fname[n]|.
-
-@p procedure open_write_file(s:str_number; n:readf_index);
-begin str_scan_file(s);
-pack_cur_name;
-while not a_open_out(wr_file[n]) do
- prompt_file_name("file name for write output","");
-wr_fname[n]:=s;
-add_str_ref(s);
-end;
-@y
-@ Open |wr_file[n]| using file name~|s| and update |wr_fname[n]|.
-The Amiga operating system does not permit write access to a file that is
-currently opened in read mode. To avoid disaster, we look for the file to
-be opened in the list of |read_from| files and close it if present.
-
-@d amiga==ifdef('AMIGA')
-@d agima==endif('AMIGA')
-@f amiga==begin
-@f agima==end
-
-@p procedure open_write_file(s:str_number; n:readf_index);
-amiga@;
-label done;
-var @!n0:readf_index; {Scratch variable}
-agima@;
-begin
- str_scan_file(s);
- pack_cur_name;
-amiga@;
- for n0:=0 to read_files-1 do begin
- if rd_fname[n0]<>0 then begin
- if str_vs_str(s,rd_fname[n0])=0 then begin
- a_close(rd_file[n0]);
- delete_str_ref(rd_fname[n0]);
- rd_fname[n0]:=0;
- if n0=read_files-1 then read_files:=n0;
- goto done;
- end;
- end;
- end;
-done: do_nothing;
-agima@;
-while not open_out_name_ok(stringcast(name_of_file+1))
- or not a_open_out(wr_file[n]) do
- prompt_file_name("file name for write output","");
-wr_fname[n]:=s;
-add_str_ref(s);
-{If on first line of input, log file is not ready yet, so don't log.}
-if log_opened then begin
- old_setting:=selector;
- if (internal[tracing_online]<=0) then
- selector:=log_only {Show what we're doing in the log file.}
- else selector:=term_and_log; {Show what we're doing.}
- print_nl("write");
- print_int(n);
- print(" = `");
- print_file_name(cur_name,cur_area,cur_ext);
- print("'."); print_nl(""); print_ln;
- selector:=old_setting;
-end;
-end;
-@z
-
-@x [41.1040] if batchmode, MakeTeX... scripts should be silent.
-mode_command: begin print_ln; interaction:=cur_mod;
-@y
-mode_command: begin print_ln; interaction:=cur_mod;
-if interaction = batch_mode
-then kpse_make_tex_discard_errors := 1
-else kpse_make_tex_discard_errors := 0;
-@z
-
-@x [42.1151] Fix `threshold' conflict with local variable name.
-@p function threshold(@!m:integer):scaled;
-var @!d:scaled; {lower bound on the smallest interval size}
-begin excess:=min_cover(0)-m;
-if excess<=0 then threshold:=0
-else begin repeat d:=perturbation;
- until min_cover(d+d)<=m;
- while min_cover(d)>m do d:=perturbation;
- threshold:=d;
- end;
-end;
-@y
-@p function compute_threshold(@!m:integer):scaled;
-var @!d:scaled; {lower bound on the smallest interval size}
-begin excess:=min_cover(0)-m;
-if excess<=0 then compute_threshold:=0
-else begin repeat d:=perturbation;
- until min_cover(d+d)<=m;
- while min_cover(d)>m do d:=perturbation;
- compute_threshold:=d;
- end;
-end;
-@z
-
-@x [42.1152] Change the call to the threshold function.
-begin d:=threshold(m); perturbation:=0;
-@y
-begin d:=compute_threshold(m); perturbation:=0;
-@z
-
-@x [45.1164] Writing the tfm file.
-@d tfm_out(#)==write(tfm_file,#) {output one byte to |tfm_file|}
-
-@p procedure tfm_two(@!x:integer); {output two bytes to |tfm_file|}
-begin tfm_out(x div 256); tfm_out(x mod 256);
-end;
-@#
-procedure tfm_four(@!x:integer); {output four bytes to |tfm_file|}
-begin if x>=0 then tfm_out(x div three_bytes)
-else begin x:=x+@'10000000000; {use two's complement for negative values}
- x:=x+@'10000000000;
- tfm_out((x div three_bytes) + 128);
- end;
-x:=x mod three_bytes; tfm_out(x div unity);
-x:=x mod unity; tfm_out(x div @'400);
-tfm_out(x mod @'400);
-end;
-@#
-procedure tfm_qqqq(@!x:four_quarters); {output four quarterwords to |tfm_file|}
-@y
-The default definitions don't work. Why not? So use C macros.
-
-@d tfm_out(#) == put_byte (#, tfm_file)
-@d tfm_two(#) == put_2_bytes (tfm_file, #)
-@d tfm_four(#) == put_4_bytes (tfm_file, #)
-
-@p procedure tfm_qqqq(@!x:four_quarters); {output four quarterwords to |tfm_file|}
-@z
-
-@x [42.1165] print_file_name
-print_nl("Font metrics written on "); print(metric_file_name); print_char(".");
-@y
-print_nl("Font metrics written on ");
-print_file_name(0,metric_file_name,0);
-print_char(".");
-@z
-
-% [43.1182] [See TeX module 564] Reading tfm files. As a special case,
-% whenever we open a tfm file for input, we read its first byte into
-% "tfm_temp" right away.
-@x
-@d tfget==get(tfm_infile)
-@d tfbyte==tfm_infile^
-@y
-@d tfget==tfm_temp:=getc(tfm_infile)
-@d tfbyte==tfm_temp
-@z
-
-% [43.1186] [See TeX module 575] We only want `eof' on the TFM file
-% to be true if we previously had EOF, not if we're at EOF now.
-% This is like `feof', and unlike our implementation of `eof' elsewhere.
-@x
-if eof(tfm_infile) then goto bad_tfm;
-@y
-if feof(tfm_infile) then goto bad_tfm;
-@z
-
-% [43.1188] [See TeX module 563] TFM file opening.
-@x
-if cur_area="" then cur_area:=MP_font_area;
-if cur_ext="" then cur_ext:=".tfm";
-pack_cur_name;
-@y
-if cur_ext="" then cur_ext:=".tfm";
-pack_cur_name;
-@z
-
-@x [43.1195] [Unique to MP] Path selector for |a_open_in| of ps_tab_file.
-begin name_of_file:=ps_tab_name;
-if a_open_in(ps_tab_file) then
-@y
-begin
-name_length := strlen (ps_tab_name);
-name_of_file := xmalloc_array (ASCII_code, name_length+1);
-strcpy (stringcast(name_of_file+1), ps_tab_name); {copy the string}
-if a_open_in(ps_tab_file, kpse_fontmap_format) then
-@z
-
-@x [43.1198] Allow blank lines and comment lines in |ps_tab_file|.
-@ @<Read at most |lmax| characters from |ps_tab_file| into string |s|...@>=
-str_room(lmax);
-j:=lmax;
-loop @+begin if eoln(ps_tab_file) then
- fatal_error("The psfont map file is bad!");
- read(ps_tab_file,c);
- if c=' ' then goto done;
-@y
-@ If we encounter the end of line before we have started reading
-characters from |ps_tab_file|, we have found an entirely blank
-line and we skip over it. Otherwise, we abort if the line ends
-prematurely. If we encounter a comment character, we also skip
-over the line, since recent versions of \.{dvips} allow comments
-in the font map file.
-
-@<Read at most |lmax| characters from |ps_tab_file| into string |s|...@>=
-str_room(lmax);
-j:=lmax;
-loop @+begin if eoln(ps_tab_file) then
- if j=lmax then begin flush_cur_string;
- goto common_ending; {skip over blank line}
- end
- else fatal_error("The psfonts.map file is bad!");
- read(ps_tab_file,c);
- if ((c='%')or(c='*')or(c=';')or(c='#')) then begin flush_cur_string;
- goto common_ending; {skip over comment line}
- end;
- if ((c=' ')or(c=tab)) then goto done;
-@z
-
-@x [43.1199] Allow tabs as field seperators in |ps_tab_file|.
-repeat if eoln(ps_tab_file) then fatal_error("The psfont map file is bad!");
- read(ps_tab_file,c);
-until c<>' ';
-repeat decr(j);
- if j<0 then fatal_error("The psfont map file is bad!");
- append_char(xord[c]);
- if eoln(ps_tab_file) then c:=' ' @+else read(ps_tab_file,c);
-until c=' ';
-@y
-repeat if eoln(ps_tab_file) then fatal_error("The psfonts.map file is bad!");
- read(ps_tab_file,c);
-until ((c<>' ')and(c<>tab));
-repeat decr(j);
- if j<0 then fatal_error("The psfonts.map file is bad!");
- append_char(xord[c]);
- if eoln(ps_tab_file) then c:=' ' @+else read(ps_tab_file,c);
-until ((c=' ')or(c=tab));
-@z
-
-@x [44.1208] l.21341 - i18n fix
- print(" output file");
- if total_shipped>1 then print_char("s");
-@y
- print(" output ");
- if total_shipped>1 then print("files")
- else print("file");
-@z
-
-@x [44.1208] print_file_name
- print(first_file_name);
-@y
- print_file_name(0,first_file_name,0);
-@z
-@x [44.1208 print_file_name
- print(last_file_name);
-@y
- print_file_name(0,last_file_name,0);
-@z
-
-@x [45.1279] INI = VIR.
-mem_ident:=" (INIMP)";
-@y
-if ini_version then mem_ident:=" (INIMP)";
-@z
-
-@x [45.1280] Add base_engine.
-@!w: four_quarters; {four ASCII codes}
-@y
-@!w: four_quarters; {four ASCII codes}
-@!base_engine: ^text_char;
-@z
-
-@x [45.1281] Add base_engine.
-@!w: four_quarters; {four ASCII codes}
-@y
-@!w: four_quarters; {four ASCII codes}
-@!base_engine: ^text_char;
-@!dummy_xord: ASCII_code;
-@!dummy_xchr: text_char;
-@!dummy_xprn: ASCII_code;
-@z
-
-@x [45.1282] Reading and writing of `mem_file' done in C.
-@d dump_wd(#)==begin mem_file^:=#; put(mem_file);@+end
-@d dump_int(#)==begin mem_file^.int:=#; put(mem_file);@+end
-@d dump_hh(#)==begin mem_file^.hh:=#; put(mem_file);@+end
-@d dump_qqqq(#)==begin mem_file^.qqqq:=#; put(mem_file);@+end
-@y
-@z
-
-@x [45.1283]
-@d undump_wd(#)==begin get(mem_file); #:=mem_file^;@+end
-@d undump_int(#)==begin get(mem_file); #:=mem_file^.int;@+end
-@d undump_hh(#)==begin get(mem_file); #:=mem_file^.hh;@+end
-@d undump_qqqq(#)==begin get(mem_file); #:=mem_file^.qqqq;@+end
-@y
-@z
-
-@x [45.1284]
-dump_int(@$);@/
-@y
-dump_int(@"57324D50); {Web2C \MP's magic constant: "W2MP"}
-{Align engine to 4 bytes with one or more trailing NUL}
-x:=strlen(engine_name);
-base_engine:=xmalloc_array(text_char,x+4);
-strcpy(stringcast(base_engine), engine_name);
-for k:=x to x+3 do base_engine[k]:=0;
-x:=x+4-(x mod 4);
-dump_int(x);dump_things(base_engine[0], x);
-libc_free(base_engine);@/
-dump_int(@$);@/
-dump_int(main_memory);@/
-@<Dump |xord|, |xchr|, and |xprn|@>;
-@z
-
-@x [45.1285] Avoid Pascal file convention.
-x:=mem_file^.int;
-if x<>@$ then goto off_base; {check that strings are the same}
-undump_int(x);
-if x<>mem_min then goto off_base;
-undump_int(x);
-if x<>mem_top then goto off_base;
-@y
-undump_int(x);
-if x<>@"57324D50 then goto off_base; {not a base file}
-undump_int(x);
-if (x<0) or (x>256) then goto off_base; {corrupted base file}
-base_engine:=xmalloc_array(text_char, x);
-undump_things(base_engine[0], x);
-base_engine[x-1]:=0; {force string termination, just in case}
-if strcmp(engine_name, stringcast(base_engine)) then
- begin wake_up_terminal;
- wterm_ln('---! ', stringcast(name_of_file+1), ' was written by ', base_engine);
- libc_free(base_engine);
- goto off_base;
-end;
-libc_free(base_engine);
-undump_int(x);
-if x<>@$ then begin {check that strings are the same}
- wake_up_terminal;
- wterm_ln('---! ', stringcast(name_of_file+1), ' doesn''t match pool strings');
- goto off_base;
-end;
-undump_int(x);
-if x<>main_memory then goto off_base;
-@<Undump |xord|, |xchr|, and |xprn|@>;
-undump_int(x);
-if x<>mem_min then goto off_base;
-{Dynamic allocation \`a la \.{mf.ch}.}
-@+init
-if ini_version then begin
- {We allocated these at start-up, but now we need to reallocate.}
- libc_free (mem);
- libc_free (str_ref);
- libc_free (next_str);
- libc_free (str_start);
- libc_free (str_pool);
-end;
-@+tini
-undump_int(mem_top);
-if mem_max < mem_top then mem_max:=mem_top; {Use at least what we dumped.}
-if mem_min+1100>mem_top then goto off_base;
-mem_max := mem_top + extra_mem_top;
-mem:=xmalloc_array (memory_word, mem_max - mem_min + 1);
-@z
-
-@x [45.1287] String pool undumping is dynamic.
-undump_size(0)(pool_size)('string pool size')(pool_ptr);
-undump_size(0)(max_strings-1)('max strings')(max_str_ptr);
-@y
-undump_size(0)(sup_pool_size-pool_free)('string pool size')(pool_ptr);
-if pool_size < pool_ptr + pool_free then
- pool_size := pool_ptr+pool_free;
-undump_size(0)(sup_max_strings)('max strings')(max_str_ptr);
-@/
-str_ref:=xmalloc_array (str_ref_type, max_strings);
-next_str:=xmalloc_array (str_number, max_strings);
-str_start:=xmalloc_array (pool_pointer, max_strings);
-str_pool:=xmalloc_array (pool_ASCII_code, pool_size);
-@z
-
-@x [45.1293] l.22667 - Allow command line to override dumped value.
-undump(batch_mode)(error_stop_mode)(interaction);
-@y
-undump(batch_mode)(error_stop_mode)(interaction);
-if interaction_option<>unspecified_mode then interaction:=interaction_option;
-@z
-
-@x [45.1293] eof is like feof here.
-undump_int(x);@+if (x<>69073)or eof(mem_file) then goto off_base
-@y
-undump_int(x);@+if (x<>69073)or feof(mem_file) then goto off_base
-@z
-
-@x [45.1294] Eliminate probably-wrong word `preloaded' from mem_idents.
-print(" (preloaded mem="); print(job_name); print_char(" ");
-print_int(round_unscaled(internal[year]) mod 100); print_char(".");
-@y
-print(" (mem="); print(job_name); print_char(" ");
-print_int(round_unscaled(internal[year])); print_char(".");
-@z
-
-@x [46.1298] Dynamic allocation.
-@p begin @!{|start_here|}
-@y
-@d const_chk(#) == begin if # < inf@&# then # := inf@&# else
- if # > sup@&# then # := sup@&# end
-{|setup_bound_var| stuff duplicated in \.{tex.ch}.}
-@d setup_bound_var(#) == bound_default := #; setup_bound_var_end
-@d setup_bound_var_end(#) == bound_name := #; setup_bound_var_end_end
-@d setup_bound_var_end_end(#) ==
- setup_bound_variable (address_of (#), bound_name, bound_default);
-
-@p begin @!{|start_here|}
- {See comments in \.{tex.ch} for why the name has to be duplicated.}
- setup_bound_var (250000)('main_memory')(main_memory);
- {|memory_word|s for |mem| in \.{INIMP}}
- setup_bound_var (0)('extra_mem_top')(extra_mem_top);
- {increase high mem in \.{VIRMP}}
- setup_bound_var (100000)('pool_size')(pool_size);
- setup_bound_var (75000)('string_vacancies')(string_vacancies);
- setup_bound_var (3000)('buf_size')(buf_size);
- setup_bound_var (2000)('path_size')(path_size);
- setup_bound_var (5000)('pool_free')(pool_free); {min pool avail after fmt}
- setup_bound_var (15000)('max_strings')(max_strings);
- setup_bound_var (79)('error_line')(error_line);
- setup_bound_var (50)('half_error_line')(half_error_line);
- setup_bound_var (79)('max_print_line')(max_print_line);
- if error_line > ssup_error_line then error_line := ssup_error_line;
-
- const_chk (main_memory);
-@+init
- if ini_version then
- extra_mem_top := 0;
-@+tini
- if extra_mem_top>sup_main_memory then extra_mem_top:=sup_main_memory;
- mem_top := mem_min + main_memory - 1;
- mem_max := mem_top;
-
- const_chk (pool_size);
- const_chk (string_vacancies);
- const_chk (buf_size);
- const_chk (path_size);
- const_chk (pool_free);
- const_chk (max_strings);
-
- buffer:=xmalloc_array (ASCII_code, buf_size);
- delta_x:=xmalloc_array (scaled, path_size);
- delta_y:=xmalloc_array (scaled, path_size);
- delta:=xmalloc_array (scaled, path_size);
- psi:=xmalloc_array (angle, path_size);
- theta:=xmalloc_array (angle, path_size);
- uu:=xmalloc_array (fraction, path_size);
- vv:=xmalloc_array (angle, path_size);
- ww:=xmalloc_array (fraction, path_size);
- source_filename_stack:=xmalloc_array (str_number, max_in_open);
- full_source_filename_stack:=xmalloc_array (str_number, max_in_open);
-
-@+init
-if ini_version then begin
- mem:=xmalloc_array (memory_word, mem_top - mem_min + 1);
-
- str_ref:=xmalloc_array (str_ref_type, max_strings);
- next_str:=xmalloc_array (str_number, max_strings);
- str_start:=xmalloc_array (pool_pointer, max_strings);
- str_pool:=xmalloc_array (pool_ASCII_code, pool_size);
-end;
-@+tini
-@z
-
-@x [46.1298] Only do get_strings_started etc. if ini.
-@!init if not get_strings_started then goto final_end;
-init_tab; {initialize the tables}
-init_prim; {call |primitive| for each primitive}
-init_str_use:=str_ptr; init_pool_ptr:=pool_ptr;@/
-max_str_ptr:=str_ptr; max_pool_ptr:=pool_ptr;
-fix_date_and_time;
-@y
-@!init if ini_version then begin
-if not get_strings_started then goto final_end;
-init_tab; {initialize the tables}
-init_prim; {call |primitive| for each primitive}
-init_str_use:=str_ptr; init_pool_ptr:=pool_ptr;@/
-max_str_ptr:=str_ptr; max_pool_ptr:=pool_ptr;
-fix_date_and_time;
-end;
-@z
-
-@x [46.1298] Set internal[prologues] in troff mode.
-history:=spotless; {ready to go!}
-@y
-history:=spotless; {ready to go!}
-if troff_mode then begin
- internal[gtroffmode]:=unity;
- internal[prologues]:=unity;
-end;
-@z
-
-@x [46.1298] Call do_final_end.
-end_of_MP: close_files_and_terminate;
-final_end: ready_already:=0;
-@y
-close_files_and_terminate;
-final_end: do_final_end;
-@z
-
-@x [46.1299] Print new line before termination; maybe switch to editor.
- print(log_name); print_char(".");
- end;
- end;
-@y
- print_file_name(0,log_name,0); print_char(".");
- end;
- end;
-print_ln;
-if (edit_name_start<>0) and (interaction>batch_mode) then
- call_edit(str_pool,edit_name_start,edit_name_length,edit_line);
-@z
-
-@x [46.1304] (final_cleanup) Only do dump if ini.
- begin @!init store_mem_file; return;@+tini@/
-@y
- begin @!init if ini_version then begin store_mem_file; return;end;@+tini@/
-@z
-
-@x [46.1306] l.22937 - Handle %&mem line
-if (mem_ident=0)or(buffer[loc]="&") then
-@y
-if (mem_ident=0)or(buffer[loc]="&")or dump_line then
-@z
-
-@x [46.1307] l.23004
-sys_random_seed := (internal[time] div unity)+internal[day];@/
-@y
-sys_random_seed := get_random_seed;@/
-@z
-
-@x [47.1307] Change read of integer.
- read(term_in,m);
- if m<0 then return
- else if m=0 then
- begin goto breakpoint;@\ {go to every label at least once}
- breakpoint: m:=0; @{'BREAKPOINT'@}@\
- end
- else begin read(term_in,n);
-@y
- m:=input_int (stdin);
- if m<0 then return
- else if m=0 then
- begin goto breakpoint;@\ {go to every label at least once}
- breakpoint: m:=0; @{'BREAKPOINT'@}@\
- end
- else begin n:=input_int (stdin);
-@z
-
-@x [47.1308]
-13: begin read(term_in,l); print_cmd_mod(n,l);
-@y
-13: begin l:=input_int (stdin); print_cmd_mod(n,l);
-@z
-
-@x [48.1309] Add editor-switch variable to globals.
-This section should be replaced, if necessary, by any special
-modification of the program
-that are necessary to make \MP\ work at a particular installation.
-It is usually best to design your change file so that all changes to
-previous sections preserve the section numbering; then everybody's version
-will be consistent with the published program. More extensive changes,
-which introduce new sections, can be inserted here; then only the index
-itself will get a new section number.
-@^system dependencies@>
-@y
-Here are the variables used to hold ``switch-to-editor'' information.
-@^system dependencies@>
-
-@<Global...@>=
-@!edit_name_start: pool_pointer;
-@!edit_name_length,@!edit_line: integer;
-@!xprn: array[ASCII_code] of ASCII_code; {use \.{\^\^} notation?}
-@!stop_at_space: boolean; {whether |more_name| returns false for space}
-
-@ The |edit_name_start| will be set to point into |str_pool| somewhere after
-its beginning if \MP\ is supposed to switch to an editor on exit.
-
-@<Set init...@>=
-edit_name_start:=0;
-stop_at_space:=true;
-
-@ Dumping the |xord|, |xchr|, and |xprn| arrays. We dump these always
-in the format, so a TCX file loaded during format creation can set a
-default for users of the format.
-
-@<Dump |xord|, |xchr|, and |xprn|@>=
-dump_things(xord[0], 256);
-dump_things(xchr[0], 256);
-dump_things(xprn[0], 256);
-
-@ Undumping the |xord|, |xchr|, and |xprn| arrays. This code is more
-complicated, because we want to ensure that a TCX file specified on
-the command line will override whatever is in the format. Since the
-tcx file has already been loaded, that implies throwing away the data
-in the format. Also, if no |translate_filename| is given, but
-|eight_bit_p| is set we have to make all characters printable.
-
-@<Undump |xord|, |xchr|, and |xprn|@>=
-if translate_filename then begin
- for k:=0 to 255 do undump_things(dummy_xord, 1);
- for k:=0 to 255 do undump_things(dummy_xchr, 1);
- for k:=0 to 255 do undump_things(dummy_xprn, 1);
- end
-else begin
- undump_things(xord[0], 256);
- undump_things(xchr[0], 256);
- undump_things(xprn[0], 256);
- if eight_bit_p then
- for k:=0 to 255 do
- xprn[k]:=1;
-end;
-
-@ Web2c is deficient, and can only translate pointers to a type
-identifier, not a general type. Easier, if more annoying, to introduce
-this extra definition than to fix Web2c.
-
-@<Types...@> =
-@!str_ref_type = 0..max_str_ref;
-@z