DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T g

⟦a9b98ef0b⟧ TextFile

    Length: 20631 (0x5097)
    Types: TextFile
    Names: »gftopxl.BSD4_n.ch«

Derivation

└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89
    └─⟦this⟧ »./tex82/Unsupported/MFpxl/mfware/gftopxl.BSD4_n.ch« 
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12
    └─⟦beba6c409⟧ »unix3.0/Unsupported.tar.Z« 
        └─⟦25c524ae4⟧ 
            └─⟦this⟧ »Unsupported/MFpxl/mfware/gftopxl.BSD4_n.ch« 

TextFile

% $Header: gftopxl.ch,v 2.2  86/12/06  11:03:12  mackay Released $

%   Change file for the GFtoPXL processor, for use on Berkeley UNIX systems.

% History:
%
% $Log:	gftopxl.ch,v $
% Revision 2.2  86/12/06  11:03:12  mackay
% Changed:
% 	Version change to 2.2 to incorporate William Lefebvre's corrections
% 	for all blank rasters.  Change to way out .?pxl file is named so
%	that it goes to the current working directory by default.
% 
% Revision 2.1.1.2  86/01/29  00:54:19  richards
% Changed:
% 	file name construction to skip pathname prefixes before looking
% 	for '.' in name
% 
% Revision 2.1.1.1  86/01/21  22:33:47  richards
% Updated to incorporate new binary I/O routines
% 
% Revision 2.1  85/03/03  21:43:35  richards
% Updated to GF utilities distributed with MF Version 0.77
% 	(New GF file format)
% 
% Revision 2.0  84/12/16  22:40:15  richards
% Updated for GFtoPXL Version 2.0 (New GF file format)
% 
% Revision 1.1  84/12/06  03:14:54  richards
% Updated for GFtoPXL Version 1.1; merged in changes from sdcarl!rusty
% 
% Revision 1.0  84/11/17  23:53:20  richards
% Base version for GFtoPXL Version 1.0
% 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [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}PXL changes for Berkeley {\mc UNIX}}
@z
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [1] Change banner string
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@x
@d banner=='This is GFtoPXL, Version 2.2' {printed when the program starts}
@y
@d banner=='This is GFtoPXL, Version 2.2 for Berkeley UNIX'
                                         {printed when the program starts}
@z

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [4] Delete files from program header,
%	Add gftopxl_ext.h,
%	have initialize() setup file names from command line
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@x
@p program GF_to_PXL(@!gf_file,@!pxl_file,@!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:integer; {loop index for initializations}
  begin print_ln(banner);@/
  @<Set initial values@>@/
  end;
@y
@p program GF_to_PXL(@!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 "gftopxl_ext.h"@>@\ {declarations for external C procedures}
@^system dependencies@>
procedure initialize; {this procedure gets things started properly}
  var i:integer; {loop index for initializations}
  begin print_ln(banner);@/
  @<Set initial values@>@/
  @<Parse command line arguments@>@/
  end;
@z

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [6] Add file_name_size to constants
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@x
@<Constants...@>=
@!line_length=79; {bracketed lines of output will be at most this long}
@!terminal_line_length=150; {maximum number of characters input in a single
  line of input from the terminal}
@!max_glyph_no=127; {maximum glyph number in font, later change to 255}
@!top_pixel=700; {boundary of pixel image of glyph}
@!bot_pixel=-250;
@!left_pixel=-250;
@!right_pixel=750;
@y
@<Constants...@>=
@!line_length=79; {bracketed lines of output will be at most this long}
@!terminal_line_length=150; {maximum number of characters input in a single
  line of input from the terminal}
@!max_glyph_no=127; {maximum glyph number in font, later change to 255}
@!top_pixel=700; {boundary of pixel image of glyph}
@!bot_pixel=-250;
@!left_pixel=-250;
@!right_pixel=750;@/
@!file_name_size=256; {max length of file name on command line}
@z

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [8] modify abort to append <nl> to end of message
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@x
@d abort(#)==begin print(' ',#); jump_out;
@y
@d abort(#)==begin print_ln(' ',#); jump_out;
@z

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [10] Add definition of "update_terminal" to flush output
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@x
The |input_ln| routine waits for the user to type a line at his or her
terminal; then it puts ASCII-code equivalents for the characters on that line
into the |buffer| array. The |term_in| file is used for terminal input,
and |term_out| for terminal output.
@^system dependencies@>

@<Glob...@>=
@!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
The |input_ln| routine waits for the user to type a line at his or her
terminal; then it puts ASCII-code equivalents for the characters on that line
into the |buffer| array. The |term_in| file is used for terminal input,
and |term_out| for terminal output.  Output written to the terminal should
be forced to appear by |update_terminal|, in case the Pascal system buffers
the output.
@^system dependencies@>

@d update_terminal==flush(output);

@<Glob...@>=
@!buffer:array[0..terminal_line_length] of ASCII_code;
@z	

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [24] Change type of binary file for gf_file
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@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 use a set of library routines to do binary
input and output.  These routines don't use the standard Pascal file
structures, but rather a ``magic cookie'' stored in a record, to
identify the file.  Therefore, we redefine |byte_file| to be a record
type.  We also add a new type, |UNIX_file_name|, to be used
when passing the name of the file to the file opening routines.

@<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; {copy of file name saved when file opened}
end;
@z

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [25] Add gf_name and pxl_name declarations
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@x
@ The program deals with two binary file variables: |gf_file| is the
input file that we are translating into \.{PXL} format, to be written
on |pxl_file|.

@<Glob...@>=
@!gf_file:byte_file; {the stuff we are \.{GFtoPXL}ing}
@!pxl_file:byte_file; {the stuff we have \.{GFtoPXL}ed}
@y
@ The program deals with two binary file variables: |gf_file| is the
input file that we are translating into \.{PXL} format, to be written
on |pxl_file|.
We also declare here the array used to hold the name of |gf_file| and
|pxl_file|.

@<Glob...@>=
@!gf_file:byte_file; {the stuff we are \.{GFtoPXL}ing}
@!gf_name: UNIX_file_name;
@!pxl_file:byte_file; {the stuff we have \.{GFtoPXL}ed}
@!pxl_name: UNIX_file_name;
@z

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [26] We use a new routine to open binary files, redefine the existing
%	opens in terms of the new routines.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@x
@ To prepare the |gf_file| for input, we |reset| it.

@p procedure open_gf_file; {prepares to read packed bytes in |gf_file|}
begin reset(gf_file);
cur_loc:=0;
end;
@y
@ To prepare the |gf_file| for input, we use an external library routine
that is coupled to the byte input and output library routines.  Procedure
|b_set_ptr| makes the library know about |cur_loc| so it will be kept
in sync with the byte offset for that file.

@d NO_path_searching == 0

@p procedure open_gf_file; {prepares to read packed bytes in |gf_file|}
begin if not b_open_in(gf_file, gf_name, NO_path_searching) then@/
    abort('Unable to open GF file for input');
b_set_ptr(gf_file, cur_loc);@/
cur_loc:=0;
end;
@z

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [27] Redefine open_pxl_file to use b_open_out
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@x
@ To prepare the |pxl_file| for output, we |rewrite| it.

@p procedure open_pxl_file; {prepares to write packed bytes in |pxl_file|}
begin rewrite(pxl_file);
end;
@y
@ To prepare the |pxl_file| for output, we call our friendly library again.

@p procedure open_pxl_file; {prepares to write packed bytes in |pxl_file|}
var
@!name_len: integer;
@!i,j,k: integer; 
@!started_number: boolean;
begin@/
if not pxl_name_ready then
@<Construct |pxl_name| from |gf_name| and |magnification|@>@/
if not b_open_out(pxl_file, pxl_name) then begin
    name_len := 1;
    while (name_len < file_name_size) and (not (pxl_name[name_len] = ' ')) do@/
        name_len := name_len + 1;
    abort('Unable to open ', pxl_name:name_len, ' for output');
    end;@/
b_set_ptr(pxl_file, pxl_byte_no);
end;
@z

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [29] Use modified routines to access gf_file
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@x
@ We shall use a set of simple functions to read the next byte or
bytes from |gf_file|. There are seven 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 signed_byte:integer; {returns the next byte, signed}
var b:eight_bits;
begin read(gf_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(gf_file,a); read(gf_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(gf_file,a); read(gf_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(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_trio:integer; {returns the next three bytes, signed}
var a,@!b,@!c:eight_bits;
begin read(gf_file,a); read(gf_file,b); read(gf_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(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 a set of simple functions to read the next byte or
bytes from |gf_file|. There are seven possibilities, each of which is
treated as a separate function in order to minimize the overhead for
subroutine calls.  We use an external C routines in the {\mc UNIX} version
to read from |gf_file| because we need random access to that file, and
for efficiency, neither of which is available from the standard Berkeley
Pascal run-time library.
@^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 signed_pair == b_read_2_signed(gf_file)
@d get_three_bytes == b_read_3_unsigned(gf_file)
@d signed_trio == b_read_3_signed(gf_file)
@d signed_quad == b_read_4_signed(gf_file)
@z

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [30] change pxl_byte from macro to procedure that calls b_write_byte
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@x
@ Most info in the |pxl_file| comes in words, but we have to write it
as bytes and halfwords occasionally.

@d pxl_byte(#)==begin write(pxl_file,#); incr(pxl_byte_no); end

@p procedure pxl_halfword(@!w:integer);
begin
if w<0 then w:=w+@"10000;
pxl_byte(w div @"100);
pxl_byte(w mod @"100);
end;
@#
procedure pxl_word(@!w:integer);
begin
if w>0 then pxl_byte(w div @"1000000)
else begin
  w:=w+@"40000000;
  w:=w+@"40000000;
  pxl_byte((w div @"1000000) + 128);
  end;
pxl_byte((w div @"10000) mod @"100);
pxl_byte((w div @"100) mod @"100);
pxl_byte(w mod @"100);
end;
@y
@ Most info in the |pxl_file| comes in words, but we have to write it
as bytes and halfwords occasionally.  For Berkeley {\mc UNIX}, we changed
these routines into external C routines.

@d pxl_byte(#) == b_write_byte(pxl_file, #)
@d pxl_halfword(#) == b_write_2_bytes(pxl_file, #)
@d pxl_word(#) == b_write_4_bytes(pxl_file, #)
@z

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [31] change gf_length and move_to_byte to match C routines
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@x
Such routines are, of course, highly system dependent. They are implemented
here in terms of two assumed system routines called |set_pos| and |cur_pos|.
The call |set_pos(f,n)| moves to item |n| in file |f|, unless |n| is
negative or larger than the total number of items in |f|; in the latter
case, |set_pos(f,n)| moves to the end of file |f|.
The call |cur_pos(f)| gives the total number of items in |f|, if
|eof(f)| is true; we use |cur_pos| only in such a situation.

@p function gf_length:integer;
begin set_pos(gf_file,-1); gf_length:=cur_pos(gf_file);
end;
@#
procedure move_to_byte(n:integer);
begin set_pos(gf_file,n); cur_loc:=n;
end;
@y

Such routines are, of course, highly system dependent. They are implemented
here in terms of two external C routines called |b_seek| and |b_file_len|,
which work together with external routines |b_read_byte| and company.
The call |b_seek(f,n)| moves to byte |n| in file |f|, unless |n| is
larger than the total number of items in |f|; in the latter
case, |b_seek(f,n)| moves to the end of file |f|.
The call |b_file_len(f)| gives the total number of bytes in |f|, 
assuming that |f| has been opened via |b_open|.

@d gf_length == b_file_len(gf_file)
@d move_to_byte(#) == b_seek(gf_file, #)
@z

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [43] change eof(gf_file) tests to b_eof(gf_file)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@x
if eof(gf_file) then bad_gf('the file ended prematurely');
@y
if b_eof(gf_file) then bad_gf('the file ended prematurely');
@z

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [55] change eof(gf_file) tests to b_eof(gf_file)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@x
while (m=223)and not eof(gf_file) do m:=get_byte;
if not eof(gf_file) then bad_gf('signature in byte ',cur_loc-1:1,
@y
while (m=223)and not b_eof(gf_file) do m:=get_byte;
if not b_eof(gf_file) then bad_gf('signature in byte ',cur_loc-1:1,
@z

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [67] print <nl> after final summary
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@x
if total_chars<>1 then print('s');
print(' altogether');
@y
if total_chars<>1 then print('s');
print_ln(' altogether');
@z

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [70] flush output when announcing completion of a character
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@x
@.char ended unexpectedly@>
    print(']');
    incr(total_chars);
@y
@.char ended unexpectedly@>
    print(']'); update_terminal;
    incr(total_chars);
@z

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [71] change eof(gf_file) to b_eof(gf_file)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@x
  if eof(gf_file) then bad_gf('the file ended prematurely');
@y
  if b_eof(gf_file) then bad_gf('the file ended prematurely');
@z

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [72] flush output after announcing new character
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@x
  min_m:=signed_quad; max_m:=signed_quad;
  min_n:=signed_quad; max_n:=signed_quad;
  end;
print('[',char_code:1);
if char_code>max_glyph_no then abort('Character number too large');
@y
  min_m:=signed_quad; max_m:=signed_quad;
  min_n:=signed_quad; max_n:=signed_quad;
  end;
print('[',char_code:1); update_terminal;
if char_code>max_glyph_no then abort('Character number too large');
@z

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [73-77] add system dependent sections: parsing command line arguments
%		and generating output file name
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@x
@* System-dependent changes.
This section should be replaced, if necessary, by changes to the program
that are necessary to make \.{GFtoPXL} 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.
@^system dependencies@>
@y
@* System-dependent changes.
This section contains changes to the program that are necessary to make
\.{GFtoPXL} work under Berkeley {\mc UNIX} and aren't modifications of
existing sections.
@^system dependencies@>

@ We defined back in |initialize| a section for parsing the command line.
Under {\mc UNIX} we provide the names of the input and output files
on the command we issue to start \.{GFtoPXL}.  The output file name
is optional, and if omitted, is constructed by taking the first part
of the GF file name (up to the first ``.'') and appending the appropriate
magnification and the letters ``pxl''. (See routine |open_pxl_file|).
@^system dependencies@>

@<Parse command ...@>=
if (argc < 2) or (argc > 3) then begin
     write_ln('Usage: gftopxl GFfile [PXLfile]');@/
     goto final_end; {we will allow this unstructure once}
end;
argv(1, gf_name);
if argc > 2 then begin
    argv(2, pxl_name);@/
    pxl_name_ready := true;
end;

@ We need another declaration for |pxl_name_ready|, which is true if
the name of the PXL file was specified on the command line.

@<Glob...@>=
@!pxl_name_ready: boolean; {true if |pxl_name[]| has valid name in it}

@ Also, it should be initialized at startup.

@<Set init...@>=
pxl_name_ready := false;

@ In |open_pxl_file|, we added a section to construct the name of the output
file from the name of the input file and the magnification gleaned from
the input file postamble.  Here it is.

@<Construct |pxl_name| ...@>=
begin
    j := file_name_size;@/
    while (j > 1) and (gf_name[j] <> '/') do@/
        decr(j);
    if (gf_name[j] = '/') then incr(j);  { to avoid picking up the / }
    name_len := 1;@/
    while (j < file_name_size)
    and (not (gf_name[j] = '.') or (gf_name[j] = ' ')) do begin @/
	pxl_name[name_len] := gf_name[j];
	incr(name_len); incr(j);
    end;
    pxl_name[name_len] := '.'; incr(name_len);@/
    i := 10000;@/
    j := ((round(1000*magnification)) mod i);
    started_number := false;
    while i > 0 do begin@/
	k := j div i;@/
	j := j mod i;@/
	i := i div 10;@/
        if started_number or (k > 0) or (i = 0) then begin
	    pxl_name[name_len] := chr( ord('0') + k);
	    incr(name_len);@/
	    started_number := true;
	end;
    end;
    pxl_name[name_len] := 'p'; incr(name_len); @/
    pxl_name[name_len] := 'x'; incr(name_len); @/
    pxl_name[name_len] := 'l'; incr(name_len); @/
    pxl_name[name_len] := ' '; @/
    write_ln('[Output file named ''', pxl_name:name_len-1, ''']');
end;

@z