home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / unixtex-6.1b-src.tgz / tar.out / contrib / unixtex / web2c / fontutil / pktogf.ch < prev    next >
Text File  |  1996-09-28  |  18KB  |  585 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. begin
  157.     verbose := false; gf_arg :=3;
  158.     if argc < 2 then abort('Usage: pktogf [-v] <pk file> [gf file].');
  159.     argv(1, pk_name);
  160.     if pk_name[1]=xchr["-"] then begin
  161.         if argc > 4 then abort('Usage: pktogf [-v] <pk file> [gf file].');
  162.         if pk_name[2]=xchr["v"] then begin
  163.             verbose := true; argv(2, pk_name); incr(gf_arg)
  164.             end else abort('Usage: pktogf [-v] <pk file> [gf file].');
  165.         end;
  166.     print(banner); print_ln (version_string); @/
  167.     if test_read_access(pk_name, PK_FILE_PATH) then begin
  168.         reset(pk_file, pk_name)
  169.         end
  170.     else begin
  171.         print_pascal_string (pk_name);
  172.         abort(': PK file not found.');
  173.     end;
  174.     cur_loc:=0;
  175. end;
  176. @#
  177. procedure open_gf_file; {prepares to write packed bytes in |gf_file|}
  178. var dot_pos, slash_pos, last, gf_index, pk_index:integer;
  179. begin
  180.   if argc = gf_arg
  181.   then argv (argc - 1, gf_name)
  182.   else begin
  183.     dot_pos := -1;
  184.     slash_pos := -1;
  185.     last := 1;
  186.     
  187.     {Find the end of |pk_name|.}
  188.     while (pk_name[last] <> ' ') and (last <= PATH_MAX - 5)
  189.     do begin
  190.       if pk_name[last] = '.' then dot_pos := last;
  191.       if pk_name[last] = '/' then slash_pos := last;
  192.       incr (last);
  193.     end;
  194.     
  195.     {If no \./ in |pk_name|, use it from the beginning.}
  196.     if slash_pos = -1 then slash_pos := 0;
  197.     
  198.     {Filenames like \.{./foo} will have |dot_pos<slash_pos|.  In that
  199.      case, we want to move |dot_pos| to the end of |pk_name|.  Similarly
  200.      if |dot_pos| is still |-1|.}
  201.     if dot_pos < slash_pos then dot_pos := last - 1;
  202.     
  203.     {Copy |pk_name| from |slash_pos+1| to |dot_pos| into |gf_name|.}
  204.     gf_index := 1;
  205.     for pk_index := slash_pos + 1 to dot_pos
  206.     do begin
  207.       gf_name[gf_index] := pk_name[pk_index];
  208.       incr (gf_index);
  209.     end;
  210.     
  211.     {Now we are ready to deal with the extension.  Copy everything to
  212.      the first \.p.  Then add \.{gf}.  This loses on filenames like
  213.      \.{foo.p300pk}, but no one uses such filenames, anyway.}
  214.     pk_index := dot_pos + 1;
  215.     while (pk_index < last) and (pk_name[pk_index] <> 'p')
  216.     do begin
  217.       gf_name[gf_index] := pk_name[pk_index];
  218.       incr (pk_index);
  219.       incr (gf_index);
  220.     end;
  221.     
  222.     gf_name[gf_index] := 'g';
  223.     gf_name[gf_index + 1] := 'f';
  224.     gf_name[gf_index + 2] := ' ';
  225.   end;
  226.  
  227.   {Report the filename mapping.}
  228.   print (xchr[xord['[']]);
  229.  
  230.   pk_index := 1;
  231.   while pk_name[pk_index] <> ' ' 
  232.   do begin
  233.     print (xchr[xord[pk_name[pk_index]]]);
  234.     incr (pk_index);
  235.   end;
  236.   
  237.   print (xchr[xord['-']]);
  238.   print (xchr[xord['>']]);
  239.  
  240.   gf_index := 1;
  241.   while gf_name[gf_index] <> ' ' 
  242.   do begin
  243.     print (xchr[xord[gf_name[gf_index]]]);
  244.     incr (gf_index);
  245.   end;
  246.   
  247.   print (xchr[xord[']']]);
  248.   print_ln (xchr[xord[' ']]);
  249.  
  250.   rewrite(gf_file,gf_name);
  251.   gf_loc:=0
  252. end;
  253. @z
  254.  
  255. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  256. % [36] Add some globals for file handling.
  257. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  258. @x
  259. @ We need a place to store the names of the input and output files, as well
  260. as a byte counter for the output file.  
  261.  
  262. @<Glob...@>=
  263. @!gf_name,@!pk_name:packed array[1..name_length] of char; {names of input
  264.     and output files}
  265. @!gf_loc, @!pk_loc:integer; {how many bytes have we sent?}
  266. @y
  267. @ We need a place to store the names of the input and output files, as well
  268. as a byte counter for the output file. And a few other things besides.
  269.  
  270. @<Glob...@>=
  271. @!gf_name,@!pk_name:packed array[1..name_length] of text_char; 
  272.     {names of input and output files; pascal-style origin from one}
  273. @!gf_loc, @!cur_loc:integer; {changed |pk_loc| to |cur_loc|}
  274. @!gf_arg:integer; {where command line may supply |gf_name|}
  275. @!verbose:boolean;
  276. @z
  277.  
  278. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  279. % [42] define gf_byte (in place of pascal procedure)
  280. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  281. @x
  282. @ We need a procedure that will write a byte to the \.{GF} file.  If the
  283. particular system
  284. @^system dependencies@>
  285. requires buffering, here is the place to do it.
  286.  
  287. @p procedure gf_byte (i : integer) ;
  288. begin gf_file^ := i ;
  289. put(gf_file) ;
  290. incr(gf_loc) ;
  291. end;
  292. @y
  293. @ Byte output is handled by a C definition.
  294.  
  295. @d gf_byte(#)==begin put_byte(#, gf_file); incr(gf_loc) end
  296. @z
  297.  
  298. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  299. % [43] use the |get_byte| routines from DVItype (renamed)
  300. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  301. @x
  302. @ We also need a function that will get a single byte from the \.{PK} file.
  303. Again, buffering may be done in this procedure.
  304.  
  305. @p function pk_byte : eight_bits ;
  306. var nybble, temp : eight_bits ;
  307. begin
  308.    temp := pk_file^ ;
  309.    get(pk_file) ;
  310.    pk_loc := pk_loc + 1 ;
  311.    pk_byte := temp ;
  312. end ;
  313. @y
  314. @ We shall use a set of simple functions to read the next byte or
  315. bytes from |pk_file|. There are seven possibilities, each of which is
  316. treated as a separate function in order to minimize the overhead for
  317. subroutine calls.
  318. @^system dependencies@>
  319.  
  320. @d pk_byte==get_byte
  321. @d pk_loc==cur_loc 
  322.  
  323. @p function get_byte:integer; {returns the next byte, unsigned}
  324. var b:eight_bits;
  325. begin if eof(pk_file) then get_byte:=0
  326. else  begin read(pk_file,b); incr(cur_loc); get_byte:=b;
  327.   end;
  328. end;
  329. @#
  330. function signed_byte:integer; {returns the next byte, signed}
  331. var b:eight_bits;
  332. begin read(pk_file,b); incr(cur_loc);
  333. if b<128 then signed_byte:=b @+ else signed_byte:=b-256;
  334. end;
  335. @#
  336. function get_two_bytes:integer; {returns the next two bytes, unsigned}
  337. var a,@!b:eight_bits;
  338. begin read(pk_file,a); read(pk_file,b);
  339. cur_loc:=cur_loc+2;
  340. get_two_bytes:=a*256+b;
  341. end;
  342. @#
  343. function signed_pair:integer; {returns the next two bytes, signed}
  344. var a,@!b:eight_bits;
  345. begin read(pk_file,a); read(pk_file,b);
  346. cur_loc:=cur_loc+2;
  347. if a<128 then signed_pair:=a*256+b
  348. else signed_pair:=(a-256)*256+b;
  349. end;
  350. @{
  351. function get_three_bytes:integer; {returns the next three bytes, unsigned}
  352. var a,@!b,@!c:eight_bits;
  353. begin read(pk_file,a); read(pk_file,b); read(pk_file,c);
  354. cur_loc:=cur_loc+3;
  355. get_three_bytes:=(a*256+b)*256+c;
  356. end;
  357. @#
  358. function signed_trio:integer; {returns the next three bytes, signed}
  359. var a,@!b,@!c:eight_bits;
  360. begin read(pk_file,a); read(pk_file,b); read(pk_file,c);
  361. cur_loc:=cur_loc+3;
  362. if a<128 then signed_trio:=(a*256+b)*256+c
  363. else signed_trio:=((a-256)*256+b)*256+c;
  364. end;
  365. @}
  366. function signed_quad:integer; {returns the next four bytes, signed}
  367. var a,@!b,@!c,@!d:eight_bits;
  368. begin read(pk_file,a); read(pk_file,b); read(pk_file,c); read(pk_file,d);
  369. cur_loc:=cur_loc+4;
  370. if a<128 then signed_quad:=((a*256+b)*256+c)*256+d
  371. else signed_quad:=(((a-256)*256+b)*256+c)*256+d;
  372. end;
  373. @z
  374.  
  375. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  376. % [45] use definitions for adaptation to DVItype functions
  377. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  378. @x
  379. @ As we are reading the packed file, we often need to fetch 16 and 32 bit
  380. quantities.  Here we have two procedures to do this.
  381.  
  382. @p function signed_byte : integer ;
  383. var a : integer ;
  384. begin
  385.    a := pk_byte ;
  386.    if a > 127 then
  387.       a := a - 256 ;
  388.    signed_byte := a ;
  389. end ;
  390. @#
  391. function get_16 : integer ;
  392. var a : integer ;
  393. begin
  394.    a := pk_byte ;
  395.    get_16 := a * 256 + pk_byte ; 
  396. end ;
  397. @#
  398. function signed_16 : integer ;
  399. var a : integer ;
  400. begin
  401.    a := signed_byte ;
  402.    signed_16 := a * 256 + pk_byte ;
  403. end ;
  404. @#
  405. function get_32 : integer ;
  406. var a : integer ;
  407. begin 
  408.    a := get_16 ; 
  409.    if a > 32767 then a := a - 65536 ;
  410.    get_32 := a * 65536 + get_16 ; 
  411. end ;
  412. @y
  413. @ We put definitions here to access the \.{DVItype} functions supplied
  414. above.  (|signed_byte| is already taken care of).
  415.  
  416. @d get_16==get_two_bytes
  417. @d signed_16==signed_pair
  418. @d get_32==signed_quad
  419. @z
  420.  
  421. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  422. % [46] remove unused gf_sbyte 
  423. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  424. @x
  425. @p procedure gf_sbyte(i : integer) ;
  426. begin
  427.    if i < 0 then
  428.       i := i + 256 ;
  429.    gf_byte(i) ;
  430. end ;
  431. @#
  432. procedure gf_16(i : integer) ;
  433. @y
  434. @p procedure gf_16(i : integer) ;
  435. @z
  436.  
  437. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  438. % [46] fix unlikely but possible overflow in addition in gf_quad
  439. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  440. @x
  441.       i := (i + 1073741824) + 1073741824 ;
  442. @y
  443.       {|i<0| at this point, but a compiler is permitted to rearrange the
  444.        order of the additions, which would cause wrong results
  445.        in the unlikely event of a non-2's-complement representation.}
  446.       i := i + 1073741824;
  447.       i := i + 1073741824;
  448. @z
  449.  
  450. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  451. % [49] preserve the METAFONT comment
  452. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  453. @x
  454. j := pk_byte ;
  455. for i := 1 to j do hppp := pk_byte ;
  456. gf_byte(comm_length) ;
  457. for i := 1 to comm_length do
  458.    gf_byte(xord[comment[i]]) ;
  459. @y
  460. j := pk_byte ;
  461. gf_byte(j) ;
  462. print('{') ;
  463. for i := 1 to j do begin
  464.   hppp:=pk_byte;
  465.   gf_byte(hppp) ;
  466.   print(xchr[xord[hppp]]);
  467.   end;
  468. print_ln('}') ;
  469. @z
  470.  
  471. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  472. % [51] since we preserve the METAFONT comment, this is unneeded
  473. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  474. @x
  475. comment := preamble_comment ;
  476. @y
  477. @z
  478.  
  479. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  480. % [63] remove unused nybble
  481. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  482. @x
  483. @!nybble : eight_bits ; {the current nybble}
  484. @y
  485. @z
  486.  
  487. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  488. % [65] change jumpout to abort
  489. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  490. @x
  491.          if rcp > max_counts then begin
  492.             print_ln('A character had too many run counts') ;
  493.             jump_out ;
  494.          end ;
  495. @y
  496.          if rcp > max_counts then abort('A character had too many run counts');
  497. @z
  498.  
  499. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  500. % [71] There is no terminal communication.
  501. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  502. @x
  503. @* Terminal communication.
  504. We must get the file names and determine whether input is to be in
  505. hexadecimal or binary.  To do this, we use the standard input path
  506. name.  We need a procedure to flush the input buffer.  For most systems,
  507. this will be an empty statement.  For other systems, a |print_ln| will
  508. provide a quick fix.  We also need a routine to get a line of input from
  509. the terminal.  On some systems, a simple |read_ln| will do.  Finally,
  510. a macro to print a string to the first blank is required.
  511.  
  512. @d flush_buffer == begin end
  513. @d get_line(#) == if eoln(input) then read_ln(input) ;
  514.    i := 1 ;
  515.    while not (eoln(input) or eof(input)) do begin
  516.       #[i] := input^ ;
  517.       incr(i) ;
  518.       get(input) ;
  519.    end ;
  520.    #[i] := ' '
  521. @y
  522. @* Terminal communication.
  523. Since this program runs entirely on command-line arguments, there
  524. is no terminal communication.
  525. @z
  526.  
  527.  
  528. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  529. % [72] There is no dialog
  530. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  531. @x
  532. @ @p procedure dialog ;
  533. var i : integer ; {index variable}
  534. buffer : packed array [1..name_length] of char; {input buffer}
  535. begin
  536.    for i := 1 to name_length do begin
  537.       gf_name[i] := ' ' ;
  538.       pk_name[i] := ' ' ;
  539.    end;
  540.    print('Input file name:  ') ;
  541.    flush_buffer ;
  542.    get_line(pk_name) ;
  543.    print('Output file name:  ') ;
  544.    flush_buffer ;
  545.    get_line(gf_name) ;
  546. end ;
  547. @y
  548. @ The \.{pktogf.web} file has a |dialog| procedure here.
  549. @z
  550.  
  551. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  552. % [73] There is no dialog and no |final_end| label
  553. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  554. @x
  555. @p begin
  556. initialize ;
  557. dialog ;
  558. @<Open files@> ;
  559. @<Read preamble@> ;
  560. skip_specials ;
  561. while flag_byte <> pk_post do begin
  562.    @<Unpack and write character@> ;
  563.    skip_specials ;
  564. end ;
  565. while not eof(pk_file) do i := pk_byte ;
  566. @<Write \.{GF} postamble@> ;
  567. print_ln(pk_loc:1,' bytes unpacked to ',gf_loc:1,' bytes.');
  568. final_end :
  569. end .
  570. @y
  571. @p begin
  572. initialize ;
  573. @<Open files@> ;
  574. @<Read preamble@> ;
  575. skip_specials ;
  576. while flag_byte <> pk_post do begin
  577.    @<Unpack and write character@> ;
  578.    skip_specials ;
  579. end ;
  580. while not eof(pk_file) do i := pk_byte ;
  581. @<Write \.{GF} postamble@> ;
  582. print_ln(pk_loc:1,' bytes unpacked to ',gf_loc:1,' bytes.');
  583. end .
  584. @z
  585.