|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T g
Length: 23957 (0x5d95) Types: TextFile Names: »gftodvi.BSD4_n.ch«
└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89 └─⟦this⟧ »./tex82/Unsupported/MFpxl/mfware/gftodvi.BSD4_n.ch« └─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12 └─⟦beba6c409⟧ »unix3.0/Unsupported.tar.Z« └─⟦25c524ae4⟧ └─⟦this⟧ »Unsupported/MFpxl/mfware/gftodvi.BSD4_n.ch«
% $Header: gftodvi.ch,v 1.7.1.5 86/02/01 15:29:58 richards Released $ % Change file for the GFtoDVI processor, for use on Berkeley UNIX systems. % History: % % $Log: gftodvi.ch,v $ % Revision 1.7.1.5 86/02/01 15:29:58 richards % Released again for MF 1.0 package % % Revision 1.7.1.4 86/02/01 15:06:50 richards % Added: % <nl> at end of successful run % % Revision 1.7.1.3 86/01/27 16:39:48 richards % Fixed: % syntax error in previous edits % % Revision 1.7.1.2 86/01/27 15:55:58 richards % Added: % dvi_buf_type declaration and redefined dvi_buf[] in % terms of it, so we can use it as a parameter to b_write_buf() % % Revision 1.7.1.1 86/01/27 15:39:10 richards % First edit to use new binary I/O routines % % Revision 1.7 85/10/21 21:55:50 richards % Released for GFtoDVI 1.7 % % Revision 1.3.7.1 85/10/18 22:59:01 richards % Updated for GFtoDVI Version 1.7 (Distributed w/ MF84 Version 0.9999) % % Revision 1.3.5.1 85/10/09 17:02:35 richards % First draft to run at 1.5 level % % Revision 1.3 85/05/27 21:15:30 richards % Updated for GFtoDVI Version 1.3 (Distributed w/ MF84 Version 0.91) % % Revision 1.2 85/04/25 19:33:30 richards % Updated to GFtoDVI Version 1.2 (Distributed w/ MF84 Version 0.81) % % Revision 1.1 85/03/03 21:47:17 richards % Updated for GF utilities distributed with MF Version 0.77 % % Revision 1.0 84/12/16 22:38:22 richards % Updated for GFtoDVI Version 1.0 (New GF file format) % % Revision 0.6 84/12/05 13:32:01 richards % Updated for GFtoDVI Version 0.6; merged in changes from sdcarl!rusty % % Note: still has BUGFIX in section 199 to keep GFtoDVI from trying % to use non-existant characters in a gray font % % Revision 0.3 84/11/17 23:51:56 richards % Base version for GFtoDVI Version 0.3 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [0] WEAVE: print changes only %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{GF\lowercase{to}DVI changes for Berkeley {\mc UNIX}} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [1] Change banner string %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d banner=='This is GFtoDVI, Version 1.7' {printed when the program starts} @y @d banner=='This is GFtoDVI, Version 1.7 for Berkeley UNIX' {printed when the program starts} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [3] Add gftodvi_ext.h, standard input to program header %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p program GF_to_DVI(@!output); label @<Labels in the outer block@>@/ const @<Constants in the outer block@>@/ type @<Types in the outer block@>@/ var @<Globals in the outer block@>@/ procedure initialize; {this procedure gets things started properly} var @!i,@!j,@!m,@!n:integer; {loop indices for initializations} begin print_ln(banner);@/ @<Set initial values@>@/ end; @y @p program GF_to_DVI(@!input,@!output); label @<Labels in the outer block@>@/ const @<Constants in the outer block@>@/ type @<Types in the outer block@>@/ var @<Globals in the outer block@>@/ @\@=#include "gftodvi_ext.h"@>@\ {declarations for external C procedures} procedure initialize; {this procedure gets things started properly} var @!i,@!j,@!m,@!n:integer; {loop indices for initializations} begin print_ln(banner);@/ @<Set initial values@>@/ end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [5] Enlarge file_name_size to 256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @<Constants...@>= @!max_labels=2000; {maximum number of labels and dots per character} @!pool_size=10000; {maximum total length of labels and other strings} @!max_strings=1100; {maximum number of labels and other strings} @!terminal_line_length=150; {maximum number of characters input in a single line of input from the terminal} @!file_name_size=50; {a file name shouldn't be longer than this} @!font_mem_size=1000; {space for font metric data} @!dvi_buf_size=800; {size of the output buffer; must be a multiple of 8} @!widest_row=8192; {maximum number of pixels per row} @y @<Constants...@>= @!max_labels=2000; {maximum number of labels and dots per character} @!pool_size=10000; {maximum total length of labels and other strings} @!max_strings=1100; {maximum number of labels and other strings} @!terminal_line_length=150; {maximum number of characters input in a single line of input from the terminal} @!file_name_size=256; {a file name shouldn't be longer than this} @!font_mem_size=1000; {space for font metric data} @!dvi_buf_size=800; {size of the output buffer; must be a multiple of 8} @!widest_row=8192; {maximum number of pixels per row} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [8] Add <nl> to end of abort() message %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d abort(#)==begin print(' ',#); jump_out; @y @d abort(#)==begin print_ln(' ',#); jump_out; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [15] change update_terminal to flush(), change def'n of term_in %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x Since the terminal is being used for both input and output, some systems need a special routine to make sure that the user can see a prompt message before waiting for input based on that message. (Otherwise the message may just be sitting in a hidden buffer somewhere, and the user will have no idea what the program is waiting for.) We shall call a system-dependent subroutine |update_terminal| in order to avoid this problem. @d update_terminal == break(output) {empty the terminal output buffer} @<Glob...@>= @!buffer:array[0..terminal_line_length] of 0..255; @!term_in:text_file; {the terminal, considered as an input file} @y Since the terminal is being used for both input and output, some systems need a special routine to make sure that the user can see a prompt message before waiting for input based on that message. (Otherwise the message may just be sitting in a hidden buffer somewhere, and the user will have no idea what the program is waiting for.) We shall call a system-dependent subroutine |update_terminal| in order to avoid this problem. @^system dependencies@> @d update_terminal == flush(output) {empty the terminal output buffer} @d term_in == input {standard input} @<Glob...@>= @!buffer:array[0..terminal_line_length] of 0..255; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [16] Remove reset(term_in) from input_ln %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ A global variable |line_length| records the first buffer position after the line just read. @^system dependencies@> @p procedure input_ln; {inputs a line from the terminal} begin update_terminal; reset(term_in); if eoln(term_in) then read_ln(term_in); line_length:=0; while (line_length<terminal_line_length)and not eoln(term_in) do begin buffer[line_length]:=xord[term_in^]; incr(line_length); get(term_in); end; end; @y @ A global variable |line_length| records the first buffer position after the line just read. @^system dependencies@> @p procedure input_ln; {inputs a line from the terminal} begin update_terminal; if eoln(term_in) then read_ln(term_in); line_length:=0; while (line_length<terminal_line_length)and not eoln(term_in) do begin buffer[line_length]:=xord[term_in^]; incr(line_length); get(term_in); end; end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [45] Change type of binary file for binary (byte) files %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x We shall stick to simple \PASCAL\ in this program, for reasons of clarity, even if such simplicity is sometimes unrealistic. @<Types ...@>= @!eight_bits=0..255; {unsigned one-byte quantity} @!byte_file=packed file of eight_bits; {files that contain binary data} @y For Berkeley Pascal, we need to use `|packed file of -128..127|' to read and write binary bytes. @<Types ...@>= @!eight_bits=0..255; {unsigned one-byte quantity} @!UNIX_file_name=packed array[1..file_name_size] of char; @!byte_file=record@/ stdio_ptr: ^integer; {pointer for stdio FILE struct} loc_ptr: ^integer; {pointer to byte position ptr to keep in sync with file} file_name: UNIX_file_name; {file name saved by open routines} end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [47] Modify file open routines to match binary I/O library %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x variable that specifies the file name. @^system dependencies@> @p procedure open_gf_file; {prepares to read packed bytes in |gf_file|} begin reset(gf_file,name_of_file); cur_loc:=0; end; @# procedure open_tfm_file; {prepares to read packed bytes in |tfm_file|} begin reset(tfm_file,name_of_file); end; @# procedure open_dvi_file; {prepares to write packed bytes in |dvi_file|} begin rewrite(dvi_file,name_of_file); end; @y variable that specifies the file name. Under {\mc UNIX}, we use an external library of C routines to read and write binary files. The library routine |b_open_in| is used to open a file for input. It also will search a series of directories to locate a file, if so directed by parameter. @^system dependencies@> @d no_file_path=0 {do no path searching} @d TeX_font_file_path=3 {path specifier for \.{TFM} files} @p procedure open_gf_file; {prepares to read packed bytes in |gf_file|} var i: 1..file_name_size; begin if not b_open_in(gf_file, name_of_file, no_file_path) then begin while (i < file_name_size) and (name_of_file[i] <> ' ') do@/ incr(i);@/ abort('Can''t open GF file: ', name_of_file:i); end; b_set_ptr(gf_file, cur_loc);@/ cur_loc:=0; end; @# procedure open_tfm_file; {prepares to read packed bytes in |tfm_file|} var i: 1..file_name_size; begin if not b_open_in(tfm_file, name_of_file, TeX_font_file_path) then begin i:=1; while (i < file_name_size) and (name_of_file[i] <> ' ') do@/ incr(i); abort('Error opening TFM file: ', name_of_file:i); end; end; @# procedure open_dvi_file; {prepares to write packed bytes in |dvi_file|} var i: 1..file_name_size; begin if not b_open_out(dvi_file, name_of_file) then begin i:=1; while (i < file_name_size) and (name_of_file[i] <> ' ') do@/ incr(i); abort('Error opening DVI file: ', name_of_file:i); end; end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [48] Change type declaration of name_of_file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!name_of_file:packed array[1..file_name_size] of char; {external file name} @y @!name_of_file:UNIX_file_name; {external file name} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [50] Use modified routines to access tfm_file using b_read_unsigned() %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p procedure read_tfm_word; begin read(tfm_file,b0); read(tfm_file,b1); read(tfm_file,b2); read(tfm_file,b3); end; @y @p procedure read_tfm_word; begin b0:=b_read_unsigned(tfm_file);@/ b1:=b_read_unsigned(tfm_file);@/ b2:=b_read_unsigned(tfm_file);@/ b3:=b_read_unsigned(tfm_file); end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [51] Use modified routines to access gf_file using b_read_x_xxx() %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ We shall use another set of simple functions to read the next byte or bytes from |gf_file|. There are four possibilities, each of which is treated as a separate function in order to minimize the overhead for subroutine calls. @^system dependencies@> @p function get_byte:integer; {returns the next byte, unsigned} var b:eight_bits; begin if eof(gf_file) then get_byte:=0 else begin read(gf_file,b); incr(cur_loc); get_byte:=b; end; end; @# function get_two_bytes:integer; {returns the next two bytes, unsigned} var a,@!b:eight_bits; begin read(gf_file,a); read(gf_file,b); cur_loc:=cur_loc+2; get_two_bytes:=a*256+b; end; @# function get_three_bytes:integer; {returns the next three bytes, unsigned} var a,@!b,@!c:eight_bits; begin read(gf_file,a); read(gf_file,b); read(gf_file,c); cur_loc:=cur_loc+3; get_three_bytes:=(a*256+b)*256+c; end; @# function signed_quad:integer; {returns the next four bytes, signed} var a,@!b,@!c,@!d:eight_bits; begin read(gf_file,a); read(gf_file,b); read(gf_file,c); read(gf_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 @ We shall use another set of simple functions to read the next byte or bytes from |gf_file|. There are four possibilities, each of which is treated as a separate function in order to minimize the overhead for subroutine calls. We redefine the \.{GFtoDVI} routines in terms of our external binary routines to avoid double subroutine call overhead. @^system dependencies@> @d get_byte==b_read_unsigned(gf_file) @d signed_byte==b_read_signed(gf_file) @d get_two_bytes==b_read_2_unsigned(gf_file) @d get_three_bytes==b_read_3_unsigned(gf_file) @d signed_quad==b_read_4_signed(gf_file) @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [52] change definition of min/max_quarterword %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x the more general memory words of \TeX. On some machines it is necessary to define |min_quarterword=-128| and |max_quarterword=127| in order to pack four quarterwords into a single word.) @^system dependencies@> @d min_quarterword=0 {change this to allow efficient packing, if necessary} @d max_quarterword=255 {ditto} @y the more general memory words of \TeX. With Berkeley {\mc UNIX} Pascal, we need to use the |-128..127| range to pack an integer subrange into a byte. @^system dependencies@> @d min_quarterword=-128 {change this to allow efficient packing, if necessary} @d max_quarterword=127 {ditto} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [87] change ">" and ":" to "/" in file name scanning %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ The file names we shall deal with for illustrative purposes have the following structure: If the name contains `\.>' or `\.:', the file area consists of all characters up to and including the final such character; otherwise the file area is null. If the remaining file name contains `\..', the file extension consists of all such characters from the first remaining `\..' to the end, otherwise the file extension is null. @^system dependencies@> We can scan such file names easily by using two global variables that keep track of the occurrences of area and extension delimiters: @<Glob...@>= @!area_delimiter:pool_pointer; {the most recent `\.>' or `\.:', if any} @!ext_delimiter:pool_pointer; {the relevant `\..', if any} @y @ The file names we shall deal with for illustrative purposes have the following structure: If the name contains `\./', the file area consists of all characters up to and including the final such character; otherwise the file area is null. If the remaining file name contains `\..', the file extension consists of all such characters from the first remaining `\..' to the end, otherwise the file extension is null. @^system dependencies@> We can scan such file names easily by using two global variables that keep track of the occurrences of area and extension delimiters: @<Glob...@>= @!area_delimiter:pool_pointer; {the most recent `\./', if any} @!ext_delimiter:pool_pointer; {the relevant `\..', if any} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [88] change home_font_area to null_string (b_open_in provides path) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ Font metric files whose areas are not given explicitly are assumed to appear in a standard system area called |home_font_area|. This system area name will, of course, vary from place to place. The program here sets it to `\.{TeXfonts:}'. @^system dependencies@> @.TeXfonts@> @<Initialize the strings@>= l:=9; init_str9("T")("e")("X")("f")("o")("n")("t")("s")(":")(home_font_area);@/ @y @ Font metric files whose areas are not given explicitly are assumed to appear in a standard system area called |home_font_area|. This system area name will, of course, vary from place to place. Under the Berkeley {\mc UNIX} version, we set |home_font_area| to |null_string| because the default areas to search for \.{TFM} files are built into the routine |test_access|. @^system dependencies@> @<Initialize the strings@>= l:=0; init_str0(home_font_area);@/ @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [90] change more_name to understand UNIX file name paths %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p function more_name(@!c:ASCII_code):boolean; begin if c=" " then more_name:=false else begin if (c=">")or(c=":") then begin area_delimiter:=pool_ptr; ext_delimiter:=0; end else if (c=".")and(ext_delimiter=0) then ext_delimiter:=pool_ptr; str_room(1); append_char(c); {contribute |c| to the current string} more_name:=true; end; end; @y @p function more_name(@!c:ASCII_code):boolean; begin if c=" " then more_name:=false else begin if (c="/") then begin area_delimiter:=pool_ptr; ext_delimiter:=0; end else if (c=".")and(ext_delimiter=0) then ext_delimiter:=pool_ptr; str_room(1); append_char(c); {contribute |c| to the current string} more_name:=true; end; end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [94] change start_gf to get file name from command line arguments %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ The |start_gf| procedure prompts the user for the name of the generic font file to be input. It opens the file, making sure that some input is present; then it opens the output file. Although this routine is system-independent, it should probably be modified to take the file name from the command line (without an initial prompt), on systems that permit such things. @p procedure start_gf; label found,done; begin loop@+begin print_nl('GF file name: '); input_ln; @.GF file name@> buf_ptr:=0; buffer[line_length]:="?"; while buffer[buf_ptr]=" " do incr(buf_ptr); if buf_ptr<line_length then begin @<Scan the file name in the buffer@>; if cur_ext=null_string then cur_ext:=gf_ext; pack_file_name(cur_name,cur_area,cur_ext); open_gf_file; if not eof(gf_file) then goto found; print_nl('Oops... I can''t find file '); print(name_of_file); @.Oops...@> @.I can't find...@> end; end; found:job_name:=cur_name; pack_file_name(job_name,null_string,dvi_ext); open_dvi_file; end; @y @ The |start_gf| procedure obtains the name of the generic font file to be input from the command line. It opens the file, making sure that some input is present; then it opens the output file. @p procedure start_gf; label done; var arg_buffer: packed array [1..file_name_size] of char; arg_buf_ptr: 1..file_name_size; begin if (argc < 1) or (argc > 2) then abort('Usage: gftodvi [GF-file]'); if argc = 1 then begin print_nl('GF file name: '); input_ln; @.GF file name@> end else begin argv(1, arg_buffer); arg_buffer[file_name_size] := ' '; arg_buf_ptr := 1; line_length := 0; while (arg_buf_ptr < file_name_size) and (arg_buffer[arg_buf_ptr] = ' ') do incr(arg_buf_ptr); while (arg_buf_ptr < file_name_size) and (line_length < terminal_line_length) and (arg_buffer[arg_buf_ptr] <> ' ') do begin buffer[line_length] := xord[arg_buffer[arg_buf_ptr]]; incr(line_length); incr(arg_buf_ptr); end; end; buf_ptr:=0; buffer[line_length]:="?"; while buffer[buf_ptr]=" " do incr(buf_ptr); if buf_ptr<line_length then begin @<Scan the file name in the buffer@>; if cur_ext=null_string then cur_ext:=gf_ext; pack_file_name(cur_name,cur_area,cur_ext); open_gf_file; end; job_name:=cur_name; pack_file_name(job_name,null_string,dvi_ext); open_dvi_file; end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [98] load_fonts: % KLUDGE: SUN Pascal compiler incorrectly aligns four_quarters data % item on stack, which causes long reference to odd address. % FIX: rearrange four_quarter data to follow aligned long (int) data. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @<Declare the procedure called |load_fonts|@>= procedure load_fonts; label done,continue,found,not_found; var @!f:internal_font_number; @!i:four_quarters; {font information word} @!j,@!k,@!v:integer; {registers for initializing font tables} @!m:title_font..slant_font+area_code; {keyword found} @!n1:0..longest_keyword; {buffered character being checked} @y @<Declare the procedure called |load_fonts|@>= procedure load_fonts; label done,continue,found,not_found; var @!f:internal_font_number; @!j,@!k,@!v:integer; {registers for initializing font tables} @!i:four_quarters; {font information word} @!m:title_font..slant_font+area_code; {keyword found} @!n1:0..longest_keyword; {buffered character being checked} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [104] Declare "dvi_buf_type" so we can use it in external routine % interface declarations %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!dvi_index=0..dvi_buf_size; {an index into the output buffer} @y @!dvi_index=0..dvi_buf_size; {an index into the output buffer} @!dvi_buf_type=array[dvi_index] of eight_bits; {declared so we can use it as a parameter type} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [105] Redeclare dvi_buf[] in terms of dvi_buf_type %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!dvi_buf:array[dvi_index] of eight_bits; {buffer for \.{DVI} output} @y @!dvi_buf:dvi_buf_type; {buffer for \.{DVI} output} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [107] write_dvi is now an external C routine %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p procedure write_dvi(@!a,@!b:dvi_index); var k:dvi_index; begin for k:=a to b do write(dvi_file,dvi_buf[k]); end; @y For Berkeley {\mc UNIX}, this is going to be handled by an external procedure, |b_write_buf|, which will do the output using |fwrite|. @d write_dvi(#)==b_write_buf(dvi_file,dvi_buf,#) @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [217] call set_paths before gf_start to initialize paths. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p begin initialize; {get all variables initialized} @<Initialize the strings@>; start_gf; {open the input and output files} @y @p begin initialize; {get all variables initialized} @<Initialize the strings@>; set_paths; {initialize paths for \.{TFM} files from environment if needed} start_gf; {open the input and output files} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [217] finish normal end with <nl> on terminal %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x cur_gf:=get_byte; str_ptr:=init_str_ptr; pool_ptr:=str_start[str_ptr]; end; final_end:end. @y cur_gf:=get_byte; str_ptr:=init_str_ptr; pool_ptr:=str_start[str_ptr]; end; final_end:print_ln(' '); end. @z