Return-Path: Date: Wed, 27 Jan 88 14:31 EST From: "Jerry Leichter (LEICHTER-JERRY@CS.YALE.EDU)" Subject: Bugfixes for VMS DVITYPE Enclosed below is an updated change file for DVITYPE on VMS. The first change is simply an update to match the latest version number string. The second fixes a problem that causes DVITYPE to be unable to open an TFM files unless you happen to have write access to them! BTW, the code for DVITYPE is full of remarks like "stupid VMS run-time bug" and "change me when bug is fixed". Anyone know anymore what bug was being worked around? This code is presumably obsolete, but without knowing what it was, it's impossible to know if it can be removed safely. -- Jerry DVItype change file for Vax/VMS Copyright (C) 1983 by David Fuchs. All rights are reserved. 7Dec87 JSL .DVIType is now at Version 2.9. 27Jan88 JSL .Use READONLY, not OLD, when opening the TFM files. @x \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{DVI$\,$\lowercase{type} changes for Vax/VMS} @z @x @d banner=='This is DVItype, Version 2.9' {printed when the program starts} @y @d banner=='This is DVItype, Vax/VMS Version 2.9' @z @x @d othercases == others: {default for cases not listed explicitly} @y @d othercases == otherwise {Vax/VMS default for cases not listed explicitly} @z @x @d print(#)==write(#) @d print_ln(#)==write_ln(#) @y In fact, we do this under Vax/VMS. We also use double-precision for all real values. @d print(#)==write(type_file,#) @d print_ln(#)==write_ln(type_file,#) @d real==double @z @x @p program DVI_type(@!dvi_file,@!output); @y @p @\@=[inherit('sys$library:starlet')]@>@\ {allows us to use system symbols and routines} program DVI_type(@!dvi_file,@!tfm_file,@!type_file,@!input,@!output); @z @x procedure initialize; {this procedure gets things started properly} var i:integer; {loop index for initializations} begin print_ln(banner);@/ @y @@/ procedure initialize; {this procedure gets things started properly} var i:integer; {loop index for initializations} begin @@/ print_ln(banner);@/ @z @x @!byte_file=packed file of eight_bits; {files that contain binary data} @y {later we'll define files that contain binary data} @z @x @!dvi_file:byte_file; {the stuff we are \.{DVI}typing} @!tfm_file:byte_file; {a font metric file} @y @!dvi_file:packed file of byte_block; {the stuff we are \.{DVI}typing} @!tfm_file:packed file of byte_block; {a font metric file} @!dvi_count:integer; {number of bytes read from current block of |dvi_file|} @!tfm_count:integer; {number of bytes read from current block of |tfm_file|} @!dvi_blocks:integer; {number of blocks in |dvi_file|} @z @x begin reset(dvi_file); @y begin reset(dvi_file); dvi_count:=0; @z @x begin reset(tfm_file,cur_name); @y begin close(tfm_file,@=error@>:=@=continue@>); {stupid Vax/VMS run-times} open(tfm_file,cur_name,@=readonly@>,@=error@>:=@=continue@>); reset(tfm_file,@=error@>:=@=continue@>); tfm_count:=0; @z @x @p procedure read_tfm_word; begin read(tfm_file,b0); read(tfm_file,b1); read(tfm_file,b2); read(tfm_file,b3); @y @d read_tfm_file(#)==begin if tfm_count=VAX_block_length then begin get(tfm_file,@=error:=continue@>); tfm_count:=0; end; #:=tfm_file^[tfm_count]; incr(tfm_count); end @p procedure read_tfm_word; begin read_tfm_file(b0); read_tfm_file(b1); read_tfm_file(b2); read_tfm_file(b3); @z @x @p function get_byte:integer; {returns the next byte, unsigned} var b:eight_bits; begin if eof(dvi_file) then get_byte:=0 else begin read(dvi_file,b); incr(cur_loc); get_byte:=b; end; end; @# function signed_byte:integer; {returns the next byte, signed} var b:eight_bits; begin read(dvi_file,b); incr(cur_loc); if b<128 then signed_byte:=b @+ else signed_byte:=b-256; end; @# function get_two_bytes:integer; {returns the next two bytes, unsigned} var a,@!b:eight_bits; begin read(dvi_file,a); read(dvi_file,b); cur_loc:=cur_loc+2; get_two_bytes:=a*256+b; end; @# function signed_pair:integer; {returns the next two bytes, signed} var a,@!b:eight_bits; begin read(dvi_file,a); read(dvi_file,b); cur_loc:=cur_loc+2; if a<128 then signed_pair:=a*256+b else signed_pair:=(a-256)*256+b; end; @# function get_three_bytes:integer; {returns the next three bytes, unsigned} var a,@!b,@!c:eight_bits; begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c); cur_loc:=cur_loc+3; get_three_bytes:=(a*256+b)*256+c; end; @# function signed_trio:integer; {returns the next three bytes, signed} var a,@!b,@!c:eight_bits; begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c); cur_loc:=cur_loc+3; if a<128 then signed_trio:=(a*256+b)*256+c else signed_trio:=((a-256)*256+b)*256+c; end; @# function signed_quad:integer; {returns the next four bytes, signed} var a,@!b,@!c,@!d:eight_bits; begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c); read(dvi_file,d); cur_loc:=cur_loc+4; if a<128 then signed_quad:=((a*256+b)*256+c)*256+d else signed_quad:=(((a-256)*256+b)*256+c)*256+d; end; @y @d read_dvi_file(#)==begin if dvi_count=VAX_block_length then begin get(dvi_file,@=error:=continue@>); dvi_count:=0; end; #:=dvi_file^[dvi_count]; incr(dvi_count); end @p function get_byte:integer; {returns the next byte, unsigned} var b:eight_bits; begin if eof(dvi_file) then get_byte:=0 else begin read_dvi_file(b); incr(cur_loc); get_byte:=b; end; end; @# function signed_byte:integer; {returns the next byte, signed} var b:eight_bits; begin read_dvi_file(b); incr(cur_loc); if b<128 then signed_byte:=b @+ else signed_byte:=b-256; end; @# function get_two_bytes:integer; {returns the next two bytes, unsigned} var a,@!b:eight_bits; begin read_dvi_file(a); read_dvi_file(b); cur_loc:=cur_loc+2; get_two_bytes:=a*256+b; end; @# function signed_pair:integer; {returns the next two bytes, signed} var a,@!b:eight_bits; begin read_dvi_file(a); read_dvi_file(b); cur_loc:=cur_loc+2; if a<128 then signed_pair:=a*256+b else signed_pair:=(a-256)*256+b; end; @# function get_three_bytes:integer; {returns the next three bytes, unsigned} var a,@!b,@!c:eight_bits; begin read_dvi_file(a); read_dvi_file(b); read_dvi_file(c); cur_loc:=cur_loc+3; get_three_bytes:=(a*256+b)*256+c; end; @# function signed_trio:integer; {returns the next three bytes, signed} var a,@!b,@!c:eight_bits; begin read_dvi_file(a); read_dvi_file(b); read_dvi_file(c); cur_loc:=cur_loc+3; if a<128 then signed_trio:=(a*256+b)*256+c else signed_trio:=((a-256)*256+b)*256+c; end; @# function signed_quad:integer; {returns the next four bytes, signed} var a,@!b,@!c,@!d:eight_bits; begin read_dvi_file(a); read_dvi_file(b); read_dvi_file(c); read_dvi_file(d); cur_loc:=cur_loc+4; if a<128 then signed_quad:=((a*256+b)*256+c)*256+d else signed_quad:=(((a-256)*256+b)*256+c)*256+d; end; @z @x begin set_pos(dvi_file,-1); dvi_length:=cur_pos(dvi_file); @y begin dvi_length:=dvi_blocks*VAX_block_length-1; @z @x begin set_pos(dvi_file,n); cur_loc:=n; @y var @!blk,@!byt:integer; {block and byte number} begin cur_loc:=n; blk:=n div VAX_block_length; byt:=n-(blk*VAX_block_length); @=find@>(dvi_file,blk+1); {VMS starts counting block numbers at 1, not 0} dvi_count:=byt; @z @x and |term_out| for terminal output. @^system dependencies@> @= @!buffer:array[0..terminal_line_length] of ASCII_code; @!term_in:text_file; {the terminal, considered as an input file} @!term_out:text_file; {the terminal, considered as an output file} @y and |term_out| for terminal output. @^system dependencies@> @d term_in==input {the terminal, considered as an input file} @d term_out==output {the terminal, considered as an output file} @= @!buffer:array[0..terminal_line_length] of ASCII_code; @z @x @d update_terminal == break(term_out) {empty the terminal output buffer} @y On Vax/VMS, this is actually not necessary in this context, since |update_terminal| is always called just before a |read|. @d update_terminal == {the terminal output buffer is emptied by |read|} @z @x begin update_terminal; reset(term_in); if eoln(term_in) then read_ln(term_in); k:=0; while (k(k)/get_integer; @z @x if eof(tfm_file) then @y if status(tfm_file)<>0 then @z @x @d default_directory_name=='TeXfonts:' {change this to the correct name} @d default_directory_name_length=9 {change this to the correct length} @y @d default_directory_name=='TEX$FONTS:' {change this to the correct name} @d default_directory_name_length=10 {change this to the correct length} @z @x m:=n-4; @y m:=n; repeat if m=0 then bad_dvi('all 0s'); @.all 0s@> move_to_byte(m); k:=get_byte; decr(m); until k<>0; if k<>223 then bad_dvi('223 byte is ',k:1); @.223 byte is wrong@> @z @x while (m=223)and not eof(dvi_file) do m:=get_byte; @y while ((m=223) or (m=0)) and not eof(dvi_file) do m:=get_byte; @z @x final_end:end. @y close(type_file,@=disposition:=save@>,@=error:=continue@>); final_end:end. @z @x This section should be replaced, if necessary, by changes to the program that are necessary to make \.{DVItype} 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 \.{DVItype} work on Vax/VMS. @== @!VAX_block_length=512; @ @== @!byte_block=packed array [0..VAX_block_length-1] of 0..255; @ 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_direct==@=direct@> @d VAX_fixed==@=fixed@> @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 @> @d VAX_fab_type==@= FAB$TYPE @> @d VAX_rab_type==@= RAB$TYPE @> @d VAX_xab_type==@= XAB$TYPE @> @d VAX_fab_xab==@= FAB$L_XAB @> @d VAX_xab_nxt==@= XAB$L_NXT @> @d VAX_xab_cod==@= XAB$B_COD @> @d VAX_xab_fhc==@= XAB$C_FHC @> @d VAX_xab_ebk==@= XAB$L_EBK @> @ @= @!sixteen_bits= 0..65535; @ @== @!type_file: text; @!command_line:packed array[1..300] of char; @!cmd_len:sixteen_bits; @!cmd_i:integer; @!file_name,@!def_file_name:varying [300] of char; @!ask,@!got_file_name: boolean; @ @= open(output,'SYS$OUTPUT',@=error:=continue@>); {FIX ME! JUNK FOR RUN-TIME BUG} 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 def_file_name:=substr(command_line,cmd_i,cmd_len-cmd_i+1); if got_file_name then begin file_name:=def_file_name+'.DVI'; open(dvi_file,file_name,@=readonly@>,,VAX_direct, VAX_fixed,@=user_action:=@>dvi_open,@=error:=continue@>); ask:=status(dvi_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('DVI file: '); if eof then goto 9999; read_ln(file_name); open(dvi_file,file_name,@=readonly@>,,VAX_direct, VAX_fixed,@=user_action:=@>dvi_open,@=error:=continue@>); ask:=status(dvi_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 def_file_name.VAX_length do if (def_file_name[cmd_len]=']') or (def_file_name[cmd_len]=':') then cmd_i:=cmd_len+1; if cmd_i<=def_file_name.VAX_length then def_file_name:=substr(def_file_name,cmd_i, def_file_name.VAX_length-cmd_i+1); file_name:=def_file_name+'.TYP'; open(type_file,file_name,@=new,32767,disposition:=delete@>, @=error:=continue@>); ask:=status(type_file)>0; if ask then write_ln('Couldn''t open ',file_name); end else ask:=true; while ask do begin write('TYPE file: '); if eof then goto 9999; read_ln(file_name); if file_name.VAX_length=0 then file_name:='SYS$OUTPUT'; open(type_file,file_name,@=new,32767,disposition:=delete@>, @=error:=continue@>); ask:=status(type_file)>0; if ask then write_ln('Couldn''t open ',file_name); end; rewrite(type_file); @ 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; @ Here is how we intervene to find out the length of the |dvi_file|. @= function dvi_open(var fab:VAX_fab_type; var rab:VAX_rab_type):integer; type XAB_ptr = ^VAX_xab_type; var user_status:integer; xab,fhc:XAB_ptr; begin user_status:=@= $OPEN@>(fab); if odd(user_status) then @= $CONNECT@>(rab); xab:=fab.VAX_fab_xab::XAB_ptr; fhc:=nil; while (xab<>nil) and (fhc=nil) do if xab^.VAX_xab_cod=VAX_xab_fhc then fhc:=xab else xab:=xab^.VAX_xab_nxt::XAB_ptr; if fhc<>nil then dvi_blocks:=int(fhc^.VAX_xab_ebk) else dvi_blocks:=0; dvi_open:=user_status; end; @z -------