%%%  WEB Change File for BibTeX (Win32 version)
%%%  Time-stamp: "97/02/26 18:09:04 cschenk"
%%%
%%%  Copyright (C) 1991, 92, 93, 94, 95, 96, 97
%%%	Christian Schenk  <cschenk@berlin.snafu.de>
%%%
%%%  This file is part of MiKTeX.
%%%
%%%  MiKTeX is free software; you can redistribute it and/or
%%%  modify it under the terms of the GNU General Public License as
%%%  published by the Free Software Foundation; either version 2, or (at
%%%  your option) any later version.
%%%  
%%%  MiKTeX is distributed in the hope that it will be useful, but
%%%  WITHOUT ANY WARRANTY; without even the implied warranty of
%%%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
%%%  General Public License for more details.
%%%  
%%%  You should have received a copy of the GNU General Public License
%%%  along with MiKTeX; if not, write to the Free Software
%%%  Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
%%%  USA.

%%%  @todo
%%%  Increase some BibTeX constants (Wolfgang Christen
%%%  @code{<christen@@chemsg1.tau.ac.il>}):
%%%
%%%  @example
%%%  Hash_Prime:    30,011
%%%  Hash_Size:     35,000
%%%  Max_Cites:      7,500
%%%  Max_Ent_Ints:   7,500 
%%%  Max_Ent_Strs:  10,000
%%%  Max_Fields:   125,000
%%%  Max_Strings:   30,000
%%%  Pool_Size:    750,000
%%%  Wiz_Fn_Space:  10,000
%%%  @end example
%%%  @end todo

%% **     2  ******************************************************************

@x
@d term_out == tty
@d term_in == tty
@y
@d term_out == output
@d term_in == i@&nput
@z

%% **     9  ******************************************************************

@x
@d close_up_shop=9998           {jump here after fatal errors}
@d exit_program=9999            {jump here if we couldn't even get started}
@y
@d close_up_shop=9998           {jump here after fatal errors}
@d exit_program=9999            {jump here if we couldn't even get started}
@d goto_close_up_shop==c4p_longjmp(clean_jmpbuf,1)
@d goto_exit_program==c4p_longjmp(exit_jmpbuf,1)
@z

%% **    10  ******************************************************************

@x
@<Procedures and functions for about everything@>@;
@<The procedure |initialize|@>
@y
@<External C routines@>@;
@<Procedures and functions for about everything@>@;
@<The procedure |initialize|@>
@z

@x
begin
initialize;
print_ln(banner);@/
@y
begin
@<Prepare jump buffers@>@;
initialize;
print(banner); miktex_banner(output); write_ln;@/
@z

%% **    13  ******************************************************************

@x
    goto exit_program;
@y
    goto_exit_program;
@z

%% **    14  ******************************************************************

@x
@<Constants in the outer block@>=
@!buf_size=1000; {maximum number of characters in an input line (or string)}
@!min_print_line=3; {minimum \.{.bbl} line length: must be |>=3|}
@!max_print_line=79; {the maximum: must be |>min_print_line| and |<buf_size|}
@!aux_stack_size=20; {maximum number of simultaneous open \.{.aux} files}
@!max_bib_files=20; {maximum number of \.{.bib} files allowed}
@!pool_size=65000; {maximum number of characters in strings}
@!max_strings=4000; {maximum number of strings, including pre-defined;
                                                        must be |<=hash_size|}
@!max_cites=750; {maximum number of distinct cite keys; must be
                                                        |<=max_strings|}
@!min_crossrefs=2; {minimum number of cross-refs required for automatic
                                                        |cite_list| inclusion}
@!wiz_fn_space=3000; {maximum amount of |wiz_defined|-function space}
@!single_fn_space=100; {maximum amount for a single |wiz_defined|-function}
@!max_ent_ints=3000; {maximum number of |int_entry_var|s
                                        (entries $\times$ |int_entry_var|s)}
@!max_ent_strs=3000; {maximum number of |str_entry_var|s
                                        (entries $\times$ |str_entry_var|s)}
@!ent_str_size=100; {maximum size of a |str_entry_var|; must be |<=buf_size|}
@!glob_str_size=1000; {maximum size of a |str_global_var|;
                                                        must be |<=buf_size|}
@!max_fields=17250; {maximum number of fields (entries $\times$ fields,
                                        about |23*max_cites| for consistency)}
@!lit_stk_size=100; {maximum number of literal functions on the stack}


@
@^space savings@>
@^system dependencies@>
These parameters can also be changed at compile time, but they're
needed to define some \.{WEB} numeric macros so they must be so
defined themselves.

@d hash_size=5000       {must be |>= max_strings| and |>= hash_prime|}
@d hash_prime=4253      {a prime number about 85\% of |hash_size| and |>= 128|
                                                and |< @t$2^{14}-2^6$@>|}
@d file_name_size=40    {file names shouldn't be longer than this}
@d max_glob_strs=10     {maximum number of |str_global_var| names}
@d max_glb_str_minus_1 = max_glob_strs-1  {to avoid wasting a |str_global_var|}
@y
@<Constants in the outer block@>=
@!buf_size=4000; {maximum number of characters in an input line (or string)}
@!min_print_line=3; {minimum \.{.bbl} line length: must be |>=3|}
@!max_print_line=79; {the maximum: must be |>min_print_line| and |<buf_size|}
@!aux_stack_size=20; {maximum number of simultaneous open \.{.aux} files}
@!max_bib_files=1200; {maximum number of \.{.bib} files allowed}
@!pool_size=657890; {maximum number of characters in strings}
@!max_strings=4000; {maximum number of strings, including pre-defined;
                                                        must be |<=hash_size|}
@!max_cites=750; {maximum number of distinct cite keys; must be
                                                        |<=max_strings|}
@!min_crossrefs=2; {minimum number of cross-refs required for automatic
                                                        |cite_list| inclusion}
@!wiz_fn_space=3000; {maximum amount of |wiz_defined|-function space}
@!single_fn_space=100; {maximum amount for a single |wiz_defined|-function}
@!max_ent_ints=28000; {maximum number of |int_entry_var|s
                                        (entries $\times$ |int_entry_var|s)}
@!max_ent_strs=12000; {maximum number of |str_entry_var|s
                                        (entries $\times$ |str_entry_var|s)}
@!ent_str_size=100; {maximum size of a |str_entry_var|; must be |<=buf_size|}
@!glob_str_size=1000; {maximum size of a |str_global_var|;
                                                        must be |<=buf_size|}
@!max_fields=80000; {maximum number of fields (entries $\times$ fields,
                                        about |23*max_cites| for consistency)}
@!lit_stk_size=100; {maximum number of literal functions on the stack}


@
@^space savings@>
@^system dependencies@>
These parameters can also be changed at compile time, but they're
needed to define some \.{WEB} numeric macros so they must be so
defined themselves.

@d hash_size=20000       {must be |>= max_strings| and |>= hash_prime|}
@d hash_prime=16319      {a prime number about 85\% of |hash_size| and |>= 128|
                                                and |< @t$2^{14}-2^6$@>|}
@d file_name_size=260   {file names shouldn't be longer than this}
@d fil_name_size=261
@d max_glob_strs=10     {maximum number of |str_global_var| names}
@d max_glb_str_minus_1 = max_glob_strs-1  {to avoid wasting a |str_global_var|}
@z

%% **    22  ******************************************************************

@x
@!ASCII_code=0..127;    {seven-bit numbers}
@y
@!ASCII_code=0..255;    {eight-bit numbers}
@z

%% **    23  ******************************************************************

@x
@d text_char == char    {the data type of characters in text files}
@d first_text_char=0    {ordinal number of the smallest element of |text_char|}
@d last_text_char=127   {ordinal number of the largest element of |text_char|}
@y
@d text_char == ASCII_code    {the data type of characters in text files}
@d first_text_char=0    {ordinal number of the smallest element of |text_char|}
@d last_text_char=255   {ordinal number of the largest element of |text_char|}
@z

%% **    27  ******************************************************************

@x
for i:=1 to @'37 do xchr[i]:=' ';
xchr[tab]:=chr(tab);
@y
for i:=1 to @'37 do xchr[i]:=chr(i);
for i:=@'177 to @'377 do xchr[i]:=chr(i);
xchr[tab]:=chr(tab);
@z

%% **    28  ******************************************************************

@x
for i:=first_text_char to last_text_char do xord[chr(i)]:=invalid_code;
for i:=1 to @'176 do xord[xchr[i]]:=i;
@y
for i:=first_text_char to last_text_char do xord[xchr[i]]:=i;
@z

%% **    37  ******************************************************************

@x
@!name_of_file:packed array[1..file_name_size] of char;
                         {on some systems this is a \&{record} variable}
@!name_length:0..file_name_size;
  {this many characters are relevant in |name_of_file| (the rest are blank)}
@!name_ptr:0..file_name_size+1;         {index variable into |name_of_file|}
@y
@!name_of_file:packed array[1..fil_name_size] of char;
                         {on some systems this is a \&{record} variable}
@!name_length:0..file_name_size;
  {this many characters are relevant in |name_of_file| (the rest are blank)}
@!name_ptr:0..file_name_size+1;         {index variable into |name_of_file|}
@z

%% **    38  ******************************************************************

@x
@^system dependencies@>
@:PASCAL H}{\ph@>
The \ph\ compiler with which the present version of \TeX\ was prepared has
extended 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
\TeX\ to undertake appropriate corrective action.
@y
We can use the routine |@!c4p_try_fopen()| for file opening:
$$\vbox{\halign{#\hfil\qquad&#\hfil\cr
|c4p_try_fopen(f,@t\\{name}@>,@!c4p_r_mode);|&input;\cr
|c4p_try_fopen(f,@t\\{name}@>,@!c4p_w_mode);|&output;\cr
|c4p_try_fopen(f,@t\\{name}@>,@!c4p_rb_mode);|&binary input;\cr
|c4p_try_fopen(f,@t\\{name}@>,@!c4p_wb_mode);|&binary output.\cr}}$$
The `\\{name}' parameter, which is of type `{\bf packed array
$[\langle\\{any}\rangle]$ of \\{char}}', stands for the name of
the external file that is being opened for input or output. It must
be zero terminated.
@^system dependencies@>
@z

@x
@d reset_OK(#)==erstat(#)=0
@d rewrite_OK(#)==erstat(#)=0

@<Procedures and functions for file-system interacting@>=
function erstat(var f:file):integer; extern;    {in the runtime library}
@#@t\2@>
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;
@y
@d a_open_out(#)==c4p_try_fopen(#,name_of_file,c4p_w_mode)
  {open a text file for output}

@<Procedures and functions for file-system interacting@>=
function a_open_in(var f:alpha_file):boolean;
  {open a text file for input}
begin if not mt_open_input_file(f) then a_open_in:=false
   else begin a_open_in:=true; reset(f); end;
end;
@z

%% **    39  ******************************************************************

@x
Files can be closed with the \ph\ routine `|close(f)|', which 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.

@<Procedures and functions for file-system interacting@>=
procedure a_close(var f:alpha_file);            {close a text file}
begin close(f);
end;
@y
Files can be closed with the routine `|@!c4p_fclose(f)|', which
@^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.

@d a_close(#)==c4p_fclose(#) {close a text file}
@z

%% **    44  ******************************************************************


@x
                print_ln(#:0);
                goto close_up_shop;
@y
                print_ln(#:0);
                goto_close_up_shop;
@z

%% **    45  ******************************************************************

@x
                 print_confusion;
                 goto close_up_shop;
@y
                 print_confusion;
                 goto_close_up_shop;
@z

%% **    47  ******************************************************************

@x
  while (not eoln(f)) do
@y
  while (not eoln(f) and not eof(f)) do
@z

%% **    60  ******************************************************************

@x
while (name_ptr <= file_name_size) do   {pad with blanks}
    begin
    name_of_file[name_ptr] := ' ';
    incr(name_ptr);
    end;
end;
@y
while (name_ptr <= fil_name_size) do   {pad with 0 bytes}
    begin
    name_of_file[name_ptr] := chr(0);
    incr(name_ptr);
    end;
end;
@z

%% **   100  ******************************************************************

@x
check_cmnd_line := false;                       {many systems will change this}
@y
if (c4p_argc > 1) then check_cmnd_line := true else check_cmnd_line := false;
@z

%% **   102  ******************************************************************

@x
do_nothing;             {the ``default system'' doesn't use the command line}
@y
c4p_strcpy(name_of_file,c4p_argv[1]);
aux_name_length:=c4p_strlen(name_of_file);
@z

%% **   109  ******************************************************************

@x
@d aux_done=31          {go here when finished with the \.{.aux} files}
@y
@d aux_done=31          {go here when finished with the \.{.aux} files}
@d goto_aux_done==c4p_longjmp(auxdon_jmpbuf,1)
@z

%% **   141  ******************************************************************

@x
while (name_ptr <= file_name_size) do   {pad with blanks}
    begin
    name_of_file[name_ptr] := ' ';
    incr(name_ptr);
    end;
@y
while (name_ptr <= file_name_size) do   {pad with 0 bytes}
    begin
    name_of_file[name_ptr] := chr(0);
    incr(name_ptr);
    end;
@z

%% **   142  ******************************************************************

@x
if (aux_ptr=0) then
    goto aux_done
@y
if (aux_ptr=0) then
    goto_aux_done
@z

%% **   146  ******************************************************************

@x
@d bst_done=32          {go here when finished with the \.{.bst} file}
@d no_bst_file=9932     {go here when skipping the \.{.bst} file}
@y
@d bst_done=32          {go here when finished with the \.{.bst} file}
@d no_bst_file=9932     {go here when skipping the \.{.bst} file}
@d goto_bst_done==c4p_longjmp(bstdon_jmpbuf,1)
@d goto_no_bst_file==c4p_longjmp(nobst_jmpbuf,1)
@z

%% **   149  ******************************************************************

@x
    if (not input_ln(bst_file)) then    {or the end of the file}
        goto bst_done
@y
    if (not input_ln(bst_file)) then    {or the end of the file}
        goto_bst_done
@z

%% **   151  ******************************************************************

@x
if (bst_str = 0) then   {there's no \.{.bst} file to read}
    goto no_bst_file;   {this is a |goto| so that |bst_done| is not in a block}
@y
if (bst_str = 0) then   {there's no \.{.bst} file to read}
    goto_no_bst_file;   {this is a |goto| so that |bst_done| is not in a block}
@z

@x
    if (not eat_bst_white_space) then   {the end of the \.{.bst} file}
        goto bst_done;
@y
    if (not eat_bst_white_space) then   {the end of the \.{.bst} file}
        goto_bst_done;
@z

%% **   467  ******************************************************************

@x
which introduce new sections, can be inserted here; then only the index
itself will get a new section number.
@y
which introduce new sections, can be inserted here; then only the index
itself will get a new section number.

@ @<External C routines@>=

function mt_open_input_file (var f:alpha_file) : boolean; forward;
procedure miktex_banner (var f:alpha_file); forward;

@ @<Globals in the outer block@>=
@!clean_jmpbuf, @!exit_jmpbuf, @!auxdon_jmpbuf, @!nobst_jmpbuf,
   @!bstdon_jmpbuf : c4p_jmp_buf;

@ @<Prepare jump buffers@>=
if c4p_setjmp (clean_jmpbuf) <> 0 then goto close_up_shop;
if c4p_setjmp (exit_jmpbuf) <> 0 then goto exit_program;
if c4p_setjmp (auxdon_jmpbuf) <> 0 then goto aux_done;
if c4p_setjmp (bstdon_jmpbuf) <> 0 then goto bst_done;
if c4p_setjmp (nobst_jmpbuf) <> 0 then goto no_bst_file;
@z
