% unix-c.ch -*-mode: change; webfile: crudetype.web version 3.01;-*- % UNIX changes by Peter King for Berkeley Pascal % modified by RMD for Crudetype version 2 and 3 % % COPYRIGHT ( C ) P.King, Heriot-Watt University, 1988. % % Permission is given to any person to make and distribute copies of this % software, subject to the following conditions: % % 1. All copies of the software must carry an exact copy of this notice. % % 2. This software is distributed free of charge, "AS IS" with absolutely no % guarantee of performance. Any persons receiving or using this software must do % so entirely at their own risk. Neither the authors nor their institutions % accept any liability for any defects of this software, or for any consequential % loss or damage however caused. % % 3. Any person who changes this software must clearly mark it as modified and % add a note describing the changes made. % [0] WEAVE: print changes only @x Module 0; Lines 42 -- 42 \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \def\title{Crudetype for {\mc UNIX } } @z @x Module 4; Lines 213 -- 213 @d banner=='This is Crudetype, Version 3.01, copyright, experimental' @y @d banner=='This is Crudetype, Version 3.01, copyright, experimental WEB2C' @z @x Module 6; Lines 242 -- 242 @ @y @ setpaths(TFMFILEPATHBIT+TEXINPUTPATHBIT); { set up the correct search path for fonts } wl_feed_dist := 1 ; wl_does_cr := true ; @z % add variables for runtime arguments, and to suppress all the non-error % information messages % use_stdin is not yet used, but is a handle for an extension to read from % input ( a UNIX pipe ) % The filenames used by |test_access| are added here. @x Module 7; Lines 253 -- 253 in_i, in_j :integer; {loop index for initializations} @y in_i, in_j :integer; {loop index for initializations} use_stdin : boolean; { read from standard input } @z @x Module 9; Lines 281 -- 281 if ( u<0) then goto exit ; @y if ( u<0) then @= uexit(1) @> ; @z % Change the types @x Module 11; Lines 310 -- 312 @= byte = 0..255 ; i_word = -max_half-1 .. max_half ; @y @= byte = 0..255 ; bite = -128..127 ; { signed ! } i_word = -max_half-1..max_half ; @z @x Module 12; Lines 330 -- 336 the macros and constants defined here. See various change files for examples. @d zchr == chr @d zord == ord @d Q_string == packed array[ first..last:integer] of char @d be_string(#) == set_string( #, buffer) @d set_j_to_length == j := last @y the macros and constants defined here. Here we have to allow for the difference between Pascal strings (which start with index 1) and C strings (index 0). The argument passed to |set_string| is a quoted string constant, so it is a C string. @d zchr == chr @d zord == ord @d Q_string == ccharpointer @d first = 0 @d last == max_string @d be_string(#) == set_string( #, buffer) @d set_j_to_length == j := strlen( ss) -1 @z @x Module 14; Lines 361 -- 361 {Declare |parse_file|} @y procedure parse_file( name: var_string; var dir, nam, ex: var_string) ; var p,r,s: s_ptr ; begin dir := blank; nam := blank; ex := blank; s := name.len ; if ( s>0) then begin p := s_search( name, '/', -s); if ( p>0) then substring( dir, name, 1, p) ; r := s_search( name, '.', -s); if ( r>p) then substring( ex, name, r, s-r+1) else r := s +1 ; substring( nam, name, p+1, r-p-1) ; end; end; @z @x Module 16; Lines 408 -- 408 @d print_ln ==write_ln(printfile ) @y @d print_ln == write_ln(printfile ); if inspection then flush(printfile ) @z % Changes to incorporate UNIX conventions % lower case file names, default to putting the .lpr file in the % same directory as the .dvi file @x Module 18; Lines 429 -- 436 @d block_length = 512 @d same_dir == false @= be_string( '.DVI' ) ; dvi_def := buffer ; be_string( 'TEX$FONTS:.TFM' ) ; tfm_def := buffer ; be_string( 'TEX$GF:.&DGF' ) ; raster_def := buffer ; be_string( '.PRI' ) ; print_ex := buffer ; @y The Unix version of \.{Crudetype} uses ``paths''. @d block_length = 1 @d same_dir == true @= be_string( '.dvi'); dvi_def := buffer ; be_string( '/tex/fonts/.tfm') ; tfm_def := buffer ; be_string( '/tex/gfdir/.&Dgf' ) ; raster_def := buffer ; be_string ( '.lpr' ) ; print_ex := buffer ; @z % More of the UNIX simple minded view of files. % but including the (optional) directory search for .tfm files @x Module 19; Lines 442 -- 443 @= {Declare |open_binary|} @y @d read_access_mode=4 {``read'' mode for |test_access|} @d write_access_mode=2 {``write'' mode for |test_access|} @d default == xwzdefault {|default| is reserved in C} @d fortran == xwzfortran {and apparently so is |fortran|} @d close_binary(#)== do_nothing ; @= function open_binary (var f_f: byte_file; var name: var_string; search_path: integer ): boolean; var cur_name: ccharpointer ; begin cur_name := name.data ; if test_read_access(cur_name, search_path) then begin reset(f_f, cur_name); open_binary := true end else open_binary := false end; @z @x Module 20; Lines 445 -- 446 @ @= rewrite(printfile) ; @y @ @= if inspection then begin be_string ('/dev/tty') ; print_name := buffer ; end ; rewrite(printfile, print_name.data ) ; @z @x Module 21; Lines 452 -- 466 @d get_val( #) == # := s_to_i( #, true) @d prefix == "/" @d got_cl == ( command.len > 0) @d read_command_line( #) == do_nothing @= {Declare |read_command_line| } @# procedure get_command ; var ss: fix_string ; begin ss := blank.data ; read_command_line( ss) ; be_string( ss ) ; command := buffer ; end; @y Unix \P\ does not supply a command line; instead it chops it up and supplies the pieces using two predeclared procedures |argc| and |argv|. It seemed to me that the least messy way to fit this onto the rest of the program is to re-assemble the command line. @d get_val( #) == # := s_to_i( #, true) @d prefix == "-" @d got_cl == ( argc > 1) @d read_command_line( #) == do_nothing @= procedure get_command ; var ss: fix_string ; nn: integer ; tt: var_string ; cc: ccharpointer ; begin command := blank ; for nn := 1 to argc-1 do begin argv( nn, ss) ; cc := ss ; incr(cc); be_string( cc ) ; tt := buffer ; append( command, tt) ; incr( command.len) ; end; end; @z @x Module 27; Lines 560 -- 572 @ If there was no command line, try to send messages to the user at a terminal. This requires nonstandard \PASCAL\ constructions to handle the online interaction. So it may be necessary on some systems to omit the dialog. First, the \.{DVI} file name. @= if can_interact and ( dvi_name.len = 0) then repeat ask_prompt('DVI file name? ') ; get_name( dvi_name) ; until ( dvi_name.len > 0) ; if not open_and_ask(dvi_file, dvi_indx, dvi_name, dvi_def, true) then abort('Couldnt open DVI file') @.Fatal: Couldnt open@> @y @ If there was no command line, try to send messages to the user at a terminal. This requires nonstandard \PASCAL\ constructions to handle the online interaction. So it may be necessary on some systems to omit the dialog. First, the (\.{DVI}) file name. This part is altered to use Unix style path searching. @= if can_interact and ( dvi_name.len = 0) then repeat ask_prompt('DVI file name? ') ; get_name( dvi_name) ; until ( dvi_name.len > 0) ; dvi_indx := TEX_INPUT_PATH ; if not open_and_ask(dvi_file, dvi_indx, dvi_name, dvi_def, true) then abort('couldnt open DVI file') @.Fatal: couldnt open@> @.Opening DVI file@> @z @x Module 28; Lines 574 -- 577 @ But when we come to open a font file, we merely report a failure: @= font_ok := open_and_ask (tfm_file, tfm_indx, tfm_name, tfm_def, true) ; @y @ When we try to open a font file, we search the path specified by the user's environment variable before we report a failure: @= tfm_indx := TFM_FILE_PATH ; font_ok := open_and_ask (tfm_file, tfm_indx, tfm_name, tfm_def, true) ; @z @x Module 30; Lines 631 -- 631 begin incr(k); buffer.data[k]:=term_in^; get(term_in); @y begin incr(k); read( term_in, buffer.data[k]) ; @z % Binary file handling @x Module 33; Lines 661 -- 671 The main input file is the \.{DVI} file. Logically, this is just a stream of 8-bit bytes, with no record or block structure. However VMS \PASCAL\ apparently cannot handle files of this type; so I have adopted the blocking scheme (due to D.R.Fuchs) from the VMS \.{DVItype} change file. But a lot of the code has been rewritten. Some other operating systems use similar blocking schemes; so this code may possibly work without much change. The program deals with two binary file variables: |@!dvi_file| is the main input file that we are printing, and |@!tfm_file| the current font metric file from which character-width information is being read. Each of these has a name and a counter, declared here; also a default name (system dependent, and so declared previously). @y The main input file is the \.{DVI} file. Logically, this is just a stream of 8-bit bytes, with no record or block structure. UNIX \PASCAL\ can happily handle these, except that it treats each byte as a signed quantity, so we do some fudging to make them unsigned. The program deals with two binary file variables: |@!dvi_file| is the main input file that we are printing, and |@!tfm_file| the current font metric file from which character-width information is being read. Each of these has a name declared here. @z % Binary file types @x Module 33; Lines 675 -- 676 @!byte_block=packed array [0..block_length-1] of byte ; @!byte_file= packed file of byte_block; @y @!byte_file= file of bite; @z % Open_and_ask must pass the search path into open_binary @x Module 35; Lines 701 -- 701 success := open_binary(f_f, name ) ; @y success := open_binary(f_f, name, f_c ) ; @z % P. King deleted all the VMS indx stuff, since all the files are (logically) % read one character at a time. I have re-instated it because it is very % useful when debugging. % @x Module 38; Lines 745 -- 776 @d get_real(#) == read_real(# @& file, # @& indx) @= function read_byte(var f_file: byte_file; var f_indx: integer) : byte; begin if eof(f_file) then warn('End of file' ) else begin read_byte := f_file^[f_indx] ; incr(f_indx); if f_indx =block_length then begin get(f_file ); f_indx:=0; end; end; end ; @# procedure skip_bytes(var f_file: byte_file; var f_indx: integer; n:integer); {discard n bytes from |f_file|} begin if n < 0 then abort('Skip_bytes called with negative number'); f_indx := f_indx + n; while( f_indx >= block_length) do begin if eof(f_file) then warn('End of file' ) else get(f_file ); f_indx := f_indx - block_length ; end ; end; @.Error: End of file@> @.Fatal: Skip_bytes...@> @y @d read_real == rr_read_real {|read_real| is Unix \Pascal\ procedure} @d get_real(#) == read_real(# @& file, # @& indx) @= function read_byte(var f_file: byte_file; var f_indx: integer) : byte; var x:bite; begin if eof(f_file) then begin warn('End of file' ) ; read_byte := 0 ; { return some value } end else begin read(f_file,x); if x < 0 then read_byte := x + 256 else read_byte := x ; incr(f_indx); end; end; @# procedure skip_bytes(var f_file: byte_file; var f_indx: integer; n:integer); {discard n bytes from |f_file|} var k:integer; x:bite; begin if n < 0 then abort('skip_bytes called with negative number'); f_indx := f_indx + n; for k:=1 to n do begin if eof(f_file) then warn('End of file' ) else read(f_file, x ); end ; end; @.Error: End of file@> @.Fatal: Skip_bytes...@> @z % SIGH!! variant records @x Module 88; Lines 1543 -- 1549 code_object = packed record breadth: i_word ; case boolean of true: (IM_font: byte ; IM_char: byte ); {Printers font and character} false: (multi: i_word) ; end; @y code_object = packed record breadth: i_word ; IM_font: byte ; IM_char: byte; {Printers font and character} multi: i_word ; end; @z @x Module 99; Lines 1701 -- 1709 trio = 1..3 ; lig_thing = packed record case trio of 1: (v_move: i_word ; h_move: i_word) ; 2: (symbol: code_object) ; 3: (num : i_word ; guard : i_word) ; end; @y trio = 1..3 ; lig_thing = packed record v_move: i_word ; h_move: i_word; symbol: code_object; num : i_word ; guard : i_word; end; @z @x Module 132; Lines 2235 -- 2236 begin if ( s.len <> t.len ) then equals := false else equals := ( s.data = t.data) ; @y var c, d: ccharpointer ; begin c := s.data; incr(c) ; d := t.data; incr(d) ; if ( s.len <> t.len ) then equals := false else equals := (strncmp(c,d, s.len) = 0) ; @z % SIGH! with statements @x Module 158; Lines 2745 -- 2747 with lig_buff[2*i].symbol do if (print_width < -breadth ) and (breadth > -30000 ) then print_width := -breadth ; @y if (print_width < -lig_buff[2*i].symbol.breadth ) and (lig_buff[2*i].symbol.breadth > -30000 ) then print_width := -lig_buff[2*i].symbol.breadth ; @z @x Module 172; Lines 2937 -- 2941 with image( run_ptr) do begin {write the data into it} hpos := Set_h ; Old_h := Set_h ; vpos := Set_v ; Old_v := Set_v ; symbol := cod ; end; @y begin {write the data into it} image( run_ptr).hpos := Set_h ; Old_h := Set_h ; image( run_ptr).vpos := Set_v ; Old_v := Set_v ; image( run_ptr).symbol := cod ; end; @z @x Module 180; Lines 3061 -- 3068 page_record = packed record prox: link ; case boolean of true: ( hpos : i_word; vpos: i_word; symbol: code_object ) ; false: ( down : link) ; end; @y page_record = packed record prox: link ; hpos : i_word; vpos: i_word; symbol: code_object; down : link ; end; @z @x Module 186; Lines 3156 -- 3175 with image(line_ptr) do begin PR_h_next := hpos - H_shunt ; if not b_space_absolute and not b_space_by_string and (PR_h_next < PR_h) then begin if (PR_h < left_stop) then warn ('Negative H-pos') ; if not batch_view then begin next(overflow) := line_ptr ; advance(overflow) ; end; advance(line_ptr) ; end else begin @; if symbol.IM_font <> PR_font then set_PR_font(symbol.IM_font); print(zchr(symbol.IM_char )) ; PR_h := PR_h + symbol.breadth ; step_wipe(line_ptr ) ; end ; end; @.Error: Negative H-pos@> @y begin PR_h_next := image(line_ptr).hpos - H_shunt ; if not b_space_absolute and not b_space_by_string and (PR_h_next < PR_h) then begin if (PR_h < left_stop) then warn ('negative H-pos') ; if not batch_view then begin next(overflow) := line_ptr ; advance(overflow) ; end ; advance(line_ptr) ; end else begin @; if image(line_ptr).symbol.IM_font <> PR_font then set_PR_font( image(line_ptr).symbol.IM_font); print(zchr( image(line_ptr).symbol.IM_char )) ; PR_h := PR_h + image(line_ptr).symbol.breadth ; step_wipe(line_ptr ) ; end ; end; @.negative H-pos@> @z % UNIX writeln moves you down a line @x Module 207; Lines 3472 -- 3472 device_ID := 'Lineprinter '; {Pad to 12 chars} @y vstrcpy (device_ID, 'Lineprinter ' ); {Pad to 12 chars} @z @x Module 207; Lines 3489 -- 3489 wl_feed_dist := 0 ; @y wl_feed_dist := 1 ; @z @x Module 210; Lines 3543 -- 3543 device_ID := 'screenview '; {Pad to 12 chars} @y vstrcpy (device_ID, 'screenview ' ); {Pad to 12 chars} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% END OF FILE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%