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 / vftovp.ch < prev    next >
Text File  |  1996-09-28  |  22KB  |  719 lines

  1. % vftovp.ch for C compilation with web2c.
  2.  
  3.  
  4. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5. % [0] WEAVE: print changes only.
  6. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  7. @x
  8. \pageno=\contentspagenumber \advance\pageno by 1
  9. @y
  10. \pageno=\contentspagenumber \advance\pageno by 1
  11. \let\maybe=\iffalse
  12. \def\title{VF$\,$\lowercase{to}$\,$VP changes for C}
  13. @z
  14.  
  15. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  16. % [1] Change banner string
  17. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  18. @x
  19. @d banner=='This is VFtoVP, Version 1.2' {printed when the program starts}
  20. @y
  21. @d banner=='This is VFtoVP, Version 1.2' {more is printed later}
  22. @z
  23.  
  24. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  25. % [2] Remove files in program statement.
  26. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  27. @x
  28. @p program VFtoVP(@!vf_file,@!tfm_file,@!vpl_file,@!output);
  29. @y
  30. @p program VFtoVP;
  31. @z
  32.  
  33. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  34. % still [2] Set up for path reading.
  35. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  36. @x
  37.   begin print_ln(banner);@/
  38. @y
  39.   @<Local variables for initialization@>
  40.   begin
  41.     if (argc < 3) or (argc > n_options + arg_options + 4)
  42.     then begin
  43.       print ('Usage: vftovp ');
  44.       print ('[-verbose] ');
  45.       print_ln ('[-charcode-format=<format>] ');
  46.       print_ln ('  <vfm file> <tfm file> [<vpl file>].');
  47. @.Usage: ...@>
  48.       uexit (1);
  49.     end;
  50.  
  51.     @<Initialize the option variables@>;
  52.     @<Parse arguments@>;
  53. @z
  54.  
  55. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  56. % [4] Set name_length to the system constant.
  57. % AIX defines `class' in <math.h>, so let's take this opportunity to
  58. % define that away.
  59. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  60. @x
  61. @<Constants...@>=
  62. @y
  63. @d name_length == PATH_MAX
  64. @d class == class_var
  65. @<Constants...@>=
  66. @z
  67.  
  68. @x
  69. @!name_length=50; {a file name shouldn't be longer than this}
  70. @y
  71. @z
  72.  
  73. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  74. % [7] Declare vf_name.
  75. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  76. @x
  77. @!vf_file:packed file of byte;
  78. @y
  79. @!vf_file:packed file of byte; {files that contain binary data}
  80. @!vf_name:packed array[1..PATH_MAX] of char;
  81. @z
  82.  
  83. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  84. % [10] Declare tfm_name.
  85. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  86. @x
  87. @!tfm_file:packed file of byte;
  88. @y
  89. @!tfm_file:packed file of byte;
  90. @!tfm_name:packed array[1..PATH_MAX] of char;
  91. @z
  92.  
  93. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  94. % [11] Open the files.
  95. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  96. @x
  97. @ On some systems you may have to do something special to read a
  98. packed file of bytes. For example, the following code didn't work
  99. when it was first tried at Stanford, because packed files have to be
  100. opened with a special switch setting on the \PASCAL\ that was used.
  101. @^system dependencies@>
  102.  
  103. @<Set init...@>=
  104. reset(tfm_file); reset(vf_file);
  105. @y
  106. @ We don't have to do anything special to read a packed file of bytes,
  107. but we do want to use environment variables to find the input files.
  108. @^system dependencies@>
  109.  
  110. @<Set init...@>=
  111. {Use path searching to find the input files.}
  112. set_paths (TFM_FILE_PATH_BIT + VF_FILE_PATH_BIT);
  113.  
  114. argv (optind, vf_name);
  115. if test_read_access (vf_name, VF_FILE_PATH)
  116. then reset (vf_file, vf_name)
  117. else begin
  118.   print_pascal_string (vf_name);
  119.   print_ln (': VF file not found.');
  120.   uexit (1);
  121. end;
  122.  
  123. argv (optind + 1, tfm_name);
  124. if test_read_access (tfm_name, TFM_FILE_PATH)
  125. then reset (tfm_file, tfm_name)
  126. else begin
  127.   print_pascal_string (tfm_name);
  128.   print_ln (': TFM file not found.');
  129.   uexit (1);
  130. end;
  131. if verbose then begin
  132.   print (banner);
  133.   print_ln (version_string);
  134. end;
  135. @z
  136.  
  137. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  138. % [20] Declare vpl_name.
  139. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  140. @x
  141. @!vpl_file:text;
  142. @y
  143. @!vpl_file:text;
  144. @!vpl_name:packed array[1..PATH_MAX] of char;
  145. @z
  146.  
  147. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  148. % [21] Open VPL file.
  149. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  150. @x
  151. @ @<Set init...@>=
  152. rewrite(vpl_file);
  153. @y
  154. @ @<Set init...@>=
  155. if optind + 2 = argc
  156. then vpl_file := stdout
  157. else begin
  158.   argv (optind + 2, vpl_name);
  159.   rewrite (vpl_file, vpl_name);
  160. end;
  161. @z
  162.  
  163. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  164. % [24] `index' is not a good choice for an identifier.
  165. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
  166. @x
  167. @<Types...@>=
  168. @!index=0..tfm_size; {address of a byte in |tfm|}
  169. @y
  170. @d index == index_type
  171.  
  172. @<Types...@>=
  173. @!index=0..tfm_size; {address of a byte in |tfm|}
  174. @z
  175.  
  176. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  177. % [24] abort() should cause a bad exit code.
  178. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
  179. @x
  180. @d abort(#)==begin print_ln(#);
  181.   print_ln('Sorry, but I can''t go on; are you sure this is a TFM?');
  182.   goto final_end;
  183.   end
  184. @y
  185. @d abort(#)==begin print_ln(#);
  186.   print_ln('Sorry, but I can''t go on; are you sure this is a TFM?');
  187.   uexit(1);
  188.   end
  189. @z
  190.  
  191. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  192. % [31] Ditto for vf_abort.
  193. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
  194. @x
  195. @d vf_abort(#)==
  196.   begin print_ln(#);
  197.   print_ln('Sorry, but I can''t go on; are you sure this is a VF?');
  198.   goto final_end;
  199.   end
  200. @y
  201. @d vf_abort(#)==
  202.   begin print_ln(#);
  203.   print_ln('Sorry, but I can''t go on; are you sure this is a VF?');
  204.   uexit(1);
  205.   end
  206. @z
  207.  
  208. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  209. % [32] Be quiet if not -verbose.
  210. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  211. @x
  212. for k:=0 to vf_ptr-1 do print(xchr[vf[k]]);
  213. print_ln(' '); count:=0;
  214. @y
  215. if verbose
  216. then begin
  217.   for k:=0 to vf_ptr-1 do print(xchr[vf[k]]);
  218.   print_ln(' ');
  219. end;
  220. count:=0;
  221. @z
  222.  
  223. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  224. % [35] Be quiet if not -verbose.
  225. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  226. @x
  227. @<Print the name of the local font@>;
  228. @y
  229. if verbose then begin
  230.   @<Print the name of the local font@>;
  231. end;
  232. @z
  233.  
  234. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  235. % [36] Output of real numbers.
  236. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  237. @x
  238. print_ln(' at ',(((vf[k]*256+vf[k+1])*256+vf[k+2])/@'4000000)*real_dsize:2:2,
  239.   'pt')
  240. @y
  241. print(' at ');
  242. print_real((((vf[k]*256+vf[k+1])*256+vf[k+2])/@'4000000)*real_dsize, 2, 2);
  243. print_ln('pt')
  244. @z
  245.  
  246. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  247. % [39] Open another TFM file.
  248. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  249. @x
  250. reset(tfm_file,cur_name);
  251. @^system dependencies@>
  252. if eof(tfm_file) then
  253.   print_ln('---not loaded, TFM file can''t be opened!')
  254. @.TFM file can\'t be opened@>
  255. else  begin font_bc:=0; font_ec:=256; {will cause error if not modified soon}
  256. @y
  257. if not test_read_access(cur_name, TFM_FILE_PATH) then
  258.   print_ln('---not loaded, TFM file can''t be opened!')
  259. @.TFM file can\'t be opened@>
  260. else begin reset(tfm_file, cur_name);
  261.   font_bc:=0; font_ec:=256; {will cause error if not modified soon}
  262. @z
  263.  
  264. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  265. % [40] Be quiet if not -verbose.
  266. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  267. @x
  268.     begin print_ln('Check sum in VF file being replaced by TFM check sum');
  269. @y
  270.     begin
  271.       if verbose
  272.       then print_ln('Check sum in VF file being replaced by TFM check sum');
  273. @z
  274.  
  275. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  276. % [42] Remove initialization of now-defunct array.
  277. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  278. @x
  279. @ @<Set init...@>=
  280. default_directory:=default_directory_name;
  281. @y
  282. @ (No initialization to be done.  Keep this module to preserve numbering.)
  283. @z
  284.  
  285. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  286. % [44] Use lowercase `.tfm' suffix.
  287. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  288. @x
  289. @ The string |cur_name| is supposed to be set to the external name of the
  290. \.{TFM} file for the current font. This usually means that we need to
  291. prepend the name of the default directory, and
  292. to append the suffix `\.{.TFM}'. Furthermore, we change lower case letters
  293. to upper case, since |cur_name| is a \PASCAL\ string.
  294. @y
  295. @ The string |cur_name| is supposed to be set to the external name of the
  296. \.{TFM} file for the current font. This usually means that we need to
  297. append the suffix ``.tfm''. 
  298. @z
  299.  
  300. @x
  301. if a=0 then
  302.   begin for k:=1 to default_directory_name_length do
  303.     cur_name[k]:=default_directory[k];
  304.   r:=default_directory_name_length;
  305.   end
  306. else r:=0;
  307. @y
  308. r:=0;
  309. @z
  310.  
  311. @x
  312.   if (vf[k]>="a")and(vf[k]<="z") then
  313.       cur_name[r]:=xchr[vf[k]-@'40]
  314.   else cur_name[r]:=xchr[vf[k]];
  315.   end;
  316. cur_name[r+1]:='.'; cur_name[r+2]:='T'; cur_name[r+3]:='F'; cur_name[r+4]:='M'
  317. @y
  318.   cur_name[r]:=xchr[vf[k]];
  319.   end;
  320. cur_name[r+1]:='.'; cur_name[r+2]:='t'; cur_name[r+3]:='f'; cur_name[r+4]:='m'
  321. @z
  322.  
  323. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  324. % [49] Change strings to C char pointers, so we can initialize them.
  325. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  326. @x
  327. @!ASCII_04,@!ASCII_10,@!ASCII_14: packed array [1..32] of char;
  328.   {strings for output in the user's external character set}
  329. @!xchr:packed array [0..255] of char;
  330. @!MBL_string,@!RI_string,@!RCE_string:packed array [1..3] of char;
  331.   {handy string constants for |face| codes}
  332. @y
  333. @!ASCII_04,@!ASCII_10,@!ASCII_14: ccharpointer;
  334.   {strings for output in the user's external character set}
  335. @!xchr:packed array [0..255] of char;
  336. @!MBL_string,@!RI_string,@!RCE_string: ccharpointer;
  337.   {handy string constants for |face| codes}
  338. @z
  339.  
  340. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  341. % [50] The Pascal strings are indexed starting at 1, so we pad with a blank.
  342. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  343. @x
  344. ASCII_04:=' !"#$%&''()*+,-./0123456789:;<=>?';@/
  345. ASCII_10:='@@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_';@/
  346. ASCII_14:='`abcdefghijklmnopqrstuvwxyz{|}~?';@/
  347. @y
  348. ASCII_04:='  !"#$%&''()*+,-./0123456789:;<=>?';@/
  349. ASCII_10:=' @@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_';@/
  350. ASCII_14:=' `abcdefghijklmnopqrstuvwxyz{|}~?';@/
  351. @z
  352.  
  353. @x
  354. MBL_string:='MBL'; RI_string:='RI '; RCE_string:='RCE';
  355. @y
  356. MBL_string:=' MBL'; RI_string:=' RI '; RCE_string:=' RCE';
  357. @z
  358.  
  359. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  360. % [60] How we output the character code depends on |charcode_format|.
  361. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
  362. @x
  363. begin if font_type>vanilla then
  364.   begin tfm[0]:=c; out_octal(0,1)
  365.   end
  366. else if ((c>="0")and(c<="9"))or@|
  367.    ((c>="A")and(c<="Z"))or@|
  368.    ((c>="a")and(c<="z")) then out(' C ',xchr[c])
  369. else begin tfm[0]:=c; out_octal(0,1);
  370.   end;
  371. @y
  372. begin if (font_type > vanilla) or (charcode_format = charcode_octal) then
  373.   begin tfm[0]:=c; out_octal(0,1)
  374.   end
  375. else if (charcode_format = charcode_ascii) and (c > " ") and (c <= "~")
  376.         and (c <> "(") and (c <> ")") then
  377.   out(' C ', xchr[c])
  378. {default case, use \.C only for letters and digits}
  379. else if ((c>="0")and(c<="9"))or@|
  380.    ((c>="A")and(c<="Z"))or@|
  381.    ((c>="a")and(c<="z")) then out(' C ',xchr[c])
  382. else begin tfm[0]:=c; out_octal(0,1);
  383.   end;
  384. @z
  385.  
  386. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  387. % [61] Don't output the face code as an integer.
  388. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
  389. @x
  390.   out(MBL_string[1+(b mod 3)]);
  391.   out(RI_string[1+s]);
  392.   out(RCE_string[1+(b div 3)]);
  393. @y
  394.   put_byte(MBL_string[1+(b mod 3)], vpl_file);
  395.   put_byte(RI_string[1+s], vpl_file);
  396.   put_byte(RCE_string[1+(b div 3)], vpl_file);
  397. @z
  398.  
  399. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  400. % [62] Force 32-bit constant arithmetic for 16-bit machines.
  401. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  402. @x
  403. f:=((tfm[k+1] mod 16)*@'400+tfm[k+2])*@'400+tfm[k+3];
  404. @y
  405. f:=((tfm[k+1] mod 16)*toint(@'400)+tfm[k+2])*@'400+tfm[k+3];
  406. @z
  407.  
  408. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  409. % [100] No progress reports unless verbose.
  410. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
  411. @x
  412.     incr(chars_on_line);
  413.     end;
  414.   print_octal(c); {progress report}
  415. @y
  416.     if verbose then incr(chars_on_line); {keep |chars_on_line = 0|}
  417.     end;
  418.   if verbose then print_octal(c); {progress report}
  419. @z
  420.  
  421. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  422. % [112] No nonlocal goto's.
  423. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
  424. @x
  425.   begin print_ln('Sorry, I haven''t room for so many ligature/kern pairs!');
  426. @.Sorry, I haven't room...@>
  427.   goto final_end;
  428. @y
  429.   begin print_ln('Sorry, I haven''t room for so many ligature/kern pairs!');
  430. @.Sorry, I haven't room...@>
  431.   uexit(1);
  432. @z
  433.  
  434. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  435. % still [112] We can't have a function named `f', because of the local
  436. % variable in do_simple_things.  It would be better, but harder, to fix
  437. % web2c.
  438. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
  439. @x
  440.      r:=f(r,(hash[r]-1)div 256,(hash[r]-1)mod 256);
  441. @y
  442.      r:=lig_f(r,(hash[r]-1)div 256,(hash[r]-1)mod 256);
  443. @z
  444.  
  445. @x
  446.   out('(INFINITE LIGATURE LOOP MUST BE BROKEN!)'); goto final_end;
  447. @y
  448.   out('(INFINITE LIGATURE LOOP MUST BE BROKEN!)'); uexit(1);
  449. @z
  450.  
  451. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  452. % [116] web2c can't handle these mutually recursive procedures.
  453. % But let's do a fake definition of f here, so that it gets into web2c's
  454. % symbol table...
  455. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
  456. @x
  457. @p function f(@!h,@!x,@!y:index):index; forward;@t\2@>
  458.   {compute $f$ for arguments known to be in |hash[h]|}
  459. @y
  460. @p 
  461. ifdef('notdef') 
  462. function lig_f(@!h,@!x,@!y:index):index; begin end;@t\2@>
  463.   {compute $f$ for arguments known to be in |hash[h]|}
  464. endif('notdef')
  465. @z
  466.  
  467. @x
  468. else eval:=f(h,x,y);
  469. @y
  470. else eval:=lig_f(h,x,y);
  471. @z
  472.  
  473. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  474. % [117] ... and then really define it now.
  475. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
  476. @x
  477. @p function f;
  478. @y
  479. @p function lig_f(@!h,@!x,@!y:index):index;
  480. @z
  481.  
  482. @x
  483. f:=lig_z[h];
  484. @y
  485. lig_f:=lig_z[h];
  486. @z
  487.  
  488. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  489. % [124] Some cc's can't handle 136 case labels in a row.
  490. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  491. @x
  492.     begin o:=vf[vf_ptr]; incr(vf_ptr);
  493.     case o of
  494.     @<Cases of \.{DVI} instructions that can appear in character packets@>@;
  495. @y
  496.     begin o:=vf[vf_ptr]; incr(vf_ptr);
  497.     if ((o<=set_char_0+127))or
  498.        ((o>=set1)and(o<=set1+3))or((o>=put1)and(o<=put1+3)) then
  499. begin if o>=set1 then
  500.     if o>=put1 then c:=get_bytes(o-put1+1,false)
  501.     else c:=get_bytes(o-set1+1,false)
  502.   else c:=o;
  503.   if f=font_ptr then
  504.     bad_vf('Character ',c:1,' in undeclared font will be ignored')
  505. @.Character...will be ignored@>
  506.   else begin vf[font_start[f+1]-1]:=c; {store |c| in the ``hole'' we left}
  507.     k:=font_chars[f];@+while vf[k]<>c do incr(k);
  508.     if k=font_start[f+1]-1 then
  509.       bad_vf('Character ',c:1,' in font ',f:1,' will be ignored')
  510.     else begin if o>=put1 then out('(PUSH)');
  511.       left; out('SETCHAR'); out_char(c);
  512.       if o>=put1 then out(')(POP');
  513.       right;
  514.       end;
  515.     end;
  516.   end
  517.     else case o of
  518.     @<Cases of \.{DVI} instructions that can appear in character packets@>
  519. @z
  520.  
  521. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  522. % [125] `signed' is a keyword in ANSI C.
  523. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  524. @x
  525. @p function get_bytes(@!k:integer;@!signed:boolean):integer;
  526. @y
  527. @p function get_bytes(@!k:integer;@!is_signed:boolean):integer;
  528. @z
  529.  
  530. @x
  531. if (k=4) or signed then
  532. @y
  533. if (k=4) or is_signed then
  534. @z
  535.  
  536. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  537. % [126] No nonlocal goto's.
  538. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  539. @x
  540.     begin print_ln('Stack overflow!'); goto final_end;
  541. @y
  542.     begin print_ln('Stack overflow!'); uexit(1);
  543. @z
  544.  
  545. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  546. % [129] This code moved outside the case statement
  547. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  548. @x
  549. @ Before we typeset a character we make sure that it exists.
  550.  
  551. @<Cases...@>=
  552. sixty_four_cases(set_char_0),sixty_four_cases(set_char_0+64),
  553.  four_cases(set1),four_cases(put1):begin if o>=set1 then
  554.     if o>=put1 then c:=get_bytes(o-put1+1,false)
  555.     else c:=get_bytes(o-set1+1,false)
  556.   else c:=o;
  557.   if f=font_ptr then
  558.     bad_vf('Character ',c:1,' in undeclared font will be ignored')
  559. @.Character...will be ignored@>
  560.   else begin vf[font_start[f+1]-1]:=c; {store |c| in the ``hole'' we left}
  561.     k:=font_chars[f];@+while vf[k]<>c do incr(k);
  562.     if k=font_start[f+1]-1 then
  563.       bad_vf('Character ',c:1,' in font ',f:1,' will be ignored')
  564.     else begin if o>=put1 then out('(PUSH)');
  565.       left; out('SETCHAR'); out_char(c);
  566.       if o>=put1 then out(')(POP');
  567.       right;
  568.       end;
  569.     end;
  570.   end;
  571. @y
  572. @ Before we typeset a character we make sure that it exists.
  573. (These cases moved outside the case statement, section 124.)
  574. @z
  575.  
  576. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  577. % [134] No final newline unless verbose.
  578. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
  579. @x
  580. print_ln('.');@/
  581. @y
  582. if verbose then print_ln('.');@/
  583. @z
  584.  
  585. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  586. % [135] System-dependent changes.
  587. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  588. @x
  589. @* System-dependent changes.
  590. This section should be replaced, if necessary, by changes to the program
  591. that are necessary to make \.{VFtoVP} work at a particular installation.
  592. It is usually best to design your change file so that all changes to
  593. previous sections preserve the section numbering; then everybody's version
  594. will be consistent with the printed program. More extensive changes,
  595. which introduce new sections, can be inserted here; then only the index
  596. itself will get a new section number.
  597. @^system dependencies@>
  598. @y
  599. @* System-dependent changes.  We want to parse a Unix-style command line.
  600.  
  601. This macro tests if its argument is the current option, as represented
  602. by the index variable |option_index|.
  603.  
  604. @d argument_is (#) == (strcmp (long_options[option_index].name, #) = 0)
  605.  
  606. @<Parse arguments@> =
  607. begin
  608.   @<Define the option table@>;
  609.   repeat
  610.     getopt_return_val := getopt_long_only (argc, gargv, '', long_options,
  611.                                            address_of_int (option_index));
  612.     if getopt_return_val <> -1
  613.     then begin
  614.       if getopt_return_val = "?"
  615.       then uexit (1); {|getopt| has already given an error message.}
  616.  
  617.       if argument_is ('charcode-format')
  618.       then begin
  619.         if strcmp (optarg, 'ascii') = 0
  620.         then charcode_format := charcode_ascii
  621.         else if strcmp (optarg, 'octal') = 0
  622.         then charcode_format := charcode_octal
  623.         else print ('Bad character code format', optarg, '.');
  624.       end
  625.       
  626.       else
  627.         {It was just a flag; |getopt| has already done the assignment.}
  628.         do_nothing;
  629.  
  630.     end;
  631.   until getopt_return_val = -1;
  632.  
  633.   {Now |optind| is the index of first non-option on the command line.}
  634. end
  635.  
  636.  
  637. @ The array of information we pass in.  The type |getopt_struct| is
  638. defined in C, to avoid type clashes.  We also need to know the return
  639. value from getopt, and the index of the current option.
  640.  
  641. @<Local var...@> =
  642. @!long_options: array[0..n_options] of getopt_struct;
  643. @!getopt_return_val: integer;
  644. @!option_index: c_int_type;
  645. @!current_option: 0..n_options;
  646.  
  647. @ Here is the first of the options we allow.
  648. @.-verbose@>
  649.  
  650. @<Define the option...@> =
  651. current_option := 0;
  652. long_options[0].name := 'verbose';
  653. long_options[0].has_arg := 0;
  654. long_options[0].flag := address_of_int (verbose);
  655. long_options[0].val := 1;
  656. incr (current_option);
  657.  
  658. @ The global variable |verbose| determines whether or not we print
  659. progress information.
  660.  
  661. @<Glob...@> =
  662. @!verbose: c_int_type;
  663.  
  664. @ It starts off |false|.
  665.  
  666. @<Initialize the option...@> =
  667. verbose := false;
  668.  
  669.  
  670. @ Here is an option to change how we output character codes.
  671. @.-charcode-format@>
  672.  
  673. @<Define the option...@> =
  674. long_options[current_option].name := 'charcode-format';
  675. long_options[current_option].has_arg := 1;
  676. long_options[current_option].flag := 0;
  677. long_options[current_option].val := 0;
  678. incr (current_option);
  679.  
  680. @ We use an ``enumerated'' type to store the information.
  681.  
  682. @<Type...@> =
  683. @!charcode_format_type = charcode_ascii..charcode_default;
  684.  
  685. @
  686. @<Const...@> =
  687. @!charcode_ascii = 0;
  688. @!charcode_octal = 1;
  689. @!charcode_default = 2;
  690.  
  691. @
  692. @<Global...@> =
  693. @!charcode_format: charcode_format_type;
  694.  
  695. @ It starts off as the default, that is, we output letters and digits as
  696. ASCII characters, everything else in octal.
  697.  
  698. @<Initialize the option...@> =
  699. charcode_format := charcode_default;
  700.  
  701.  
  702. @ An element with all zeros always ends the list.
  703.  
  704. @<Define the option...@> =
  705. long_options[current_option].name := 0;
  706. long_options[current_option].has_arg := 0;
  707. long_options[current_option].flag := 0;
  708. long_options[current_option].val := 0;
  709.  
  710.  
  711. @ Pascal compilers won't count the number of elements in an array
  712. constant for us.  This doesn't include the zero-element at the end,
  713. because this array starts at index zero.
  714.  
  715. @<Constants...@> =
  716. @!n_options = 2;
  717. @!arg_options = 1;
  718. @z
  719.