$Id$
Second-level change file for Metafont compilation on RISC OS
Line numbers refer to either mf.web or mf.ch from Web2c 7.2 or their merge.

Changes are:
	Setting filetypes on all openout calls.
	Throwback
	Filename parsing.
	output_mode and -desktop flag.
	max_strings, string_vacancies and pool_size dynamical from cnf file.


max_strings, string_vacancies and pool_size are not constants.
@x 351
@!max_strings=7500; {maximum number of strings; must not exceed |max_halfword|}
@!string_vacancies=74000; {the minimum number of characters that should be
  available for the user's identifier names and strings,
  after \MF's own error messages are stored}
@!pool_size=100000; {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 \MF's own strings, which is currently about 22000}
@y
@!inf_max_strings = 2000;
@!sup_max_strings = 32767; {max value allowed by \.{TANGLE}}

@!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

max_strings, string_vacancies, pool_size and pool_free are variables.
@x 426
@!gf_buf_size:integer; {size of the output buffer, must be a multiple of 8}
@y
@!gf_buf_size:integer; {size of the output buffer, must be a multiple of 8}
@!max_strings:integer; {maximum number of strings; must not exceed |max_halfword|}
@!string_vacancies:integer; {the minimum number of characters that should be
  available for the user's identifier names and strings,
  after \MF's own error messages are stored}
@!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 \MF's own strings, which is currently about 22000}
@!pool_free:integer;{minimum pool space free after format loaded}
@z

str_pool and str_start are dynamically allocated.
@x 1001
@!str_pool:packed array[pool_pointer] of packed_ASCII_code; {the characters}
@!str_start : array[str_number] of pool_pointer; {the starting pointers}
@y
@!str_pool:^packed_ASCII_code; {the characters}
@!str_start : ^pool_pointer; {the starting pointers}
@z

And so is str_ref. |str_ref_type| is defined in the last section.
@x
@!str_ref:array[str_number] of 0..max_str_ref;
@y
@!str_ref:^str_ref_type;
@z

Throwback. We direct output to the throwback buffer.
@x 1369
procedure print_visible_char(@!s:ASCII_code); {prints a single character}
begin case selector of
@y
procedure print_visible_char(@!s:ASCII_code); {prints a single character}
begin throwback_char(xchr[s]);
case selector of
@z

print_err enables the logging.
@x 1568
  print_nl("! "); print(#);
@y
  print_nl("! "); throwback_start; print(#);
@z

And error stops it and sends the message.
@x 1713
print_char("."); show_context;
@y
throwback_stop; print_char("."); show_context;
{ |throwback_xsend| is called like |call_edit| }
if throwback_flag and (file_ptr>0) then
  throwback_xsend(str_pool, str_start[input_stack[file_ptr].name_field],
	length(input_stack[file_ptr].name_field), line);
@z

We provide a "T" option on error stops
@x 1753
"E": if file_ptr>0 then
@y
"T": if (not throwback_flag) and (file_ptr>0) then begin
       throwback_flag:=true; { enable throwback }
       throwback_xsend(str_pool, str_start[edit_file.name_field],
		length(edit_file.name_field), line);
       { and send the current message }
       interaction:=nonstop_mode;
       return;
     end;
"E": if file_ptr>0 then
@z

@x 1775
if file_ptr>0 then print("E to edit your file,");
@y
if file_ptr>0 then begin
  print("E to edit your file,");
  if not throwback_flag then
    print_nl("T to start throwback and run without stopping,");
end;
@z

--- Filename parsing ---
We accept '.' or ':' as directory separator and '.' or '/' as extension
separator. This will fail for Unix-style names, but that is not
important since the filename is rescanned after path searching which
will translate it to RISC OS style.

These changes are virtually identical in TeX and Metafont

The last '.' is not always the area_delimiter
@x [15545] web.mf:15545
@!area_delimiter:pool_pointer; {the most recent `\./', if any}
@!ext_delimiter:pool_pointer; {the most recent `\..', if any}
@y
@!area_delimiter:pool_pointer; {the most recent `\..' before the extension, if any}
@!ext_delimiter:pool_pointer; {the most recent `\..' or `\./', if any}
@!area_delimiter2:pool_pointer; {the last `\..', if any}
@z

|begin_name|: Initialise |area_delimiter2| also.
@x [15560] web.mf:15560
begin area_delimiter:=0; ext_delimiter:=0;
@y
begin area_delimiter:=0; ext_delimiter:=0; area_delimiter2:=0;
@z

|more_name|: |DIR_SEP| can be the extension delimiter
@x [15569] web.mf:15569
else  begin if IS_DIR_SEP (c) then
    begin area_delimiter:=pool_ptr; ext_delimiter:=0;
    end
  else if c="." then ext_delimiter:=pool_ptr;
@y
else  begin if IS_DIR_SEP(c) then
    begin ext_delimiter:=pool_ptr;
      area_delimiter:=area_delimiter2;
      area_delimiter2:=pool_ptr;
    end
  else if c="/" then
    begin ext_delimiter:=pool_ptr;
      area_delimiter:=area_delimiter2;
    end;
@z

Logfiles are type Text
@x [15783]
while not a_open_out(log_file) do @<Try to get a different log file name@>;
@y
while not a_open_out(log_file, riscos_TEXT_type) do
  @<Try to get a different log file name@>;
@z

GF files are type GF.
@x [15835]
  while not b_open_out(gf_file) do
@y
  while not b_open_out(gf_file, riscos_GF_type) do
@z

After opening the first input file, we set the output_mode according to its
extension conventions. We also set the prefix if desktop_flag is set.
@x [15875]
  begin job_name:=cur_name;
@y
  begin job_name:=cur_name;
    riscos_set_output_mode (name_of_file + 1);
    if riscos_desktop_flag then
      riscos_initialise_prefix (name_of_file + 1);
@z

TFM file are type TFM
@x [21512]
while not b_open_out(tfm_file) do
@y
while not b_open_out(tfm_file, riscos_TFM_type) do
@z


str_ref, str_start, str_pool are also dynamically allocated.
@x 22521
  libc_free (mem);
@y
  libc_free (mem);
  libc_free (str_ref);
  libc_free (str_start);
  libc_free (str_pool);
@z

@x
undump_size(0)(pool_size)('string pool size')(pool_ptr);
undump_size(0)(max_strings)('max strings')(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')(str_ptr);
@/
xmalloc_array (str_ref, max_strings);
xmalloc_array (str_start, max_strings);
xmalloc_array (str_pool, pool_size);
@z

Base files are type Data
@x [22678]
while not w_open_out(base_file) do
@y
while not w_open_out(base_file, riscos_DUMP_type) do
@z

More dynamic values, max_strings, pool_size, string_vacancies, pool_free
@x 22767
  setup_bound_var (16384)('gf_buf_size')(gf_buf_size);
@y
  setup_bound_var (16384)('gf_buf_size')(gf_buf_size);
  setup_bound_var (100000)('pool_size')(pool_size);
  setup_bound_var (74000)('string_vacancies')(string_vacancies);
  setup_bound_var (5000)('pool_free')(pool_free); {min pool avail after fmt}
  setup_bound_var (7500)('max_strings')(max_strings);

  const_chk (pool_size);
  const_chk (string_vacancies);
  const_chk (pool_free);
  const_chk (max_strings);
@z

Allocate the arrays if ini_version
@x 22778
  xmalloc_array (mem, mem_top - mem_min);
@y
  xmalloc_array (mem, mem_top - mem_min);
  xmalloc_array (str_ref, max_strings);
  xmalloc_array (str_start, max_strings);
  xmalloc_array (str_pool, pool_size);
@z

@x 23064
edit_name_start:=0;
@y
edit_name_start:=0;

@ 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
