This change file is for the OpenVMS version of BibTeX Copyright 1990 Don Hosek DO NOT MODIFY THIS FILE. If you must make changes, use a different name and alter the banner string so that it no longer has PD VMS in it. --Character Reference------------------------------------------------- Upper case letters: ABCDEFGHIJKLMNOPQRSTUVWXYZ Lower case letters: abcdefghijklmnopqrstuvwxyz Digits: 0123456789 Square, curly, angle braces, parentheses: [] {} <> () Backslash, slash, vertical bar: \ / | Punctuation: . ? ! , : ; Underscore, hyphen, equals sign: _ - = Quotes--right left double: ' ` " "at", "number" "dollar", "percent", "and": @ # $ % & "hat", "star", "plus", "tilde": ^ * + ~ ----------------------------------------------------------------------- 12-Feb-88 Modified for Version .99b by Jerry Leichter (1.0) 15-Apr-88 Modified for Version .99c by Jerry Leichter 27-May-88 Fixed some spelling errors and typos that showed up when the code was woven. Added support for specifying the file name on the command line. Nelson Beebe. (1.1) 2-Dec-88 Got rid of all of the tabs so that it not only matches our copy of the WEB, but so that it can be stored readily on a non-ascii machine or be sent via e-mail with little fear of corruption. The beginning of the so-called "HMC implementation." Don Hosek. (1.2) 3-Dec-88 Fixed error on text_char definitions. Don Hosek. (1.3) 5-Dec thru 8-Dec-88 Modified program to be called through the CLI. The qualifiers /STAT, and /TRACE are added. Changed Vax to VAX because it bugged Heather. Removed line endings because they shouldn't have been there. All debug..gubed stuff is removed because it's not used very much and is better dealt with using VMS's debugger facility. -dh (1.4) 10-NOV-89 Mostly cosmetic changes to the change file including modification of the format of the banner line and inclusion of the CLD file in this file. Note that tabs in the master file have been globally replaced with two spaces (which is the standard practice with the other TeXware). -dh (1.5) 27-MAY-90 Added character reference table; fixed problem with WEAVE 4.1 and this program; added mising \def of \pascal; got values for TeX and Bib input paths from /TEXINPUTS and /BIBINPUTS qualifiers. -dh (1.6) 8-JUN-90 Minor change to CLD file since BIBINPUTS should be set to TEX_BIB by default. (1.6a) 28-Apr-91 Fixed bug in behaviour of BIBINPUTS that had been lurking about but never fixed. Reported with fix by Tony McGrath (1.6b) 09-Feb-94 Christian Spieler (SPC): Adapted change file for OpenVMS(AXP). The calling interface for the external CLI support routines has been modified according to the implementation in VMS TeX and VMS MF. 26-Nov-94 Christian Spieler (SPC): Removed \pascal defininition, \PASCAL is used consistently. New features: - Revised the command line handling: Added the ability to parse the command line internally, when invoked as a foreign command. - Apply wildcard expansion to all input file specifications. This allows to use wildcards in the /TEXINPUTS and /BIBINPUTS search lists, and implements the "subdirectory searching" facility, as recommended by the TDS (standard TeX Directory Structure) proposal. - Incremented version number to [PD VMS 1.7] 29-Nov-94 Christian Spieler (SPC): Take care of possible directory part in file specification on the command line. (Do not recognize '.'s before a trailing ']'.) 25-Mar-95 Christian Spieler (SPC) [PD VMS 1.8]: - Changed the `internal char' type |ASCII_code| to support 8-bit numbers, to match the change `TeX 2.x -> TeX 3.x'. - Increased the size of various array limits. 28-Mar-95 Christian Spieler (SPC) [PD VMS 1.8]: - Allow modification of |min_crossrefs| constant at runtime. (Change was inspired by the Web2C port of BibTeX.) - Change name of /TEXINPUTS qualifier into /BSTINPUTS. ------BIBTEX.CLD--------------------------------------------------------------- ! CLD file for BibTeX. ! (HMC Implementation 8-June-1990) ! Don Hosek module bibtex_cli define verb BIBTEX image TEX_EXE:BIBTEX.EXE parameter p1,label=filespec,prompt="Input file",value(type=$infile) qualifier STATS, ! default is /NOSTATS negatable, placement=global qualifier TRACE, ! default is /NOTRACE negatable, placement=global qualifier BSTINPUTS, placement=global, default, nonnegatable, value(default="TEX_BST:") qualifier BIBINPUTS, placement=global, default, nonnegatable, value(default="TEX_BIB:") qualifier MIN_CROSSREFS, placement=global, nonnegatable, value(required, type=$number) ------end of BIBTEX.CLD-------------------------------------------------------- {Section 0} <<<<>>>> @x [0] (AMS) Avoid dropped E in identifiers other than TeX \def\drop{\kern-.1667em\lower.5ex\hbox{E}\kern-.125em} % middle of TeX \catcode`E=13 \uppercase{\def E{e}} \def\\#1{\hbox{\let E=\drop\it#1\/\kern.05em}} % italic type for identifiers @y \def\drop{\kern-.1667em\lower.5ex\hbox{E}\kern-.125em} % middle of TeX \def\cape#1{\if X#1\drop\else E\fi#1} % other E's in identifiers \begingroup \catcode`E=13 \uppercase{\gdef E{e}} \gdef\\#1{\hbox{\catcode`E=13 \let E=\cape \it#1\/\kern.05em}} % italic type for identifiers \endgroup @z {Section 0} @x \def\title{\BibTeX\ } @y \let\maybe=\iffalse \maybe \def\title{\BibTeX\ for OpenVMS; 25th Mar 1995} \else \def\title{\BibTeX\ changes for OpenVMS; 25th Mar 1995} \fi @z {Section 1} @x The |banner| string defined here should be changed whenever \BibTeX\ gets modified. @d banner=='This is BibTeX, Version 0.99c' {printed when the program starts} @y The HMC implementation is based on work done by Nelson H.F.\ Beebe, Jerry Leichter, and an anonymous progenitor. From Beebe's version, numerous changes were made to the OpenVMS version by Don Hosek at Harvey Mudd College for assorted enhancements, the most significant of which is the insertion of code to make \BibTeX\ a DCL verb. @d banner=='This is BibTeX, Version 0.99c [PD VMS 1.8]' @z {Section 2} @x Terminal output goes to the file |term_out|, while terminal input comes from |term_in|. On our system, these (system-dependent) files are already opened at the beginning of the program, and have the same real name. @d term_out == tty @d term_in == tty @y Terminal output goes to the file |term_out|, while terminal input comes from |term_in|. On our OpenVMS, these (system-dependent) files are already opened at the beginning of the program. @d term_out == output @d term_in == input @z {Section 4} @x @^debugging@> @^statistics@> Some of the code below is intended to be used only when diagnosing the strange behavior that sometimes occurs when \BibTeX\ is being installed or when system wizards are fooling around with \BibTeX\ without quite knowing what they are doing. Such code will not normally be compiled; it is delimited by the codewords `$|debug|\ldots|gubed|$', with apologies to people who wish to preserve the purity of English. Similarly, there is some conditional code delimited by `$|stat|\ldots|tats|$' that is intended only for use when statistics are to be kept about \BibTeX's memory/cpu usage, and there is conditional code delimited by `$|trace|\ldots|ecart|$' that is intended to be a trace facility for use mainly when debugging \.{.bst} files. @d debug == @{ { remove the `|@{|' when debugging } @d gubed == @t@>@} { remove the `|@}|' when debugging } @f debug == begin @f gubed == end @# @d stat == @{ { remove the `|@{|' when keeping statistics } @d tats == @t@>@} { remove the `|@}|' when keeping statistics } @f stat == begin @f tats == end @# @d trace == @{ { remove the `|@{|' when in |trace| mode } @d ecart == @t@>@} { remove the `|@}|' when in |trace| mode } @f trace == begin @f ecart == end @y @^debugging@> @^statistics@> Some of the code below is intended to be used only when diagnosing the strange behavior that sometimes occurs system wizards are fooling around with \BibTeX\ without quite knowing what they are doing. There is some conditional code delimited by `$|stat|\ldots|tats|$' that is intended only for use when statistics are to be kept about \BibTeX's memory/cpu usage selected by the qualifier \.{/STATS}, and there is conditional code delimited by `$|trace|\ldots|ecart|$' that is intended to be a trace facility for use mainly when debugging \.{.bst} files selected by the qualifier \.{/TRACE}. Since the debugging code simply referred to some in-line compiler switches, it's been removed entirely. @d stat == if stat_flag then begin @d tats == end; @f stat == begin @f tats == end @# @d trace == if trace_flag then begin @d ecart == end; @f trace == begin @f ecart == end @= @!stat_flag, @!trace_flag: boolean; @z {Section 5} @x We assume that |case| statements may include a default case that applies if no matching label is found, since most \PASCAL\ compilers have plugged this hole in the language by incorporating some sort of default mechanism. For example, the \ph\ compiler allows `|others|:' as a default label, and other \PASCAL s allow syntaxes like `\ignorespaces|else|\unskip' or `\\{otherwise}' or `\\{otherwise}:', etc. The definitions of |othercases| and |endcases| should be changed to agree with local conventions. Note that no semicolon appears before |endcases| in this program, so the definition of |endcases| should include a semicolon if the compiler wants one. (Of course, if no default mechanism is available, the |case| statements of \BibTeX\ will have to be laboriously extended by listing all remaining cases. People who are stuck with such \PASCAL s have in fact done this, successfully but not happily!) @d othercases == others: {default for cases not listed explicitly} @d endcases == @+end {follows the default case in an extended |case| statement} @f othercases == else @f endcases == end @y We assume that |case| statements may include a default case that applies if no matching label is found, in VAX Pascal, this is done using \\{otherwise}. @d othercases == otherwise {default for cases not listed explicitly} @d endcases == @+end {follows the default case in an extended |case| statement} @f othercases == else @f endcases == end @z {Section 10} @x program BibTEX; {all files are opened dynamically} @y program BibTEX(input,output); {all files are opened dynamically} @z {Section 11} <<<<>>>> @x @= @{@&$C-,A+,D-@} {no range check, catch arithmetic overflow, no debug overhead} @!debug @{@&$C+,D+@}@+ gubed {but turn everything on when debugging} @y On OpenVMS, there are no compiler directives that can be introduced in this way, but we take this opportunity to include a few system-dependent goodies. @d VAX_text==@= text @> @d VAX_new==@= new @> @d VAX_none==@= none @> @d VAX_byte==@= byte @> @d VAX_word==@= word @> @d VAX_error==@= error @> @d VAX_length==@= length @> @d VAX_syi_sid==@= syi$_sid @> @d VAX_continue==@= continue @> @d VAX_ignore_error==VAX_error:=VAX_continue @d VAX_disposition==@= disposition @> @d VAX_delete==@= delete @> @d VAX_save==@= save @> @d VAX_dispositon_delete==@=disposition:=delete@> @d VAX_disposition_save==@=disposition:=save@> @d VAX_user_action==@=user_action@> @d VAX_external==@= external @> @d VAX_asynchronous==@= asynchronous@> @d VAX_readonly==@= readonly @> @d VAX_unsafe==@= unsafe @> @d VAX_volatile==@= volatile @> @d VAX_class_s==@= CLASS_S @> @d VAX_aligned==@= aligned @> @d VAX_unsigned==@= unsigned @> @d VAX_carriage_control==@= carriage_control @> @d VAX_io_setmode==@= io$_setmode @> @d VAX_iom_ctrlcast==@= io$m_ctrlcast @> @d VAX_immed==@= %immed @> @d VAX_descr==@= %descr @> @d VAX_stdescr==@= %stdescr @> @d VAX_ref==@= %ref @> @d VAX_qiow==@= $qiow @> @d VAX_assign==@= $assign @> @d VAX_numtim==@= $numtim @> @d VAX_getsyi==@= $getsyi @> @d VAX_lib_get_foreign==@= lib$get_foreign @> @d VAX_lib_sig_to_ret==@= lib$sig_to_ret @> @d VAX_establish==@= establish @> @d VAX_status==@= status @> @# @d VAX_address_of==@= iaddress@> @# @d VAX_varying_length==@=length @> @d VAX_varying_body==@=body@> @# @d VAX_trnlog==@= $trnlog @> @d VAX_ss_normal==@= ss$_normal @> @d VAX_CLI__absent==@= CLI$_ABSENT @> @d VAX_CLI__comma==@= CLI$_COMMA @> @d VAX_CLI__concat==@= CLI$_CONCAT @> @d VAX_CLI__defaulted==@= CLI$_DEFAULTED @> @d VAX_CLI__locneg==@= CLI$_LOCNEG @> @d VAX_CLI__locpres==@= CLI$_LOCPRES @> @d VAX_CLI__negated==@= CLI$_NEGATED @> @d VAX_CLI__present==@= CLI$_PRESENT @> @d VAX_cli_get_value==@= CLI$GET_VALUE @> @d VAX_cli_present==@= CLI$PRESENT @> @d VAX_cli_dcl_parse==@= CLI$DCL_PARSE @> @# @f extern==forward @f varying==array @f VAX_unsigned==integer @f unsigned==integer @= @= [inherit('SYS$Library:Starlet')] @> @z {Section 13} <<<<>>>> @x procedure initialize; var @ begin @; if (bad > 0) then begin write_ln (term_out,bad:0,' is a bad bad'); goto exit_program; end; @; pre_def_certain_strings;@/ get_the_top_level_aux_file_name; end; @y procedure initialize; var @ begin if not odd(init_cli(BIBTEX_CLD_table,'BIBT','BIBINPUTS')) then begin write_ln('Ouch---access to DCL command line interface has failed!'); goto exit_program; end; @; if (bad > 0) then begin write_ln (term_out,bad:0,' is a bad bad'); goto exit_program; end; @@; @; pre_def_certain_strings;@/ get_the_top_level_aux_file_name; end; @z {Section 14} <<<<< Changed 05-FEB-1994 by SPC removed constant definitions for CLI return values. >>>>> <<<<< Modified 25-MAR-1995 by SPC : enlarged some parameters: |buf_size| : 1000 -> 2000 |max_bib_files| : 20 -> 30 |pool_size| : 65000 -> 200000 |max_strings| : 4000 -> 6000 |max_cites| : 750 -> 1000 |wiz_fn_space| : 3000 -> 5000 |max_ent_int| : 3000 -> 5000 |max_ent_strs| : 3000 -> 4000 |max_fields| : 17250 -> 23000 >>>>> <<<<< Modified 27-MAR-1995 by SPC : |min_crossrefs is now a variable. >>>>> @x These parameters can be changed at compile time to extend or reduce \BibTeX's capacity. They are set to accommodate about 750 cites when used with the standard styles, although |pool_size| is usually the first limitation to be a problem, often when there are 500 cites. @= @!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=2000; {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 |>>>> <<<<< Modified 25-MAR-1995 by SPC : enlarged the string hash array. |hash_size| : 5000 -> 7000 |hash_prime| : 4253 -> 5953 >>>>> @x 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 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=7000 {must be |>= max_strings| and |>= hash_prime|} @d hash_prime=5953 {a prime number about 85\% of |hash_size| and |>= 128| and |< @t$2^{14}-2^6$@>|} @d file_name_size=255 {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|} @z {Section 22} <<<<>>>> @x @= @!ASCII_code=0..127; {seven-bit numbers} @y @= @!word_type = @=[word]@> -32768..32767; {16-bit integers} @!ASCII_code=0..255; {eight-bit numbers} @z {Section 23} @x last_text_char bug fixed. @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 == 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=255 {ordinal number of the largest element of |text_char|} @z {Section 26} <<<<>>>> @x @d tab=@'11 {ASCII code treated as |white_space|} @d space=@'40 {ASCII code treated as |white_space|} @y @d tab=@'11 {ASCII code treated as |white_space|} @d line_feed=@'12 {ASCII code treated as |white_space|} @d form_feed=@'14 {ASCII code treated as |white_space|} @d carriage_return=@'15 {ASCII code treated as |white_space|} @d space=@'40 {ASCII code treated as |white_space|} @z {Section 27} <<<<>>>> @x usually best to map the additional letters into codes less than~@'40. @= for i:=1 to @'37 do xchr[i]:=' '; xchr[tab]:=chr(tab); @y usually best to map the additional letters into codes less than~@'40. This VMS port has been extended to permit usage of characters taken from columns 10--15 of the extended ISO character set (ISO Latin 1, or DEC Multinational); to match the behaviour of VMS TeX 3.x. @= for i:=1 to @'37 do xchr[i]:=chr(i); for i:=@'200 to @'237 do xchr[i]:=' '; for i:=@'240 to @'377 do xchr[i]:=chr(i); @z {Section 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[chr(i)]:=invalid_code; for i:=@'200 to @'377 do xord[xchr[i]]:=i; for i:=0 to @'176 do xord[xchr[i]]:=i; @z {Section 32} <<<<>>>> @x @= for i:=0 to @'177 do lex_class[i] := other_lex; for i:=0 to @'37 do lex_class[i] := illegal; lex_class[invalid_code] := illegal; lex_class[tab] := white_space; lex_class[space] := white_space; @y @= for i:=0 to @'377 do lex_class[i] := other_lex; for i:=0 to @'37 do lex_class[i] := illegal; for i:=@'200 to @'237 do lex_class[i] := illegal; lex_class[invalid_code] := illegal; lex_class[tab] := white_space; lex_class[line_feed] := white_space; lex_class[form_feed] := white_space; lex_class[carriage_return] := white_space; lex_class[space] := white_space; @z {Section 33} <<<<>>>> @x @= for i:=0 to @'177 do id_class[i] := legal_id_char; for i:=0 to @'37 do id_class[i] := illegal_id_char; @y @= for i:=0 to @'377 do id_class[i] := legal_id_char; for i:=0 to @'37 do id_class[i] := illegal_id_char; for i:=@'200 to @'377 do id_class[i] := illegal_id_char; @z {Section 35} <<<<>>>> @x @= for i:=0 to @'177 do char_width[i] := 0; @# @y @= for i:=0 to @'377 do char_width[i] := 0; @# @z {Section 36} @x @!alpha_file=packed file of text_char; {files that contain textual data} @y @!alpha_file=text; {files that contain textual data} @z {Section 37} @x Set up name_of_file using VMS Pascal's string facility @= @!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..file_name_size] of char; {on some systems this is a \&{record} variable} @!name_length:unsigned_word; {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 {Section 38} @x 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. \TeX'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 @= 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 The OpenVMS \PASCAL\ compiler with which the present version of \BibTeX\ was prepared has provided a way to specify a file name on the |open| command in the manner shown below. For more details, see the OpenVMS \PASCAL\ manual. 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. \TeX's file-opening procedures return |false| if no file identified by |name_of_file| could be opened. @= function a_open_in(var f:alpha_file):boolean; {open a text file for input} begin open(f,name_of_file,VAX_readonly,VAX_user_action:=user_open_wild, VAX_ignore_error); if VAX_status(f)>0 then a_open_in:=false else begin reset(f,VAX_ignore_error); a_open_in:=VAX_status(f)<=0; end; end; @# function a_open_out(var f:alpha_file):boolean; {open a text file for output} begin open(f,name_of_file,VAX_new,16383,{VAX\_disposition\_delete,} VAX_ignore_error); if VAX_status(f)>0 then a_open_out:=false else begin rewrite(f,VAX_ignore_error); a_open_out:=VAX_status(f)<=0; end; end; @z {Section 73} @x @d longest_pds=12 {the length of `\.{change.case\$}'} @y Since we don't know how long the logical names given by the \.{/BSTINPUTS} and \.{/BIBINPUTS} will be, we define |longest_pds| to be 255. However, since VAX \PASCAL\ automatically pads out strings, we don't need to worry about making every argument to |pre_define| 255 characters long. @d longest_pds=255 @z {Section 74} @x @!s_bib_area : str_number; {\.{texbib:}} @y @!s_bib_area : str_number; {\.{texbib:}} @!inp_name, @!binp_name : pds_type; @!inp_len, @!binp_len : [VAX_word] pds_len; @z {Section 75} @x Important notes: These pre-definitions must not have any glitches or the program may bomb because the |log_file| hasn't been opened yet, and |text_ilk|s should be pre-defined later, for \.{.bst}-function-execution purposes. @y Important notes: These pre-definitions must not have any glitches or the program may bomb because the |log_file| hasn't been opened yet, and |text_ilk|s should be pre-defined later, for \.{.bst}-function-execution purposes. We will also take this opportunity to read the values of the qualifiers \.{/BSTINPUTS} and \.{/BIBINPUTS} now. @z {Section 75} @x pre_define('texinputs: ',10,file_area_ilk); s_bst_area := hash_text[pre_def_loc]; pre_define('texbib: ',7,file_area_ilk); s_bib_area := hash_text[pre_def_loc]; @y VAX_cli_get_value('BSTINPUTS',inp_name,inp_len); pre_define(inp_name,inp_len,file_area_ilk); s_bst_area := hash_text[pre_def_loc];@/ VAX_cli_get_value('BIBINPUTS',binp_name,binp_len); pre_define(binp_name,binp_len,file_area_ilk); s_bib_area := hash_text[pre_def_loc]; @z {Section 100} <<<<>>>> @x @= procedure get_the_top_level_aux_file_name; label aux_found,@!aux_not_found; var @@/ begin check_cmnd_line := false; {many systems will change this} loop begin if (check_cmnd_line) then @ else begin write (term_out,'Please type input file name (no extension)--'); if (eoln(term_in)) then {so the first |read| works} read_ln (term_in); aux_name_length := 0; while (not eoln(term_in)) do begin if (aux_name_length = file_name_size) then begin while (not eoln(term_in)) do {discard the rest of the line} get(term_in); sam_you_made_the_file_name_too_long; end; incr(aux_name_length); name_of_file[aux_name_length] := term_in^; get(term_in); end; end; @; aux_not_found: check_cmnd_line := false; end; aux_found: {now we're ready to read the \.{.aux} file} end; @y @= procedure get_the_top_level_aux_file_name; label aux_found,@!aux_not_found; var @@/ begin check_cmnd_line := odd(VAX_cli_present('FILESPEC')); loop begin if (check_cmnd_line) then @ else begin write (term_out,'Please type input file name (no extension)--'); if (eoln(term_in)) then {so the first |read| works} read_ln (term_in); aux_name_length := 0; while (not eoln(term_in)) do begin if (aux_name_length = file_name_size) then begin while (not eoln(term_in)) do {discard the rest of the line} begin get(term_in); if eof(term_in) then goto exit_program; end; sam_you_made_the_file_name_too_long; end; incr(aux_name_length); name_of_file[aux_name_length] := term_in^; get(term_in); if eof(term_in) then goto exit_program; end; end; @; aux_not_found: check_cmnd_line := false; end; aux_found: {now we're ready to read the \.{.aux} file} end; @z {Section 101} <<<<>>>> @x @= @!check_cmnd_line : boolean; {|true| if we're to check the command line} @y @= @!check_cmnd_line : boolean; {|true| if we're to check the command line} @!i, j : integer; {scratch integer} @z {Section 102} <<<<>>> @x And finally, here's the code that handles the command line argument. @= begin do_nothing; {the ``default system'' doesn't use the command line} end @y On OpenVMS, we can create a DCL verb to call the executable module. Doing things in this manner saves us quite a bit of trouble later on since it deals with much of the command line parsing for us. The CLD file for \BibTeX\ is, appropriately enough, named \.{BIBTEX.CLD}. This file defines all the command line parameters and qualifiers. We will only concern ourselves with the parameter containing the file name in this section. @= begin i:=VAX_cli_get_value('FILESPEC', name_of_file, name_length); i:=index(name_of_file, ']'); j:=index(substr(name_of_file, i+1, name_length-i), '.'); if j<>0 then name_length:=i+j-1; {If they give us an extension, remove it} aux_name_length:=name_length; end @z {Section 106} <<<<>>>> @x @= begin name_length := aux_name_length; {set to last used position} add_extension (s_aux_extension); {this also sets |name_length|} aux_ptr := 0; {initialize the \.{.aux} file stack} if (not a_open_in(cur_aux_file)) then sam_you_made_the_file_name_wrong; @# name_length := aux_name_length; add_extension (s_log_extension); {this also sets |name_length|} if (not a_open_out(log_file)) then sam_you_made_the_file_name_wrong; @y @= begin name_length := aux_name_length; {set to last used position} add_extension (s_aux_extension); {this also sets |name_length|} aux_ptr := 0; {initialize the \.{.aux} file stack} if (not a_open_in(cur_aux_file)) then sam_you_made_the_file_name_wrong; @# {The output and log file are written to the location, where the top level \.{.aux} file was found.} name_of_file := act_pathname + act_basename; aux_name_length := act_pathname.VAX_varying_length + act_basename.VAX_varying_length; @# name_length := aux_name_length; add_extension (s_log_extension); {this also sets |name_length|} if (not a_open_out(log_file)) then sam_you_made_the_file_name_wrong; @z {Section 159} @x This version is for printing when in |trace| mode. @= trace procedure trace_pr_fn_class (@!fn_loc : hash_loc); begin case (fn_type[fn_loc]) of built_in : trace_pr ('built-in'); wiz_defined : trace_pr ('wizard-defined'); int_literal : trace_pr ('integer-literal'); str_literal : trace_pr ('string-literal'); field : trace_pr ('field'); int_entry_var : trace_pr ('integer-entry-variable'); str_entry_var : trace_pr ('string-entry-variable'); int_global_var : trace_pr ('integer-global-variable'); str_global_var : trace_pr ('string-global-variable'); othercases unknwn_function_class_confusion endcases; end; ecart @y This version is for printing when in |trace| mode. @= procedure trace_pr_fn_class (@!fn_loc : hash_loc); begin case (fn_type[fn_loc]) of built_in : trace_pr ('built-in'); wiz_defined : trace_pr ('wizard-defined'); int_literal : trace_pr ('integer-literal'); str_literal : trace_pr ('string-literal'); field : trace_pr ('field'); int_entry_var : trace_pr ('integer-entry-variable'); str_entry_var : trace_pr ('string-entry-variable'); int_global_var : trace_pr ('integer-global-variable'); str_global_var : trace_pr ('string-global-variable'); othercases unknwn_function_class_confusion endcases; end; @z {Section 307} @x procedure push_lit_stk (@!push_lt:integer; @!push_type:stk_type); trace var dum_ptr : lit_stk_loc; {used just as an index variable} ecart@/ @y procedure push_lit_stk (@!push_lt:integer; @!push_type:stk_type); var dum_ptr : lit_stk_loc; {used just as an index variable} @z {Section 331} @x @!b_write : hash_loc; {\.{write\$}} @!b_default : hash_loc; {either \.{skip\$} or \.{default.type}} @# stat @!blt_in_loc : array[blt_in_range] of hash_loc; {for execution counts} @!execution_count : array[blt_in_range] of integer; {the same} @!total_ex_count : integer; {the sum of all |execution_count|s} @!blt_in_ptr : blt_in_range; {a pointer into |blt_in_loc|} tats@/ @y @!b_write : hash_loc; {\.{write\$}} @!b_default : hash_loc; {either \.{skip\$} or \.{default.type}} @!blt_in_loc : array[blt_in_range] of hash_loc; {for execution counts} @!execution_count : array[blt_in_range] of integer; {the same} @!total_ex_count : integer; {the sum of all |execution_count|s} @!blt_in_ptr : blt_in_range; {a pointer into |blt_in_loc|} @z {Section 459} @x BibTeX 0.99d? if (type_list[cite_ptr] = undefined) then undefined : trace_pr ('unknown') @y if (type_list[cite_ptr] = undefined) then trace_pr ('unknown') @z {Section 467...} <<<<< Changed 05-FEB-1994 by SPC modified test for command line qualifiers to not use the (symbolic) return constant definitions CLI$PRESENT(). >>>>> <<<<< Modified 26-NOV-1994 by SPC : - added check function for presence of CLI table - added wildcard parsing capabibity to input file opening routine >>>>> <<<<< Modified 27-MAR-1995 by SPC : Allow modification of |min_crossrefs| value through the new command qualifier /MIN_CROSSREFS. >>>>> @x This section should be replaced, if necessary, by changes to the program that are necessary to make \BibTeX\ 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 printed program. More extensive changes, which introduce new sections, can be inserted here; then only the index itself will get a new section number. @y Here are the remaining changes to the program that are necessary to make \BibTeX\ work on OpenVMS. @ First, we need to pull in some external functions: @= [VAX_external] function VAX_cli_present( entity_desc : [VAX_volatile,VAX_class_s] packed array [l1..u1:integer] of char ):integer; @/ external;@;@t\2@>@# [VAX_external] function VAX_cli_get_value(@/ entity_desc : [VAX_volatile,VAX_class_s,VAX_readonly] @+ packed array [l1..u1:integer] of char; var ret_desc : [VAX_volatile,VAX_class_s] @+ packed array [l2..u2:integer] of char; var ret_length : [VAX_volatile,VAX_unsafe] @+ unsigned_word := VAX_immed 0 ):integer; @/ external; [VAX_external] @+function VAX_cli_dcl_parse(@/ VAX_stdescr cmdline:[VAX_volatile,VAX_readonly] packed array [l1..u1:integer] of char := VAX_immed 0; VAX_immed cld_table:[VAX_volatile,VAX_readonly] VAX_unsigned := VAX_immed 0):integer; @/ extern;@;@t\2@>@# [VAX_external] @+function VAX_lib_get_foreign(@/ VAX_stdescr cmdlin:[VAX_volatile] packed array [l1..u1:integer] of char := VAX_immed 0; VAX_stdescr prompt:[VAX_volatile] packed array [l2..u2:integer] of char := VAX_immed 0; var len : [VAX_volatile] unsigned_word := VAX_immed 0; var flag : [VAX_volatile] integer := VAX_immed 0) :integer; @/ extern;@;@t\2@>@# [VAX_external, VAX_asynchronous] @+function VAX_lib_sig_to_ret(@/ VAX_ref signal_args:[VAX_volatile,VAX_unsafe] array [l1..u1:integer] of unsigned_char; VAX_ref mechan_args:[VAX_volatile,VAX_unsafe] array [l2..u2:integer] of unsigned_char) :integer; @/ extern; @ @= unsigned_char = [VAX_byte] 0..255; unsigned_word = [VAX_word] 0..65535; sixteen_bits = unsigned_word; unsafe_file = [VAX_unsafe] file of char; FAB_ptr = ^VAX_fab_type; RAB_ptr = ^VAX_rab_type; NAM_ptr = ^VAX_nam_type; chrptr = ^char; @ The following global symbol is used to refer to the command definition table linked into the \BibTeX\ program @d BIBTEX_CLD_table == @=BIBTEX_CLI@> @= BIBTEX_CLD_table : [VAX_external, VAX_readonly] VAX_unsigned; @ The |init_cli| function is invoked right at the beginning of \BibTeX, only preceded by the terminal output initialization. Its purpose is to make sure that the DCL command interface is available. This function checks, if the program was invoked by the DCL command specified through |verb_name| and that a command qualifier specified by |qual_name| is present (or defaulted) in the command description. For the second test, a small subroutine |check_cli| is needed, because of the "caller--callee" dependence required by the user error handler facility. The |verb_name| string supplied to |init_cli| by the caller must not exceed a length of 4, otherwise the comparison with the "last DCL command" does never succeed, because the DCL parser truncates commands to a length of 4! The test item |qual_name| should be a specific, non-negatable command qualifier for the verb |verb_name|, which is set by default in the command description. If either of these two tests fail, it can be assumed that the program was invoked as a foreign command (or started by the RUN command). If this case, the command line tail is fetched with the \.{LIB\$GET\_FOREIGN} runtime functions and parsed internally, using the \.{CLI\$DCL\_PARSE} utility routine and the command table linked into the program executable, whose name is supplied by the |table| formal parameter. @.LIB{\$}GET_FOREIGN@> @.CLI{\$}DCL_PARSE@> @= function init_cli( var table:[VAX_readonly] VAX_unsigned; verb_name:[VAX_readonly] packed array[l1..u1:integer] of char; qual_name:[VAX_readonly] packed array[l2..u2:integer] of char ): integer; label exit; var command_line: packed array[1..256] of char; @!len: sixteen_bits; @!sts: integer; function check_cli( unique_def_qual:[VAX_readonly] packed array[l1..u1:integer] of char ): integer; begin VAX_establish(VAX_lib_sig_to_ret); check_cli := VAX_cli_present(unique_def_qual); end; begin sts := VAX_cli_get_value('$VERB',command_line,len); if (odd(sts) and (len > 0)) then if (substr(command_line,1,len) = verb_name) then if (odd(check_cli(qual_name))) then begin init_cli := 1; return; end; VAX_lib_get_foreign(command_line,,len); {prepend |verb_name| plus a blank to |command_line|} command_line := verb_name + ' ' + substr(command_line,1,len); init_cli := VAX_cli_dcl_parse(command_line, VAX_address_of(table)); exit:end; @ The |min_crossrefs| `constant' is now defined as an initialized variable and can be modified at runtime: @= @!min_crossrefs: integer := 2; {minimum number of cross-refs required for automatic |cite_list| inclusion} @ Now, we read the command line flag values. @= trace_flag:= odd(VAX_cli_present('TRACE'));@/ stat_flag:= odd(VAX_cli_present('STATS')); cli_get_num_value('MIN_CROSSREFS',min_crossrefs); @ The following small function |cli_get_num_value|is used to fetch an integer numerical value from a command line qualifier. One VAX-\PASCAL\ extension permits string variables to be used in place of files for reading and writing values. The |VAX_string_read(b,i,...)| procedure reads values into variables |i,...| from the characters stored in the string variable |b|. The |VAX_string_status| function returns a value in a manner entirely analogous to VAX-\PASCAL's external I/O |VAX_status| function, but relating to the success of the previous string read/write. @d VAX_string_read==@= readv @> @d VAX_string_status==@= statusv @> @= function cli_get_num_value( qualifier_name : [VAX_readonly] @+ packed array [l1..u1:integer] of char; var numeric_var : integer ): boolean; var numstr_buf: packed array[1..256] of char; @!numstr_len: sixteen_bits; @!sts,@!int_val: integer; begin sts := (VAX_cli_present(qualifier_name)); if odd(sts) then begin sts := VAX_cli_get_value(qualifier_name,numstr_buf,numstr_len); VAX_string_read(substr(numstr_buf,1,numstr_len),int_val,VAX_ignore_error); if VAX_string_status > 0 then sts := 0 else numeric_var := int_val; end; cli_get_num_value := odd(sts); end; @ The following global string variables are used by the user defined action routine (called during |VAX_open| processing) to return the name components of the actual file accessed. @= @!act_pathname:varying [300] of char; @!act_basename,@!act_fextension:varying [32] of char; @!act_fversion:varying[16] of char; @ We supply the following routine to be used (in a call of the VAX-\PASCAL\ |open| procedure) as a |user_action| function. When called from within the |open| routine, the addresses of the |FAB| and |RAB| allocated to the file are passed to such a function, along with the file variable; the latter is tagged as `unsafe' to prevent undesirable compiler optimizations. The |user_open_wild| function, used to open files for reading, performs wild card expansion on the file specification and opens the first matching file. @d VAX_rms_parse==@=$parse@> @d VAX_rms_search==@=$search@> @d VAX_rms_create==@=$create@> @d VAX_rms_connect==@=$connect@> @d VAX_rms_open==@=$open@> @# @d VAX_fab_type==@= FAB$TYPE @> @d VAX_rab_type==@= RAB$TYPE @> @d VAX_nam_type==@= NAM$TYPE @> @d VAX_FAB_V_NAM== @=FAB$V_NAM@> @d VAX_FAB_L_NAM== @=FAB$L_NAM@> @d VAX_NAM_B_RSL== @=NAM$B_RSL@> @d VAX_NAM_L_RSA== @=NAM$L_RSA@> @d VAX_NAM_B_NODE==@=NAM$B_NODE @> @d VAX_NAM_L_NODE==@=NAM$L_NODE @> @d VAX_NAM_B_DEV==@=NAM$B_DEV @> @d VAX_NAM_L_DEV==@=NAM$L_DEV @> @d VAX_NAM_B_DIR==@=NAM$B_DIR @> @d VAX_NAM_L_DIR==@=NAM$L_DIR @> @d VAX_NAM_B_NAME==@=NAM$B_NAME @> @d VAX_NAM_L_NAME==@=NAM$L_NAME @> @d VAX_NAM_B_TYPE==@=NAM$B_TYPE @> @d VAX_NAM_L_TYPE==@=NAM$L_TYPE @> @d VAX_NAM_B_VER==@=NAM$B_VER @> @d VAX_NAM_L_VER==@=NAM$L_VER @> @= function user_open_wild( var FAB:VAX_fab_type; var RAB:VAX_rab_type; var F:unsafe_file):integer; var sts:integer; NAM:NAM_ptr; p:chrptr; i:integer; begin sts:=VAX_rms_parse(FAB); if odd(sts) then begin sts:=VAX_rms_search(FAB); if odd(sts) then FAB.VAX_FAB_V_NAM:=true; {Use |NAM| block in |VAX_rms_open| call!} sts:=VAX_rms_open(FAB); if odd(sts) then begin sts:=VAX_rms_connect(RAB); if odd(sts) then begin NAM:=FAB.VAX_FAB_L_NAM::NAM_ptr; if NAM<>nil then begin act_pathname.VAX_varying_length:=NAM^.VAX_NAM_B_NODE+ NAM^.VAX_NAM_B_DEV+NAM^.VAX_NAM_B_DIR; for i:=1 to act_pathname.VAX_varying_length do begin p:=(NAM^.VAX_NAM_L_RSA::integer+i-1)::chrptr; act_pathname.VAX_varying_body[i]:=p^; end; act_basename.VAX_varying_length:=NAM^.VAX_NAM_B_NAME; for i:=1 to NAM^.VAX_NAM_B_NAME do begin p:=(NAM^.VAX_NAM_L_NAME::integer+i-1)::chrptr; act_basename.VAX_varying_body[i]:=p^; end; act_fextension.VAX_varying_length:=NAM^.VAX_NAM_B_TYPE; for i:=1 to NAM^.VAX_NAM_B_TYPE do begin p:=(NAM^.VAX_NAM_L_TYPE::integer+i-1)::chrptr; act_fextension.VAX_varying_body[i]:=p^; end; act_fversion.VAX_varying_length:=NAM^.VAX_NAM_B_VER; for i:=1 to NAM^.VAX_NAM_B_VER do begin p:=(NAM^.VAX_NAM_L_VER::integer+i-1)::chrptr; act_fversion.VAX_varying_body[i]:=p^; end; end; end; end; end; user_open_wild:=sts; end; @z