home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / tex / texsrc2 / Src / fontutil / pktogf / ch next >
Encoding:
Text File  |  1993-05-21  |  16.9 KB  |  575 lines

  1. % pktogf.ch for C compilation with web2c.
  2. %
  3. % 09/19/88 Pierre A. MacKay    version 1.0.
  4. % 12/02/89 Karl Berry        cosmetic changes.
  5. % 02/04/90 Karl            new file-searching routines.
  6. % (more recent changes in ../ChangeLog.W2C)
  7. %
  8. % One major change in output format is incorporated by this change
  9. % file.  The local pktogf preamble comment is ignored and the 
  10. % dated METAFONT comment is passed through unaltered.  This
  11. % provides a continuous check on the origin of fonts in both
  12. % gf and pk formats.  PKtoGF runs silently unless it is given the
  13. % -v switch in the command line.
  14.  
  15.  
  16. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  17. % [0] WEAVE: print changes only
  18. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  19. @x
  20. \pageno=\contentspagenumber \advance\pageno by 1
  21. @y
  22. \pageno=\contentspagenumber \advance\pageno by 1
  23. \let\maybe=\iffalse
  24. \def\title{PK$\,$\lowercase{to}$\,$GF changes for C}
  25. @z
  26.  
  27. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  28. % [1] Change banner string
  29. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  30. @x
  31. @d banner=='This is PKtoGF, Version 1.1'
  32.          {printed when the program starts}
  33. @y
  34. @d banner=='This is PKtoGF, Version 1.1' {more is printed later}
  35. @z
  36.  
  37. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  38. % [3] Change program header to standard input/output
  39. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  40. @x
  41. @ Both the input and output come from binary files.  On line interaction
  42. is handled through \PASCAL's standard |input| and |output| files.
  43.  
  44. @d print_ln(#)==write_ln(output,#)
  45. @d print(#)==write(output,#)
  46.  
  47. @p program PKtoGF(input, output);
  48. label @<Labels in the outer block@>@/
  49. const @<Constants in the outer block@>@/
  50. type @<Types in the outer block@>@/
  51. var @<Globals in the outer block@>@/
  52. procedure initialize; {this procedure gets things started properly}
  53.   var i:integer; {loop index for initializations}
  54.   begin print_ln(banner);@/
  55.   @<Set initial values@>@/
  56.   end;
  57.  
  58. @y 
  59. @ Both the input and output come from binary files.  On line
  60. interaction is handled through \PASCAL's standard |input| and |output|
  61. files.  For C compilation terminal input and output is directed to
  62. |stdin| and |stdout|.  In this program there is no terminal input.
  63. Since the terminal output is really not very interesting, it is
  64. produced only when the \.{-v} command line flag is presented.
  65.  
  66. @d term_out == stdout {standard output}
  67. @d print_ln(#)==if verbose then write_ln(term_out, #)
  68. @d print(#)==if verbose then write(term_out, #)
  69.  
  70. @p program PK_to_GF;
  71. const @<Constants in the outer block@>@/
  72. type @<Types in the outer block@>@/
  73. var @<Globals in the outer block@>@/
  74. procedure initialize; {this procedure gets things started properly}
  75.   var i:integer; {loop index for initializations}
  76.   begin
  77.   set_paths (PK_FILE_PATH_BIT);
  78.   @<Set initial values@>@/
  79.   end;
  80. @z
  81.  
  82. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  83. % [5] Eliminate the |final_end| label
  84. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  85. @x
  86. @ If the program has to stop prematurely, it goes to the
  87. `|final_end|'.
  88.  
  89. @d final_end=9999 {label for the end of it all}
  90.  
  91. @<Labels...@>=final_end;
  92. @y
  93. @ This module is deleted, because it is only useful for
  94. a non-local goto, which we don't use in C.
  95. @z
  96.  
  97. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  98. % [6] remove terminal_line_length, since there is no dialog.
  99. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  100. @x
  101. @<Constants...@>=
  102. @!name_length=80; {maximum length of a file name}
  103. @!terminal_line_length=132; {maximum length of an input line}
  104. @y
  105. @d name_length==PATH_MAX
  106.  
  107. @<Constants...@>=
  108. @z
  109.  
  110. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  111. % [7] Have abort append <nl> to end of msg and eliminate non-local goto
  112. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  113. @x
  114. @d abort(#)==begin print_ln(' ',#); jump_out; end
  115.  
  116. @p procedure jump_out;
  117. begin goto final_end;
  118. end;
  119.  
  120. @y
  121. @d abort(#)==begin verbose:=true; print_ln(#); uexit(1);
  122.     end
  123.  
  124. @z
  125. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  126. % [30] remove an unused variable (de-linting)
  127. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  128. @x
  129. function pk_packed_num : integer ;
  130. var i, j, k : integer ;
  131. @y
  132. function pk_packed_num : integer ;
  133. var i, j : integer ;
  134. @z
  135. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  136. % [35] Use path-searching to open |pk_file|.
  137. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  138. @x
  139. @p procedure open_gf_file; {prepares to write packed bytes in a |gf_file|}
  140. begin rewrite(gf_file,gf_name);
  141. gf_loc := 0 ;
  142. end;
  143. @#
  144. procedure open_pk_file; {prepares the input for reading}
  145. begin reset(pk_file,pk_name);
  146. pk_loc := 0 ;
  147. end;
  148.  
  149. @y
  150. In C, we use the external |test_read_access| procedure, which also does path
  151. searching based on the user's environment or the default path.  In the course
  152. of this routine we also check the command line for the \.{-v} flag, and make
  153. other checks to see that it is worth running this program at all.
  154.  
  155. @p procedure open_pk_file; {prepares to read packed bytes in |pk_file|}
  156. var j:integer;
  157. begin
  158.     verbose := false; gf_arg :=3;
  159.     if argc < 2 then abort('Usage: pktogf [-v] <pk file> [gf file].');
  160.     argv(1, pk_name);
  161.     if pk_name[1]=xchr["-"] then begin
  162.         if argc > 4 then abort('Usage: pktogf [-v] <pk file> [gf file].');
  163.         if pk_name[2]=xchr["v"] then begin
  164.             verbose := true; argv(2, pk_name); incr(gf_arg)
  165.             end else abort('Usage: pktogf [-v] <pk file> [gf file].');
  166.         end;
  167.     print(banner); print_ln (version_string); @/
  168.     if test_read_access(pk_name, PK_FILE_PATH) then begin
  169.         reset(pk_file, pk_name)
  170.         end
  171.     else begin
  172.         print_pascal_string (pk_name);
  173.         abort(': PK file not found.');
  174.     end;
  175.     cur_loc:=0;
  176. end;
  177. @#
  178. procedure open_gf_file; {prepares to write packed bytes in |gf_file|}
  179. var dot_pos, slash_pos, last, gf_index, pk_index:integer;
  180. begin
  181.   if argc = gf_arg
  182.   then argv (argc - 1, gf_name)
  183.   else begin
  184.     dot_pos := -1;
  185.     slash_pos := -1;
  186.     last := 1;
  187.     
  188.     {Find the end of |pk_name|.}
  189.     while (pk_name[last] <> ' ') and (last <= PATH_MAX - 5)
  190.     do begin
  191.       if pk_name[last] = '.' then dot_pos := last;
  192.       if pk_name[last] = '/' then slash_pos := last;
  193.       incr (last);
  194.     end;
  195.     
  196.     {If no \./ in |pk_name|, use it from the beginning.}
  197.     if slash_pos = -1 then slash_pos := 0;
  198.     
  199.     {Filenames like \.{./foo} will have |dot_pos<slash_pos|.  In that
  200.      case, we want to move |dot_pos| to the end of |pk_name|.  Similarly
  201.      if |dot_pos| is still |-1|.}
  202.     if dot_pos < slash_pos then dot_pos := last - 1;
  203.     
  204.     {Copy |pk_name| from |slash_pos+1| to |dot_pos| into |gf_name|.}
  205.     gf_index := 1;
  206.     for pk_index := slash_pos + 1 to dot_pos
  207.     do begin
  208.       gf_name[gf_index] := pk_name[pk_index];
  209.       incr (gf_index);
  210.     end;
  211.     
  212.     {Now we are ready to deal with the extension.  Copy everything to
  213.      the first \.p.  Then add \.{gf}.  This loses on filenames like
  214.      \.{foo.p300pk}, but no one uses such filenames, anyway.}
  215.     pk_index := dot_pos + 1;
  216.     while (pk_index < last) and (pk_name[pk_index] <> 'p')
  217.     do begin
  218.       gf_name[gf_index] := pk_name[pk_index];
  219.       incr (pk_index);
  220.       incr (gf_index);
  221.     end;
  222.     
  223.     gf_name[gf_index] := 'g';
  224.     gf_name[gf_index + 1] := 'f';
  225.     gf_name[gf_index + 2] := ' ';
  226.   end;
  227.  
  228.   {Report the filename mapping.}
  229.   print (xchr[xord['[']]);
  230.  
  231.   pk_index := 1;
  232.   while pk_name[pk_index] <> ' ' 
  233.   do begin
  234.     print (xchr[xord[pk_name[pk_index]]]);
  235.     incr (pk_index);
  236.   end;
  237.   
  238.   print (xchr[xord['-']]);
  239.   print (xchr[xord['>']]);
  240.  
  241.   gf_index := 1;
  242.   while gf_name[gf_index] <> ' ' 
  243.   do begin
  244.     print (xchr[xord[gf_name[gf_index]]]);
  245.     incr (gf_index);
  246.   end;
  247.   
  248.   print (xchr[xord[']']]);
  249.   print_ln (xchr[xord[' ']]);
  250.  
  251.   riscos_type:=riscos_gftype;
  252.   rewrite(gf_file,gf_name);
  253.   gf_loc:=0;
  254. end;
  255. @z
  256.  
  257. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  258. % [36] Add some globals for file handling.
  259. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  260. @x
  261. @ We need a place to store the names of the input and output files, as well
  262. as a byte counter for the output file.  
  263.  
  264. @<Glob...@>=
  265. @!gf_name,@!pk_name:packed array[1..name_length] of char; {names of input
  266.     and output files}
  267. @!gf_loc, @!pk_loc:integer; {how many bytes have we sent?}
  268. @y
  269. @ We need a place to store the names of the input and output files, as well
  270. as a byte counter for the output file. And a few other things besides.
  271.  
  272. @<Glob...@>=
  273. @!gf_name,@!pk_name:packed array[1..name_length] of text_char; 
  274.     {names of input and output files; pascal-style origin from one}
  275. @!gf_loc, @!cur_loc:integer; {changed |pk_loc| to |cur_loc|}
  276. @!gf_arg:integer; {where command line may supply |gf_name|}
  277. @!verbose:boolean;
  278. @z
  279.  
  280. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  281. % [37] define gf_byte (in place of pascal procedure)
  282. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  283. @x
  284. @ We need a procedure that will write a byte to the \.{GF} file.  If the
  285. particular system
  286. @^system dependencies@>
  287. requires buffering, here is the place to do it.
  288.  
  289. @p procedure gf_byte (i : integer) ;
  290. begin gf_file^ := i ;
  291. put(gf_file) ;
  292. incr(gf_loc) ;
  293. end;
  294. @y
  295. @ Byte output is handled by a C definition.
  296.  
  297. @d gf_byte(#)==begin put_byte(#, gf_file); incr(gf_loc) end
  298.  
  299. @z
  300.  
  301. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  302. % [38] use the |get_byte| routines from DVItype (renamed)
  303. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  304. @x
  305. @ We also need a function that will get a single byte from the \.{PK} file.
  306. Again, buffering may be done in this procedure.
  307.  
  308. @p function pk_byte : eight_bits ;
  309. var nybble, temp : eight_bits ;
  310. begin
  311.    temp := pk_file^ ;
  312.    get(pk_file) ;
  313.    pk_loc := pk_loc + 1 ;
  314.    pk_byte := temp ;
  315. end ;
  316. @y
  317. @ We shall use a set of simple functions to read the next byte or
  318. bytes from |pk_file|. There are seven possibilities, each of which is
  319. treated as a separate function in order to minimize the overhead for
  320. subroutine calls.
  321. @^system dependencies@>
  322.  
  323. @d pk_byte==get_byte
  324. @d pk_loc==cur_loc 
  325.  
  326. @p function get_byte:integer; {returns the next byte, unsigned}
  327. var b:eight_bits;
  328. begin if eof(pk_file) then get_byte:=0
  329. else  begin read(pk_file,b); incr(cur_loc); get_byte:=b;
  330.   end;
  331. end;
  332. @#
  333. function signed_byte:integer; {returns the next byte, signed}
  334. var b:eight_bits;
  335. begin read(pk_file,b); incr(cur_loc);
  336. if b<128 then signed_byte:=b @+ else signed_byte:=b-256;
  337. end;
  338. @#
  339. function get_two_bytes:integer; {returns the next two bytes, unsigned}
  340. var a,@!b:eight_bits;
  341. begin read(pk_file,a); read(pk_file,b);
  342. cur_loc:=cur_loc+2;
  343. get_two_bytes:=a*256+b;
  344. end;
  345. @#
  346. function signed_pair:integer; {returns the next two bytes, signed}
  347. var a,@!b:eight_bits;
  348. begin read(pk_file,a); read(pk_file,b);
  349. cur_loc:=cur_loc+2;
  350. if a<128 then signed_pair:=a*256+b
  351. else signed_pair:=(a-256)*256+b;
  352. end;
  353. @{
  354. function get_three_bytes:integer; {returns the next three bytes, unsigned}
  355. var a,@!b,@!c:eight_bits;
  356. begin read(pk_file,a); read(pk_file,b); read(pk_file,c);
  357. cur_loc:=cur_loc+3;
  358. get_three_bytes:=(a*256+b)*256+c;
  359. end;
  360. @#
  361. function signed_trio:integer; {returns the next three bytes, signed}
  362. var a,@!b,@!c:eight_bits;
  363. begin read(pk_file,a); read(pk_file,b); read(pk_file,c);
  364. cur_loc:=cur_loc+3;
  365. if a<128 then signed_trio:=(a*256+b)*256+c
  366. else signed_trio:=((a-256)*256+b)*256+c;
  367. end;
  368. @}
  369. function signed_quad:integer; {returns the next four bytes, signed}
  370. var a,@!b,@!c,@!d:eight_bits;
  371. begin read(pk_file,a); read(pk_file,b); read(pk_file,c); read(pk_file,d);
  372. cur_loc:=cur_loc+4;
  373. if a<128 then signed_quad:=((a*256+b)*256+c)*256+d
  374. else signed_quad:=(((a-256)*256+b)*256+c)*256+d;
  375. end;
  376. @z
  377.  
  378. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  379. % [40] use definitions for adaptation to DVItype functions
  380. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  381. @x
  382. @ As we are reading the packed file, we often need to fetch 16 and 32 bit
  383. quantities.  Here we have two procedures to do this.
  384.  
  385. @p function signed_byte : integer ;
  386. var a : integer ;
  387. begin
  388.    a := pk_byte ;
  389.    if a > 127 then
  390.       a := a - 256 ;
  391.    signed_byte := a ;
  392. end ;
  393. @#
  394. function get_16 : integer ;
  395. var a : integer ;
  396. begin
  397.    a := pk_byte ;
  398.    get_16 := a * 256 + pk_byte ; 
  399. end ;
  400. @#
  401. function signed_16 : integer ;
  402. var a : integer ;
  403. begin
  404.    a := signed_byte ;
  405.    signed_16 := a * 256 + pk_byte ;
  406. end ;
  407. @#
  408. function get_32 : integer ;
  409. var a : integer ;
  410. begin 
  411.    a := get_16 ; 
  412.    if a > 32767 then a := a - 65536 ;
  413.    get_32 := a * 65536 + get_16 ; 
  414. end ;
  415. @y
  416. @ We put definitions here to access the \.{DVItype} functions supplied
  417. above.  (|signed_byte| is already taken care of).
  418.  
  419. @d get_16==get_two_bytes
  420. @d signed_16==signed_pair
  421. @d get_32==signed_quad
  422. @z
  423.  
  424. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  425. % [1] remove unused gf_sbyte 
  426. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  427. @x
  428. @p procedure gf_sbyte(i : integer) ;
  429. begin
  430.    if i < 0 then
  431.       i := i + 256 ;
  432.    gf_byte(i) ;
  433. end ;
  434. @#
  435. procedure gf_16(i : integer) ;
  436. @y
  437. @p procedure gf_16(i : integer) ;
  438. @z
  439.  
  440. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  441. % [49] preserve the METAFONT comment
  442. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  443. @x
  444. j := pk_byte ;
  445. for i := 1 to j do hppp := pk_byte ;
  446. gf_byte(comm_length) ;
  447. for i := 1 to comm_length do
  448.    gf_byte(xord[comment[i]]) ;
  449. @y
  450. j := pk_byte ;
  451. gf_byte(j) ;
  452. print('{') ;
  453. for i := 1 to j do begin
  454.   hppp:=pk_byte;
  455.   gf_byte(hppp) ;
  456.   print(xchr[xord[hppp]]);
  457.   end;
  458. print_ln('}') ;
  459. @z
  460.  
  461. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  462. % [51] since we preserve the METAFONT comment, this is unneeded
  463. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  464. @x
  465. comment := preamble_comment ;
  466. @y
  467. @z
  468.  
  469. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  470. % [63] remove unused nybble
  471. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  472. @x
  473. @!nybble : eight_bits ; {the current nybble}
  474. @y
  475. @z
  476.  
  477. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  478. % [65] change jumpout to abort
  479. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  480. @x
  481.          if rcp > max_counts then begin
  482.             print_ln('A character had too many run counts') ;
  483.             jump_out ;
  484.          end ;
  485. @y
  486.          if rcp > max_counts then abort('A character had too many run counts');
  487. @z
  488.  
  489. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  490. % [71] There is no terminal communication.
  491. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  492. @x
  493. @* Terminal communication.
  494. We must get the file names and determine whether input is to be in
  495. hexadecimal or binary.  To do this, we use the standard input path
  496. name.  We need a procedure to flush the input buffer.  For most systems,
  497. this will be an empty statement.  For other systems, a |print_ln| will
  498. provide a quick fix.  We also need a routine to get a line of input from
  499. the terminal.  On some systems, a simple |read_ln| will do.  Finally,
  500. a macro to print a string to the first blank is required.
  501.  
  502. @d flush_buffer == begin end
  503. @d get_line(#) == if eoln(input) then read_ln(input) ;
  504.    i := 1 ;
  505.    while not (eoln(input) or eof(input)) do begin
  506.       #[i] := input^ ;
  507.       incr(i) ;
  508.       get(input) ;
  509.    end ;
  510.    #[i] := ' '
  511. @y
  512. @* Terminal communication.
  513. Since this program runs entirely on command-line arguments, there
  514. is no terminal communication.
  515. @z
  516.  
  517.  
  518. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  519. % [72] There is no dialog
  520. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  521. @x
  522. @ @p procedure dialog ;
  523. var i : integer ; {index variable}
  524. buffer : packed array [1..name_length] of char; {input buffer}
  525. begin
  526.    for i := 1 to name_length do begin
  527.       gf_name[i] := ' ' ;
  528.       pk_name[i] := ' ' ;
  529.    end;
  530.    print('Input file name:  ') ;
  531.    flush_buffer ;
  532.    get_line(pk_name) ;
  533.    print('Output file name:  ') ;
  534.    flush_buffer ;
  535.    get_line(gf_name) ;
  536. end ;
  537. @y
  538. @ The \.{pktogf.web} file has a |dialog| procedure here.
  539. @z
  540.  
  541. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  542. % [73] There is no dialog and no |final_end| label
  543. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  544. @x
  545. @p begin
  546. initialize ;
  547. dialog ;
  548. @<Open files@> ;
  549. @<Read preamble@> ;
  550. skip_specials ;
  551. while flag_byte <> pk_post do begin
  552.    @<Unpack and write character@> ;
  553.    skip_specials ;
  554. end ;
  555. while not eof(pk_file) do i := pk_byte ;
  556. @<Write \.{GF} postamble@> ;
  557. print_ln(pk_loc:1,' bytes unpacked to ',gf_loc:1,' bytes.');
  558. final_end :
  559. end .
  560. @y
  561. @p begin
  562. initialize ;
  563. @<Open files@> ;
  564. @<Read preamble@> ;
  565. skip_specials ;
  566. while flag_byte <> pk_post do begin
  567.    @<Unpack and write character@> ;
  568.    skip_specials ;
  569. end ;
  570. while not eof(pk_file) do i := pk_byte ;
  571. @<Write \.{GF} postamble@> ;
  572. print_ln(pk_loc:1,' bytes unpacked to ',gf_loc:1,' bytes.');
  573. end .
  574. @z
  575.