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 / tftopl.ch < prev    next >
Text File  |  1996-09-28  |  16KB  |  500 lines

  1. % tftopl.ch for C compilation with web2c.
  2. % The original version of this file was created by Pavel Curtis.
  3. %
  4. % History:
  5. % 04/04/83 (PC)  Original version, made to work with version 1.0 of TFtoPL,
  6. %                released with version 0.96 of TeX in February, 1983.
  7. % 04/16/83 (PC)  Brought up to version 1.0 released with version 0.97 of TeX
  8. %                in April, 1983.
  9. % 06/30/83 (HWT) Revised changefile format, for use with version 1.7 Tangle.
  10. % 07/28/83 (HWT) Brought up to version 2
  11. % 11/21/83 (HWT) Brought up to version 2.1
  12. % 03/24/84 (HWT) Brought up to version 2.2
  13. % 07/12/84 (HWT) Brought up to version 2.3
  14. % 07/05/87 (ETM) Brought up to version 2.5
  15. % 03/22/88 (ETM) Converted for use with WEB to C.
  16. % 11/30/89 (KB)  Version 3.
  17. % 01/16/90 (SR)  Version 3.1.
  18. % (more recent changes in ../ChangeLog and ./ChangeLog)
  19.  
  20.  
  21. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  22. % [0] WEAVE: print changes only.
  23. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  24. @x
  25. \pageno=\contentspagenumber \advance\pageno by 1
  26. @y
  27. \pageno=\contentspagenumber \advance\pageno by 1
  28. \let\maybe=\iffalse
  29. \def\title{TF\lowercase{to}PL changes for C}
  30. @z
  31.  
  32. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  33. % [1] Change banner string.
  34. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  35. @x
  36. @d banner=='This is TFtoPL, Version 3.1' {printed when the program starts}
  37. @y
  38. @d banner=='This is TFtoPL, Version 3.1' {more is printed later}
  39. @z
  40.  
  41. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  42. % [2] Fix files in program statement.  We need to tell web2c about one
  43. % special variable.  Perhaps it would be better to allow @define's
  44. % anywhere in a source file, but that seemed equally ugly as this.
  45. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  46. @x
  47. @p program TFtoPL(@!tfm_file,@!pl_file,@!output);
  48. @y
  49. {Tangle doesn't recognize @@ when it's right after the \.=.}
  50. @p
  51. @= @@define var tfm;@>@\
  52. program TFtoPL;
  53. @z
  54.  
  55. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  56. % [still 2] Don't print banner unless verbose.  Also, we need to
  57. % initialize various things, and tftopl doesn't have an `initialize'
  58. % procedure, so we do it here.
  59. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  60. @x
  61.   begin print_ln(banner);@/
  62. @y
  63.   var @<Local variables for initialization@>
  64.   begin
  65.     if (argc < 2) or (argc > n_options + arg_options + 3)
  66.     then begin
  67.       print ('Usage: tftopl ');
  68.       print ('[-verbose] ');
  69.       print_ln ('[-charcode-format=<format>] ');
  70.       print_ln ('<tfm file>[.tfm] [<property list file>].');
  71. @.Usage: ...@>
  72.       uexit (1);
  73.     end;
  74.  
  75.     {We |xrealloc| when we know how big the file is.  The 1000 comes
  76.      from the negative lower bound.}
  77.     tfm_file_array := cast_to_byte_pointer (xmalloc (1002));
  78.     @<Initialize the option variables@>;
  79.     @<Parse arguments@>;
  80. @z
  81.  
  82. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  83. % [6] Declare tfm_name.
  84. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  85. @x
  86. @!tfm_file:packed file of 0..255;
  87. @y
  88. @!tfm_file:packed file of 0..255;
  89. @!tfm_name:packed array [1..PATH_MAX] of char;
  90. @z
  91.  
  92. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  93. % [7] Open the TFM file.
  94. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  95. @x
  96. @ On some systems you may have to do something special to read a
  97. packed file of bytes. For example, the following code didn't work
  98. when it was first tried at Stanford, because packed files have to be
  99. opened with a special switch setting on the \PASCAL\ that was used.
  100. @^system dependencies@>
  101.  
  102. @<Set init...@>=
  103. reset(tfm_file);
  104. @y
  105. @ On some systems you may have to do something special to read a
  106. packed file of bytes.  With C under Unix, we just open the file by name
  107. and read characters from it.
  108.  
  109. @<Set init...@>=
  110. set_paths (TFM_FILE_PATH_BIT);
  111. argv (optind, tfm_name);
  112. extend_filename (tfm_name, 'tfm');
  113. if test_read_access (tfm_name, TFM_FILE_PATH)
  114. then begin
  115.   reset (tfm_file, tfm_name);
  116. end else begin
  117.   errprint_pascal_string (tfm_name);
  118.   write_ln (stderr, ': TFM file not found.');
  119.   uexit (1);
  120. end;
  121. if verbose then begin
  122.   print (banner);
  123.   print_ln (version_string);
  124. end;
  125. @z
  126.  
  127. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  128. % [16] Declare pl_name.
  129. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  130. @x
  131. @!pl_file:text;
  132. @y
  133. @!pl_file: text;
  134. @!pl_name: array[1..PATH_MAX] of char;
  135. @z
  136.  
  137. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  138. % [17] Open the PL file.
  139. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  140. @x
  141. @ @<Set init...@>=
  142. rewrite(pl_file);
  143. @y
  144. @ If an explicit filename isn't given, we write the output to |stdout|.
  145.  
  146. @<Set init...@>=
  147. if optind + 1 = argc
  148. then pl_file := stdout
  149. else begin
  150.   argv (optind + 1, pl_name);
  151.   rewrite (pl_file, pl_name);
  152. end;
  153. @z
  154.  
  155. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  156. % [18,19] Make |tfm| be dynamically allocated, and rename `index'.
  157. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  158. @x
  159. @<Types...@>=
  160. @!byte=0..255; {unsigned eight-bit quantity}
  161. @!index=0..tfm_size; {address of a byte in |tfm|}
  162.  
  163. @ @<Glob...@>=
  164. @!tfm:array [-1000..tfm_size] of byte; {the input data all goes here}
  165. @y
  166. @d index == index_type
  167.  
  168. @<Types...@>=
  169. @!byte=0..255; {unsigned eight-bit quantity}
  170. @!index=integer; {address of a byte in |tfm|}
  171.  
  172. @ @<Glob...@>=
  173. {Kludge here to define |tfm| as a macro which takes care of the negative
  174.  lower bound.  We've defined |tfm| for the benefit of web2c above.}
  175. @=#define tfm (tfmfilearray + 1001);@>@\
  176. @!tfm_file_array: pointer_to_byte; {the input data all goes here}
  177. @z
  178.  
  179. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  180. % [20] Send error output to stderr.
  181. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  182. @x
  183. @d abort(#)==begin print_ln(#);
  184.   print_ln('Sorry, but I can''t go on; are you sure this is a TFM?');
  185. @y
  186. @d abort(#)==begin write_ln(stderr, #);
  187.   write_ln(stderr, 'Sorry, but I can''t go on; are you sure this is a TFM?');
  188. @z
  189.  
  190. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  191. % [20] Allow arbitrarily large input files.
  192. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  193. @x
  194. if 4*lf-1>tfm_size then abort('The file is bigger than I can handle!');
  195. @.The file is bigger...@>
  196. @y
  197. tfm_file_array
  198.   := cast_to_byte_pointer (xrealloc (tfm_file_array, 4 * lf - 1 + 1002));
  199. @z
  200.  
  201. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  202. % [27, 28] Change strings to C char pointers. The Pascal strings are
  203. % indexed starting at 1, so we pad with a blank.
  204. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  205. @x
  206. @!ASCII_04,@!ASCII_10,@!ASCII_14: packed array [1..32] of char;
  207.   {strings for output in the user's external character set}
  208. @!MBL_string,@!RI_string,@!RCE_string:packed array [1..3] of char;
  209.   {handy string constants for |face| codes}
  210. @y
  211. @!ASCII_04,@!ASCII_10,@!ASCII_14: ccharpointer;
  212.   {strings for output in the user's external character set}
  213. @!ASCII_all: packed array[0..256] of char;
  214. @!MBL_string,@!RI_string,@!RCE_string: ccharpointer;
  215.   {handy string constants for |face| codes}
  216. @z
  217.  
  218. @x
  219. ASCII_04:=' !"#$%&''()*+,-./0123456789:;<=>?';@/
  220. ASCII_10:='@@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_';@/
  221. ASCII_14:='`abcdefghijklmnopqrstuvwxyz{|}~ ';@/
  222. MBL_string:='MBL'; RI_string:='RI '; RCE_string:='RCE';
  223. @y
  224. ASCII_04:='  !"#$%&''()*+,-./0123456789:;<=>?';@/
  225. ASCII_10:=' @@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_';@/
  226. ASCII_14:=' `abcdefghijklmnopqrstuvwxyz{|}~ ';@/
  227. vstrcpy (ASCII_all, ASCII_04);
  228. vstrcat (ASCII_all, '@@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_');
  229. vstrcat (ASCII_all, '`abcdefghijklmnopqrstuvwxyz{|}~');@/
  230. MBL_string:=' MBL'; RI_string:=' RI '; RCE_string:=' RCE';
  231. @z
  232.  
  233. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  234. % [38] How we output the character code depends on |charcode_format|.
  235. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
  236. @x
  237. begin if font_type>vanilla then
  238.   begin tfm[0]:=c; out_octal(0,1)
  239.   end
  240. else if (c>="0")and(c<="9") then
  241.   out(' C ',c-"0":1)
  242. else if (c>="A")and(c<="Z") then
  243.   out(' C ',ASCII_10[c-"A"+2])
  244. else if (c>="a")and(c<="z") then
  245.   out(' C ',ASCII_14[c-"a"+2])
  246. else  begin tfm[0]:=c; out_octal(0,1);
  247. @y
  248. begin if (font_type > vanilla) or (charcode_format = charcode_octal) then
  249.   begin tfm[0]:=c; out_octal(0,1)
  250.   end
  251. else if (charcode_format = charcode_ascii) and (c > " ") and (c <= "~")
  252.         and (c <> "(") and (c <> ")") then
  253.   out(' C ', ASCII_all[c - " " + 1])
  254. {default case, use \.C only for letters and digits}
  255. else if (c>="0")and(c<="9") then
  256.   out(' C ',c-"0":1)
  257. else if (c>="A")and(c<="Z") then
  258.   out(' C ',ASCII_10[c-"A"+2])
  259. else if (c>="a")and(c<="z") then
  260.   out(' C ',ASCII_14[c-"a"+2])
  261. else  begin tfm[0]:=c; out_octal(0,1);
  262. @z
  263.  
  264. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  265. % [39] Don't output the face code as an integer.
  266. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
  267. @x
  268.   out(MBL_string[1+(b mod 3)]);
  269.   out(RI_string[1+s]);
  270.   out(RCE_string[1+(b div 3)]);
  271. @y
  272.   put_byte(MBL_string[1+(b mod 3)], pl_file);
  273.   put_byte(RI_string[1+s], pl_file);
  274.   put_byte(RCE_string[1+(b div 3)], pl_file);
  275. @z
  276.  
  277. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  278. % [40] Force 32-bit constant arithmetic for 16-bit machines.
  279. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  280. @x
  281. f:=((tfm[k+1] mod 16)*@'400+tfm[k+2])*@'400+tfm[k+3];
  282. @y
  283. f:=((tfm[k+1] mod 16)*toint(@'400)+tfm[k+2])*@'400+tfm[k+3];
  284. @z
  285.  
  286. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  287. % [78] No progress reports unless verbose.
  288. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
  289. @x
  290.     incr(chars_on_line);
  291.     end;
  292.   print_octal(c); {progress report}
  293. @y
  294.     if verbose then incr(chars_on_line);
  295.     end;
  296.   if verbose then print_octal(c); {progress report}
  297. @z
  298.  
  299. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  300. % [89] Change the name of the variable `class', since AIX 3.1's <math.h>
  301. % defines a function by that name.
  302. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
  303. @x
  304. @d pending=4 {$f(x,y)$ is being evaluated}
  305. @y
  306. @d pending=4 {$f(x,y)$ is being evaluated}
  307.  
  308. @d class == class_var 
  309. @z
  310.  
  311. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  312. % [90] Change name of the function `f'.
  313. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
  314. @x
  315.      r:=f(r,(hash[r]-1)div 256,(hash[r]-1)mod 256);
  316. @y
  317.      r:=f_fn(r,(hash[r]-1)div 256,(hash[r]-1)mod 256);
  318. @z
  319.  
  320. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  321. % [94] web2c can't handle these mutually recursive procedures.
  322. % But let's do a fake definition of f here, so that it gets into web2c's
  323. % symbol table. We also have to change the name, because there is also a
  324. % variable named `f', and some C compilers can't deal with that.
  325. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  326. @x
  327. @p function f(@!h,@!x,@!y:index):index; forward;@t\2@>
  328.   {compute $f$ for arguments known to be in |hash[h]|}
  329. @y
  330. @p 
  331. ifdef('notdef') 
  332. function f_fn(@!h,@!x,@!y:index):index; begin end;@t\2@>
  333.   {compute $f$ for arguments known to be in |hash[h]|}
  334. endif('notdef')
  335. @z
  336. @x
  337. else eval:=f(h,x,y);
  338. @y
  339. else eval:=f_fn(h,x,y);
  340. @z
  341.  
  342. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  343. % [95] The real definition of f.
  344. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
  345. @x
  346. @p function f;
  347. @y
  348. @p function f_fn(@!h,@!x,@!y:index):index; 
  349. @z
  350. @x
  351. f:=lig_z[h];
  352. @y
  353. f_fn:=lig_z[h];
  354. @z
  355.  
  356. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  357. % [99] No final newline unless verbose.
  358. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
  359. @x
  360. do_characters; print_ln('.');@/
  361. @y
  362. do_characters; if verbose then print_ln('.');@/
  363. @z
  364.  
  365. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  366. % [100] System-dependent changes.
  367. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  368. @x
  369. @* System-dependent changes.
  370. This section should be replaced, if necessary, by changes to the program
  371. that are necessary to make \.{TFtoPL} work at a particular installation.
  372. It is usually best to design your change file so that all changes to
  373. previous sections preserve the section numbering; then everybody's version
  374. will be consistent with the printed program. More extensive changes,
  375. which introduce new sections, can be inserted here; then only the index
  376. itself will get a new section number.
  377. @^system dependencies@>
  378. @y
  379. @* System-dependent changes.  We want to parse a Unix-style command line.
  380.  
  381. This macro tests if its argument is the current option, as represented
  382. by the index variable |option_index|.
  383.  
  384. @d argument_is (#) == (strcmp (long_options[option_index].name, #) = 0)
  385.  
  386. @<Parse arguments@> =
  387. begin
  388.   @<Define the option table@>;
  389.   repeat
  390.     getopt_return_val := getopt_long_only (argc, gargv, '', long_options,
  391.                                            address_of_int (option_index));
  392.     if getopt_return_val <> -1
  393.     then begin
  394.       if getopt_return_val = "?"
  395.       then uexit (1); {|getopt| has already given an error message.}
  396.  
  397.       if argument_is ('charcode-format')
  398.       then begin
  399.         if strcmp (optarg, 'ascii') = 0
  400.         then charcode_format := charcode_ascii
  401.         else if strcmp (optarg, 'octal') = 0
  402.         then charcode_format := charcode_octal
  403.         else print ('Bad character code format', optarg, '.');
  404.       end
  405.       
  406.       else
  407.         {It was just a flag; |getopt| has already done the assignment.}
  408.         do_nothing;
  409.  
  410.     end;
  411.   until getopt_return_val = -1;
  412.  
  413.   {Now |optind| is the index of first non-option on the command line.}
  414. end
  415.  
  416.  
  417. @ The array of information we pass in.  The type |getopt_struct| is
  418. defined in C, to avoid type clashes.  We also need to know the return
  419. value from getopt, and the index of the current option.
  420.  
  421. @<Local var...@> =
  422. @!long_options: array[0..n_options] of getopt_struct;
  423. @!getopt_return_val: integer;
  424. @!option_index: c_int_type;
  425. @!current_option: 0..n_options;
  426.  
  427. @ Here is the first of the options we allow.
  428. @.-verbose@>
  429.  
  430. @<Define the option...@> =
  431. current_option := 0;
  432. long_options[0].name := 'verbose';
  433. long_options[0].has_arg := 0;
  434. long_options[0].flag := address_of_int (verbose);
  435. long_options[0].val := 1;
  436. incr (current_option);
  437.  
  438. @ The global variable |verbose| determines whether or not we print
  439. progress information.
  440.  
  441. @<Glob...@> =
  442. @!verbose: c_int_type;
  443.  
  444. @ It starts off |false|.
  445.  
  446. @<Initialize the option...@> =
  447. verbose := false;
  448.  
  449.  
  450. @ Here is an option to change how we output character codes.
  451. @.-charcode-format@>
  452.  
  453. @<Define the option...@> =
  454. long_options[current_option].name := 'charcode-format';
  455. long_options[current_option].has_arg := 1;
  456. long_options[current_option].flag := 0;
  457. long_options[current_option].val := 0;
  458. incr (current_option);
  459.  
  460. @ We use an ``enumerated'' type to store the information.
  461.  
  462. @<Type...@> =
  463. @!charcode_format_type = charcode_ascii..charcode_default;
  464.  
  465. @
  466. @<Const...@> =
  467. @!charcode_ascii = 0;
  468. @!charcode_octal = 1;
  469. @!charcode_default = 2;
  470.  
  471. @
  472. @<Global...@> =
  473. @!charcode_format: charcode_format_type;
  474.  
  475. @ It starts off as the default, that is, we output letters and digits as
  476. ASCII characters, everything else in octal.
  477.  
  478. @<Initialize the option...@> =
  479. charcode_format := charcode_default;
  480.  
  481.  
  482. @ An element with all zeros always ends the list.
  483.  
  484. @<Define the option...@> =
  485. long_options[current_option].name := 0;
  486. long_options[current_option].has_arg := 0;
  487. long_options[current_option].flag := 0;
  488. long_options[current_option].val := 0;
  489.  
  490.  
  491. @ Pascal compilers won't count the number of elements in an array
  492. constant for us.  This doesn't include the zero-element at the end,
  493. because this array starts at index zero.
  494.  
  495. @<Constants...@> =
  496. @!n_options = 2;
  497. @!arg_options = 1;
  498. @z
  499.