From: IN%"U12921@UICVM.uic.EDU" "Don Hosek" 21-JUL-1989 14:52:31.07 To: Ted Nieland CC: Subj: BibTeX.VMS-CHANGES Return-path: U12921@UICVM.UIC.EDU Received: from AAMRL.AF.MIL by FALCON; Fri, 21 Jul 89 14:52 EST Received: from UICVM.uic.edu by AAMRL.AF.MIL; Fri, 21 Jul 89 14:45 EDT Received: from UICVM by UICVM.uic.edu (IBM VM SMTP R1.2.1MX) with BSMTP id 4980; Fri, 21 Jul 89 13:24:15 CDT Received: by UICVM (Mailer R2.03B) id 7068; Fri, 21 Jul 89 13:24:11 CDT Date: Fri, 21 Jul 89 13:23:18 CDT From: Don Hosek Subject: BibTeX.VMS-CHANGES To: Ted Nieland This change file is for the VAX/VMS version of BibTeX 12-Feb-88 Modified for Version .99b by Jerry Leichter 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. 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. 3-Dec-88 Fixed error on text_char definitions. Don Hosek. 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 Here is the CLD file. ----------------------------------------------------------------------- ! CLD file for BibTeX. ! (HMC Implementation 12/8/88) ! Don Hosek define verb BIBTEX image tex_root:[sources.bibtex0_99]bibtex.exe parameter p1,label=filespec,prompt="Input file",value(required,type=$infile) qualifier stats, ! default is /NOSTATS qualifier trace ! default is /NOTRACE ----------------------------------------------------------------------- Limbo. @x \def\title{\BibTeX\ } @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{\BibTeX\ changes for VAX/VMS} @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 VAX/VMS 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. The date in the banner line represents the last significant change to the \BibTeX\ code; it is {\bf not} updated for program version updates unless the version update requires reworking a major portion of the change file. If major changes are made outside of the normal HMC development, an additional note should be added to the banner to distinguish the change file from the ``HMC'' version. @d banner=='This is BibTeX, VAX/VMS Version 0.99c [HMC 12/8/88]' @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 VAX/VMS, 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 VAX/VMS, 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_word==@= word @> @d VAX_error==@= error @> @d VAX_length==@= length @> @d VAX_syi_sid==@= syi$_sid @> @d VAX_continue==@= continue @> @d VAX_external==@= external @> @d VAX_readonly==@= readonly @> @d VAX_volatile==@= volatile @> @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_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_disposition==@= disposition @> @d VAX_delete==@= delete @> @d VAX_save==@= save @> @d VAX_varying==@= varying @> @d VAX_substr==@= substr @> @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 CLI_get_value==@= CLI$GET_VALUE @> @d CLI_present==@= CLI$PRESENT @> @= @= [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 (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. @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=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 |= @y @= @!word_type = @=[word]@> -32768..32767; {16-bit integers} @z Module 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 Module 36. @x @!alpha_file=packed file of text_char; {files that contain textual data} @y @!alpha_file=text; {files that contain textual data} @z Module 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 Module 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 VAX/VMS \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 VAX/VMS \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_error:=VAX_continue); if status(f)>0 then a_open_in:=false else begin reset(f,VAX_error:=VAX_continue); a_open_in:=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:=VAX\_delete,} VAX_error:=VAX_continue); if status(f)>0 then a_open_out:=false else begin rewrite(f,VAX_error:=VAX_continue); a_open_out:=status(f)<=0; end; end; @z Module 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 pre_define('tex_inputs: ',11,file_area_ilk); s_bst_area := hash_text[pre_def_loc]; pre_define('tex_bib: ',8,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 := true; 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 begin {discard the rest of the line} 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 Module 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 : integer; {scratch integer} @z Module 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 VAX/VMS, 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:=CLI_get_value('FILESPEC', name_of_file, name_length); i:=index(name_of_file, '.'); if i<>0 then name_length:=i-1; {If they give us an extension, we don't want it} aux_name_length:=name_length; end @z Module 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 Module 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 Module 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 Module 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 Module 467. @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 VAX/VMS. @ First, we need to pull in some external functions: @= @= [ EXTERNAL ] @> function CLI_present( entity_desc : @=[CLASS_S]@> packed array [@=$l1@>..@=$u1@>:integer] of char ):integer; external; @# @= [ EXTERNAL ] @> function CLI_get_value( entity_desc : @=[CLASS_S]@> packed array [@=$l1@>..@=$u1@>:integer] of char; ret_desc : @=[CLASS_S]@> packed array [@=$l2@>..@=$u2@>:integer] of char; var ret_length : @=[UNSAFE]@> unsigned_word := VAX_immed 0 ):integer; external; @ @= unsigned_word = @=[WORD]@> 0..65535; @ Now, we read the command line flag values. @= trace_flag:= ((CLI_present('TRACE') = VAX_CLI_present) or (CLI_present('TRACE') = VAX_CLI_defaulted)); stat_flag:= ((CLI_present('STATS') = VAX_CLI_present) or (CLI_present('STATS') = VAX_CLI_defaulted)); @z