WEAVE change file for Vax/VMS Copyright (C) 1983 by David Fuchs. All rights are reserved. MODIFICATION RECORD ~~~~~~~~~~~~~~~~~~~ 20-JUL-1988 BHK Switch off reporting of usage statistics. Permit WEAVEing of large things like TEX.WEB 06-SEP-1988 BHK Incorporate correct handling of the `::' type-cast operator. See UK-TeX vol.88, no. 27 21-NOV-1988 CNK Set |last_text_char| = 255 (from 127). See TeXhax vol. 88, no. 100 12-DEC-1988 BHK Emit VMS status on program exit 28-SEP-1989 BHK Modify for weave v3 29-SEP-1989 BHK Corrected bug which made continuation lines not perpetuate any TeX comment that commenced in the previous line. (V3.0-1) 29-SEP-1989 BHK Prevent multiple cross-references to any particular module from within any one particular module. (V3.0-2) 03-NOV-1989 BHK Modified for V4 (eight-bit support) 10-APR-1990 BHK Modified for V4.1 24-SEP-1990 BHK Modified for V4.2 03-FEB-1992 BHK Modified for V4.4 {Section 0} @x \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{WEAVE changes for Vax/VMS} @z {Section 1} @x @d banner=='This is WEAVE, Version 4.4' @y @d banner=='This is WEAVE, Vax/VMS Version 4.4' @z {Section 2} @x and |change_file|, and the \TeX\ output goes to file |tex_file|. @y and |change_file|, and the \TeX\ output goes to file |tex_file|. VMS requires us to mention |input| and |output| in the program header, too. They are used for terminal input and output. @z {Section 2} @x program WEAVE(@!web_file,@!change_file,@!tex_file); @y program WEAVE(@!input,@!output,@!web_file,@!change_file,@!tex_file); @z {Section 2} @x begin @@/ @y begin @@/ @@/ @z {Section 3} @x <<<<< Added 20-JUL-1988 by BHK >>>>> @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== {empty statement} @d tats== {another empty statement} @z {Section 4} @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, things are a bit different. @= @=[check(none),inherit('sys$library:starlet')]@> {no debug overhead, but...} debug @=[check(all),inherit('sys$library:starlet')]@> gubed {turn everything on when debugging} @z {Section 7} @x @d othercases == others: {default for cases not listed explicitly} @y @d othercases == otherwise {Vax/VMS default for cases not listed explicitly} @z {Section 8} @x <<<<< Added 20-JUL-1988 by BHK >>>>> @!max_refs=30000; {number of cross references; must be less than 65536} @!max_toks=30000; {number of symbols in \PASCAL\ texts being parsed; must be less than 65536} @!max_texts=2000; {number of phrases in \PASCAL\ texts being parsed; must be less than 10240} @!max_scraps=1000; {number of tokens in \PASCAL\ texts being parsed} @y @!max_refs=40000; {number of cross references; must be less than 65536} @!max_toks=40000; {number of symbols in \PASCAL\ texts being parsed; must be less than 65536} @!max_texts=5000; {number of phrases in \PASCAL\ texts being parsed; must be less than 10240} @!max_scraps=2000; {number of tokens in \PASCAL\ texts being parsed} @z {Section 12} @x @!text_file=packed file of text_char; @y @!text_file=text; @z {Section 15} @x <<<<< Added 06-SEP-1988 by BHK >>>>> @d carriage_return=@'15 {ASCII code used at end of line} @y @d carriage_return=@'15 {ASCII code used at end of line} @d type_cast=@'27 {equivalent to `::'} @z {Section 20} @x @d print_ln(#)==write_ln(term_out,#) {`|print|' and then start new line} @d new_line==write_ln(term_out) {start new line} @y @d print_ln(#)==write_ln(term_out,#,chr(13),chr(10)) {`|print|' and then start new line} @d new_line==write_ln(term_out,chr(13),chr(10)) {start new line} @z {Section 21} @x rewrite(term_out,'TTY:'); {send |term_out| output to the terminal} @y @= open@>(term_out,'SYS$OUTPUT',@=carriage_control:=none@>); rewrite(term_out); @z {Section 22} @x @d update_terminal == break(term_out) {empty the terminal output buffer} @y @d update_terminal == write_ln(term_out) {empty the terminal output buffer} @z {Section 26} @x @ The following code opens |tex_file|. Since this file was listed in the program header, we assume that the \PASCAL\ runtime system has checked that a suitable external file name has been given. @^system dependencies@> @= rewrite(tex_file); @y @ The following code opens |tex_file|. Actually, on Vax/VMS this task is put off until later. @^system dependencies@> @z {Section 27} @x @ Input goes into an array called |buffer|. @=@!buffer: array[0..long_buf_size] of ASCII_code; @y @ Input goes into an array called |buffer|. Actually, it is first read into |temp_buffer|. @=@!buffer: array[0..long_buf_size] of ASCII_code; @!temp_buffer: varying [buf_size] of char; @z {Section 28} @x <<<< : V3 WEB has changed>>>>> @p function input_ln(var f:text_file):boolean; {inputs a line or returns |false|} var final_limit:0..buf_size; {|limit| without trailing blanks} begin limit:=0; final_limit:=0; if eof(f) then input_ln:=false else begin while not eoln(f) do begin buffer[limit]:=xord[f^]; get(f); incr(limit); if buffer[limit-1]<>" " then final_limit:=limit; if limit=buf_size then begin while not eoln(f) do get(f); decr(limit); {keep |buffer[buf_size]| empty} if final_limit>limit then final_limit:=limit; print_nl('! Input line too long'); loc:=0; error; @.Input line too long@> end; end; read_ln(f); limit:=final_limit; input_ln:=true; end; end; @y On Vax/VMS we first read a line into |temp_buffer|, since that's faster. @p function input_ln(var f:text_file):boolean; {inputs a line or returns |false|} var i,@!l:0..buf_size; begin limit:=0; if eof(f) then input_ln:=false else begin read(f,temp_buffer); l:=temp_buffer.@=length@>; for i:=1 to l do begin buffer[i-1]:=xord[temp_buffer[i]]; if buffer[i-1]<>" " then limit:=i; end; if not eoln(f) then begin print_nl('! Input line too long'); error; @.Input line too long@> end else read_ln(f); input_ln:=true; end; end; @z {Section 51} <<<<< Added 29-SEP-1989 by BHK : correct multiple xrefs>>>>> @x @p procedure new_mod_xref(@!p:name_pointer); var q,@!r:xref_number; {pointers to previous cross references} begin q:=xref[p]; r:=0; if q>0 then begin if mod_xref_switch=0 then while num(q)>=def_flag do begin r:=q; q:=xlink(q); end else if num(q)>=def_flag then begin r:=q; q:=xlink(q); end; end; append_xref(module_count+mod_xref_switch); xlink(xref_ptr):=q; mod_xref_switch:=0; if r=0 then xref[p]:=xref_ptr else xlink(r):=xref_ptr; end; @y @p procedure new_mod_xref(@!p:name_pointer); label exit; var q,@!r:xref_number; {pointers to previous cross references} begin q:=xref[p]; r:=0; if q>0 then begin if mod_xref_switch=0 then while num(q)>=def_flag do begin r:=q; q:=xlink(q); end else if num(q)>=def_flag then begin r:=q; q:=xlink(q); end; end; if num(q) = module_count+mod_xref_switch then return; append_xref(module_count+mod_xref_switch); xlink(xref_ptr):=q; mod_xref_switch:=0; if r=0 then xref[p]:=xref_ptr else xlink(r):=xref_ptr; exit: end; @z {Section 97} @x <<<<< Added 06-SEP-1988 by BHK >>>>> ":": if buffer[loc]="=" then compress(left_arrow); @y ":": if buffer[loc]="=" then compress(left_arrow) else if buffer[loc]=":" then compress(type_cast); @z {Section 122} <<<< : fix comment continuation>>>>> @x done: for k:=1 to j do write(tex_file,xchr[out_buf[k]]); if per_cent then write(tex_file,xchr["%"]); write_ln(tex_file); incr(out_line); @y done: for k:=1 to j do out_temp_buffer[k]:=xchr[out_buf[k]]; k:=j; if per_cent then begin incr(k); out_temp_buffer[k]:=xchr["%"]; end; write_ln(tex_file,substr(out_temp_buffer,1,k)); incr(out_line); @z {Section 186} @x <<<<< Added 06-SEP-1988 by BHK >>>>> ":": sc1(":")(colon); @y ":": sc1(":")(colon); type_cast: sc2(":")(":")(math); @z {Section 258} @x @!term_in:text_file; {the user's terminal as an input file} @y @z {Section 259} @x @= @y @d term_in==input @= @z {Section 261} @x reset(term_in,'TTY:','/I'); {open |term_in| as the terminal, don't do a |get|} @y @z {Section 261} @x @t\4\4@>{here files should be closed if the operating system requires it} @y if history(tex_file,@=disposition:=save@>,@=error:=continue@>); @z {Section 263} @x <<<<< Added 12-DEC-1988 by BHK >>>>> @ Some implementations may wish to pass the |history| value to the operating system so that it can be used to govern whether or not other programs are started. Here we simply report the history to the user. @^system dependencies@> @= case history of spotless: print_nl('(No errors were found.)'); harmless_message: print_nl('(Did you see the warning message above?)'); error_message: print_nl('(Pardon me, but I think I spotted something wrong.)'); fatal_message: print_nl('(That was a fatal error, my friend.)'); end {there are no other cases} @y @ This implementation passes the |history| value to the operating system so that it can be used to govern whether or not other programs are started; we also report the history to the user here. @^system dependencies@> @d VAX_exit==@=$exit@> @d VAX_ss_normal==@= sts$k_success @> @d VAX_ss_warning==@= sts$k_warning + sts$m_inhib_msg @> @d VAX_ss_error==@= sts$k_error + sts$m_inhib_msg @> @d VAX_ss_fatal==@= sts$k_severe + sts$m_inhib_msg @> @= case history of spotless: begin print_nl('(No errors were found.)'); VAX_exit(VAX_ss_normal) end; { Everything OK! } harmless_message: begin print_nl('(Did you see the warning message above?)'); VAX_exit(VAX_ss_warning) end; error_message: begin print_nl('(Pardon me, but I think I spotted something wrong.)'); VAX_exit(VAX_ss_error) end; fatal_message: begin print_nl('(That was a fatal error, my friend.)'); VAX_exit(VAX_ss_fatal) end {there are no other cases} end; @z {Section 264 et seq} @x This module should be replaced, if necessary, by changes to the program that are necessary to make \.{WEAVE} work at a particular installation. It is usually best to design your change file so that all changes to previous modules preserve the module numbering; then everybody's version will be consistent with the printed program. More extensive changes, which introduce new modules, can be inserted here; then only the index itself will get a new module number. @y Here are the remaining changes to the program that are necessary to make \.{WEAVE} work on Vax/VMS. @ This variable is for speeding up the output routine. @= @!out_temp_buffer: packed array [1..line_length+1] of char; @ On Vax/VMS we need the following special definitions, types, variables and procedures to be able to get the file name from the command line, or to prompt for them. @d VAX_volatile==@=volatile@> @d VAX_immed==@=%immed @> @d VAX_external==@=external@> @d VAX_stdescr==@=%stdescr @> @d VAX_lib_get_foreign==@= lib$get_foreign@> @d VAX_length==@=length @> @ @= @!command_line:packed array[1..300] of char; @!cmd_len:sixteen_bits; @!cmd_i:integer; @!file_name,@!default_file_name:varying [300] of char; @!ask,@!got_file_name: boolean; @ Here is the library procedure that gets the user's command line. @= [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] sixteen_bits := VAX_immed 0; var flag : [VAX_volatile] integer := VAX_immed 0) :integer; extern; @ We get the external file names, and then call |open| to associate an external file with each file variable. @d VAX_open == @= open@> @= cmd_i:=0; VAX_lib_get_foreign(command_line,,cmd_len,cmd_i); cmd_i:=1; while (cmd_i<=cmd_len) and (command_line[cmd_i]=' ') do incr(cmd_i); got_file_name:=cmd_i<=cmd_len; if got_file_name then default_file_name:=substr(command_line,cmd_i,cmd_len-cmd_i+1); if got_file_name then begin file_name:=default_file_name+'.WEB'; VAX_open(web_file,file_name,@=readonly@>,@=error:=continue@>); ask:=status(web_file)<>0; if ask then write_ln('Couldn''t open ',file_name); end else ask:=true; while ask do begin got_file_name:=false; write('Web file: '); if eof then begin mark_fatal; jump_out; end; read_ln(file_name); VAX_open(web_file,file_name,@=readonly@>,@=error:=continue@>); ask:=status(web_file)<>0; if ask then write_ln('Couldn''t open ',file_name); end; if got_file_name then begin file_name:=default_file_name+'.CH'; VAX_open(change_file,file_name,@=readonly@>,@=error:=continue@>); ask:=status(change_file)>0; {can be empty} if ask then write_ln('Couldn''t open ',file_name); end else ask:=true; while ask do begin write('Change file: '); if eof then begin mark_fatal; jump_out; end; read_ln(file_name); if file_name.VAX_length=0 then file_name:='NL:'; VAX_open(change_file,file_name,@=readonly@>,@=error:=continue@>); ask:=status(change_file)>0; if ask then write_ln('Couldn''t open ',file_name); end; if got_file_name then begin cmd_i:=1; for cmd_len:=1 to default_file_name.VAX_length do if (default_file_name[cmd_len]=']') or (default_file_name[cmd_len]=':') then cmd_i:=cmd_len+1; if cmd_i<=default_file_name.VAX_length then default_file_name:=substr(default_file_name,cmd_i, default_file_name.VAX_length-cmd_i+1); file_name:=default_file_name+'.TEX'; VAX_open(tex_file,file_name,@=new,disposition:=delete@>, @=error:=continue@>); ask:=status(tex_file)>0; if ask then write_ln('Couldn''t open ',file_name); end else ask:=true; while ask do begin write('TeX file: '); if eof then begin mark_fatal; jump_out; end; read_ln(file_name); VAX_open(tex_file,file_name,@=new,disposition:=delete@>, @=error:=continue@>); ask:=status(tex_file)>0; if ask then write_ln('Couldn''t open ',file_name); end; rewrite(tex_file); @z