1% odvicopy.ch: web2c changes for odvicopy.web 2% 3% This file is part of the Omega project, which 4% is based in the web2c distribution of TeX. 5% 6% Copyright 2006 Karl Berry (to fix int_8 for AIX). 7% Copyright (c) 1994--1998 John Plaice and Yannis Haralambous 8% applies only to the changes to the original dvicopy.ch. 9% 10% dvicopy.ch for C compilation with web2c. 11% The original version of this file was created by Monika Jayme and 12% Klaus Guntermann at TH Darmstadt (THD), FR Germany. 13% Some parts are borrowed from the changes to dvitype, vftovp and vptovf. 14% 15% July 90 THD First versions for dvicopy 0.91 and 0.92 16% Aug 09 90 THD Updated to dvicopy 1.0 and released 17% Mar 20 91 THD Updated to dvicopy 1.2 18% (more recent changes in the ChangeLog) 19 20@x [0] WEAVE: print changes only 21\pageno=\contentspagenumber \advance\pageno by 1 22@y 23\pageno=\contentspagenumber \advance\pageno by 1 24\let\maybe=\iffalse 25@z 26 27@x [1] Define my_name 28@d banner=='This is ODVIcopy, Version 1.6' {printed when the program starts} 29@y 30@d my_name=='odvicopy' 31@d banner=='This is ODVIcopy, Version 1.6' {printed when the program starts} 32@z 33 34@x [2] No random reading on stdin, may be not seekable. 35@d random_reading==true {should we skip around in the file?} 36@y 37@<Globals in the outer block@>= 38@!random_reading:boolean; {should we skip around in the file?} 39@z 40 41@x [3] Set up kpathsea. 42procedure initialize; {this procedure gets things started properly} 43 var @<Local variables for initialization@>@/ 44 begin print_ln(banner);@/ 45@y 46@<Define |parse_arguments|@> 47procedure initialize; {this procedure gets things started properly} 48 var @<Local variables for initialization@>@/ 49 begin 50 kpse_set_program_name (argv[0], my_name); 51 parse_arguments; 52 print (banner); print_ln (version_string); 53@z 54 55@x [5] Big enough arrays to convert the dvilj sample font document. 56@<Constants...@>= 57@!max_fonts=100; {maximum number of distinct fonts} 58@!max_chars=10000; {maximum number of different characters among all fonts} 59@!max_widths=3000; {maximum number of different characters widths} 60@!max_packets=5000; {maximum number of different characters packets; 61 must be less than 65536} 62@!max_bytes=30000; {maximum number of bytes for characters packets} 63@!max_recursion=10; {\.{VF} files shouldn't recurse beyond this level} 64@!stack_size=100; {\.{DVI} files shouldn't |push| beyond this depth} 65@!terminal_line_length=150; {maximum number of characters input in a single 66 line of input from the terminal} 67@!name_length=50; {a file name shouldn't be longer than this} 68@y 69@<Constants...@>= 70@!max_fonts=1000; {maximum number of distinct fonts} 71@!max_chars=750000; {maximum number of different characters among all fonts} 72@!max_widths=10000; {maximum number of different characters widths} 73@!max_packets=100000; {maximum number of different characters packets; 74 must be less than 65536} 75@!max_bytes=3000000; {maximum number of bytes for characters packets} 76@!max_recursion=10; {\.{VF} files shouldn't recurse beyond this level} 77@!stack_size=100; {\.{DVI} files shouldn't |push| beyond this depth} 78@!terminal_line_length=256; {maximum number of characters input in a single 79 line of input from the terminal} 80@z 81 82% [7] int_8 conflicts with <sys/inttypes.h> on AIX. 83% It just gets turned into schar anyway, so use that. 84@x 85@d int_32 == integer {signed 32~bit integers} 86@y 87@d int_32 == integer {signed 32~bit integers} 88@d int_8 == int_8_odvicopy {avoid C declaration collision on AIX} 89@z 90% 91@x 92@!int_8 = -@"80..@"7F; {signed 8~bit integer} 93@y 94@!int_8_odvicopy = -@"80..@"7F; {signed 8~bit integer} 95@z 96 97% [11] Redirect output, so it can go to either stdout or stderr, 98% depending on where the output dvi file is going. 99@x 100@d print(#)==write(output,#) 101@d print_ln(#)==write_ln(output,#) 102@d new_line==write_ln(output) {start new line} 103@y 104@d print(#)==write(term_out,#) 105@d print_ln(#)==write_ln(term_out,#) 106@d new_line==write_ln(term_out) {start new line} 107@z 108 109@x [14] Permissive input. 110@!ASCII_code=" ".."~"; {a subrange of the integers} 111@y 112@!ASCII_code=0..255; {a subrange of the integers} 113@z 114 115% [15] The text_char type is used as an array index into xord. The 116% default type `char' produces signed integers, which are bad array 117% indices in C. 118@x 119@d text_char == char {the data type of characters in text files} 120@d first_text_char=0 {ordinal number of the smallest element of |text_char|} 121@d last_text_char=127 {ordinal number of the largest element of |text_char|} 122@y 123@d text_char == ASCII_code {the data type of characters in text files} 124@d first_text_char=0 {ordinal number of the smallest element of |text_char|} 125@d last_text_char=255 {ordinal number of the largest element of |text_char|} 126@z 127 128@x [23] Remove non-local goto, declare jump_out as noreturn 129@d abort(#)==begin print_ln(' ',#,'.'); jump_out; 130 end 131 132@<Error handling...@>= 133@<Basic printing procedures@>@; 134procedure close_files_and_terminate; forward; 135@# 136procedure jump_out; 137begin mark_fatal; close_files_and_terminate; 138goto final_end; 139end; 140@y 141@d abort(#)==begin write_ln(stderr, ' ',#,'.'); jump_out; 142 end 143 144@<Error handling...@>= 145@<Basic printing procedures@>@; 146procedure close_files_and_terminate; forward; 147@# 148noreturn procedure jump_out; 149begin mark_fatal; close_files_and_terminate; 150uexit(1); 151end; 152@z 153 154@x [24] Declare confusion as noreturn 155procedure confusion(@!p:pckt_pointer); 156@y 157noreturn procedure confusion(@!p:pckt_pointer); 158@z 159 160@x [25] Declare overflow as noreturn 161procedure overflow(@!p:pckt_pointer;@!n:int_16u); 162@y 163noreturn procedure overflow(@!p:pckt_pointer;@!n:int_16u); 164@z 165 166@x [62] cur_name is no longer a fixed-size array. 167@!cur_name:packed array[1..name_length] of char; {external name, 168 with no lower case letters} 169@y 170@!cur_name:^char; 171@z 172 173@x [63] Ignore arguments to make_font_name. 174@ For \.{TFM} and \.{VF} files we just append the appropriate extension 175to the file name packet; in addition a system dependent area part 176(usually different for \.{TFM} and \.{VF} files) is prepended if 177the file name packet contains no area part. 178@^system dependencies@> 179 180@d append_to_name(#)== 181 if l_cur_name<name_length then 182 begin incr(l_cur_name); cur_name[l_cur_name]:=#; 183 end 184 else overflow(str_name_length,name_length) 185@d make_font_name_end(#)== 186 append_to_name(#[l]); make_name 187@d make_font_name(#)== 188 l_cur_name:=0; for l:=1 to # do make_font_name_end 189@y 190@ Since files are actually searched through path definitions, 191the area definitions are ignored here. 192To reduce the required changes we simply ignore the parameters given 193to |make_font_name|. 194@^system dependencies@> 195 196@d append_to_name(#)== begin 197 cur_name[l_cur_name]:=#; 198 incr(l_cur_name); 199 end 200@d make_font_name_end(#)== 201 make_name 202@d make_font_name(#)== 203 l_cur_name:=0; make_font_name_end 204@z 205 206% [67] No conversion of filenames in lower case, and initialize and 207% terminate for C strings. Eliminate now unused variable. 208@x 209@!c:char; {a character to be appended to |cur_name|} 210@y 211@z 212 213@x 214cur_loc:=pckt_start[n]; cur_limit:=pckt_start[n+1]; 215@y 216cur_name := xmalloc_array (char, pckt_length (n) + pckt_length (e)); 217cur_loc:=pckt_start[n]; cur_limit:=pckt_start[n+1]; 218@z 219 220@x 221 if (b>="a")and(b<="z") then Decr(b)(("a"-"A")); {convert to upper case} 222@y 223@z 224 225@x 226cur_loc:=pckt_start[e]; cur_limit:=pckt_start[e+1]; 227while cur_loc<cur_limit do 228 begin pckt_extract(b); append_res_to_name(xchr[b]); 229 end; 230while l_cur_name<name_length do 231 begin incr(l_cur_name); cur_name[l_cur_name]:=' '; 232 end; 233@y Skip copying in the extension, kpathsea knows what to do. 234 cur_name[l_cur_name] := 0; 235@z 236 237@x [91] Lower case file name extensions. 238id4(".")("T")("F")("M")(tfm_ext); {file name extension for \.{TFM} files} 239id4(".")("O")("F")("M")(ofm_ext); {file name extension for \.{OFM} files} 240@y 241id4(".")("t")("f")("m")(tfm_ext); {file name extension for \.{TFM} files} 242id4(".")("o")("f")("m")(ofm_ext); {file name extension for \.{OFM} files} 243@z 244 245@x [92] Set default directory name 246@ If no font directory has been specified, \.{\title} is supposed to use 247the default \.{TFM} directory, which is a system-dependent place where 248the \.{TFM} files for standard fonts are kept. 249The string variable |TFM_default_area| contains the name of this area. 250@^system dependencies@> 251 252@d TFM_default_area_name=='TeXfonts:' {change this to the correct name} 253@d OFM_default_area_name=='TeXfonts:' {change this to the correct name} 254@d TFM_default_area_name_length=9 {change this to the correct length} 255@d OFM_default_area_name_length=9 {change this to the correct length} 256 257@<Glob...@>= 258@!TFM_default_area:packed array[1..TFM_default_area_name_length] of char; 259@!OFM_default_area:packed array[1..OFM_default_area_name_length] of char; 260@y 261@ If no font directory has been specified, we search paths. 262@z 263 264@x [93] Remove initialization of now-defunct array 265@ @<Set init...@>= 266TFM_default_area:=TFM_default_area_name; 267OFM_default_area:=OFM_default_area_name; 268@y 269@ (No initialization to be done. Keep this module to preserve numbering.) 270@z 271 272@x [94] Declare bad_tfm as noreturn 273procedure bad_tfm; 274@y 275noreturn procedure bad_tfm; 276@z 277 278@x [94] Declare bad_font as noreturn 279procedure bad_font; 280@y 281noreturn procedure bad_font; 282@z 283 284@x [95] Open TFM file 285@<TFM: Open |tfm_file|@>= 286make_font_name(TFM_default_area_name_length)(TFM_default_area)(tfm_ext); 287reset(tfm_file,cur_name); 288if eof(tfm_file) then begin 289 make_font_name(OFM_default_area_name_length)(OFM_default_area)(ofm_ext); 290 reset(tfm_file,cur_name); 291 if eof(tfm_file) then 292@^system dependencies@> 293 abort('---not loaded, TFM or OFM file can''t be opened!') 294@y 295|TFM_default_area_name_length| and |TFM_default_area| will not 296be used by |make_font_name|. 297 298@<TFM: Open |tfm_file|@>= 299make_font_name(TFM_default_area_name_length)(TFM_default_area)(tfm_ext); 300full_name := kpse_find_tfm (cur_name); 301if full_name then begin 302 resetbin (tfm_file, full_name); 303 free (cur_name); 304 free (full_name); 305 end 306else begin 307 make_font_name(OFM_default_area_name_length)(OFM_default_area)(ofm_ext); 308 full_name := kpse_find_ofm (cur_name); 309 if full_name then begin 310 resetbin (tfm_file, full_name); 311 free (cur_name); 312 free (full_name); 313 end 314 else abort('---not loaded, TFM or OFM file can''t be opened!') 315@z 316 317@x [99] 318close_in(tfm_file); 319@y 320xfclose(tfm_file, cur_name); 321@z 322 323@x [101] Avoid compiler warnings 324read_tfm_word; tfm_b01(first_two); 325@y 326nco:=0; extra_words:=0; 327read_tfm_word; tfm_b01(first_two); 328@z 329 330@x [108] Declare full_name. 331@!dvi_loc:int_32; {where we are about to look, in |dvi_file|} 332@y 333@!dvi_loc:int_32; {where we are about to look, in |dvi_file|} 334@!full_name: ^char; 335@z 336 337@x [109] Declare bad_dvi as noreturn 338procedure bad_dvi; 339@y 340noreturn procedure bad_dvi; 341@z 342 343@x [111] Fix up opening the binary files 344@ To prepare |dvi_file| for input, we |reset| it. 345 346@<Open input file(s)@>= 347reset(dvi_file); {prepares to read packed bytes from |dvi_file|} 348dvi_loc:=0; 349@y 350@ To prepare |dvi_file| for input, we |reset| it. 351 352@<Open input file(s)@>= 353dvi_loc:=0; 354@z 355 356@x [113] Make dvi_length() and dvi_move() work. 357@p function dvi_length:int_32; 358begin set_pos(dvi_file,-1); dvi_length:=cur_pos(dvi_file); 359end; 360@# 361procedure dvi_move(@!n:int_32); 362begin set_pos(dvi_file,n); dvi_loc:=n; 363end; 364@y 365@p function dvi_length:int_32; 366begin xfseek(dvi_file, 0, 2, dvi_name); 367dvi_loc:=xftell(dvi_file, dvi_name); 368dvi_length:=dvi_loc; 369end; 370@# 371procedure dvi_move(n:int_32); 372begin xfseek(dvi_file, n, 0, dvi_name); 373dvi_loc:=n; 374end; 375@z 376 377@x [135] Lower case file name extensions. 378id3(".")("V")("F")(vf_ext); {file name extension for \.{VF} files} 379id4(".")("O")("V")("F")(ovf_ext); {file name extension for \.{OVF} files} 380@y 381id3(".")("v")("f")(vf_ext); {file name extension for \.{VF} files} 382id4(".")("o")("v")("f")(ovf_ext); {file name extension for \.{OVF} files} 383@z 384 385@x [137/138] Set default directory name 386@ If no font directory has been specified, \.{\title} is supposed to use 387the default \.{VF} directory, which is a system-dependent place where 388the \.{VF} files for standard fonts are kept. 389The string variable |VF_default_area| contains the name of this area. 390@^system dependencies@> 391 392@d VF_default_area_name=='TeXvfonts:' {change this to the correct name} 393@d VF_default_area_name_length=10 {change this to the correct length} 394@d OVF_default_area_name=='TeXvfonts:' {change this to the correct name} 395@d OVF_default_area_name_length=10 {change this to the correct length} 396 397@<Glob...@>= 398@!VF_default_area:packed array[1..VF_default_area_name_length] of char; 399@!OVF_default_area:packed array[1..OVF_default_area_name_length] of char; 400 401@ @<Set init...@>= 402VF_default_area:=VF_default_area_name; 403OVF_default_area:=OVF_default_area_name; 404@y 405@ If no font directory has been specified, \.{\title} is supposed to use 406the default \.{VF} directory, which is a system-dependent place where 407the \.{VF} files for standard fonts are kept. 408 409Actually, under UNIX the standard area is defined in an external 410file \.{site.h}. And the users have a path searched for fonts, 411by setting the \.{VFFONTS} environment variable. 412 413@ (No initialization to be done. Keep this module to preserve numbering.) 414@z 415 416@x [139] Open VF file 417@<VF: Open |vf_file| or |goto not_found|@>= 418make_font_name(VF_default_area_name_length)(VF_default_area)(vf_ext); 419reset(vf_file,cur_name); 420if eof(vf_file) then begin 421 make_font_name(OVF_default_area_name_length)(OVF_default_area)(ovf_ext); 422 reset(vf_file,cur_name); 423 if eof(vf_file) then 424@^system dependencies@> 425 goto not_found 426 end; 427@y 428Do path searching. But the \.{VF} file may not exist. 429 430@<VF: Open |vf_file| or |goto not_found|@>= 431make_font_name(VF_default_area_name_length)(VF_default_area)(vf_ext); 432full_name := kpse_find_vf (cur_name); 433if full_name then begin 434 resetbin (vf_file, full_name); 435 free (cur_name); 436 free (full_name); 437 end 438else begin 439 make_font_name(OVF_default_area_name_length)(OVF_default_area)(ovf_ext); 440 full_name := kpse_find_ovf (cur_name); 441 if full_name then begin 442 resetbin (vf_file, full_name); 443 free (cur_name); 444 free (full_name); 445 end 446 else goto not_found 447 end; 448@z 449 450@x [151] 451close_in(vf_file); 452@y 453xfclose(vf_file,cur_name); 454@z 455 456@x [163] copy elements of array piece by piece 457@ @<VF: Start a new level@>= 458append_one(push); 459vf_move[vf_ptr]:=vf_move[vf_ptr-1]; 460@y 461@ \.{web2c} does not like array assignments. So we need to do them 462through a macro replacement. 463 464@d do_vf_move(#) == vf_move[vf_ptr]# := vf_move[vf_ptr-1]# 465@d vf_move_assign == begin do_vf_move([0][0]); do_vf_move([0][1]); 466 do_vf_move([1][0]); do_vf_move([1][1]) 467 end 468 469@<VF: Start a new level@>= 470append_one(push); 471vf_move_assign; 472@z 473 474@x [170] and again... 475 vf_move[vf_ptr]:=vf_move[vf_ptr-1]; 476@y 477 vf_move_assign; 478@z 479 480@x [176] break is fflush. 481@d update_terminal == break(output) {empty the terminal output buffer} 482@y 483@d update_terminal == fflush(stdout) {empty the terminal output buffer} 484@z 485 486@x [176] 487procedure input_ln; {inputs a line from the terminal} 488var k:0..terminal_line_length; 489begin if n_opt=0 then 490 begin print('Enter option: '); update_terminal; reset(input); 491 if eoln(input) then read_ln(input); 492 k:=0; pckt_room(terminal_line_length); 493 while (k<terminal_line_length)and not eoln(input) do 494 begin append_byte(xord[input^]); incr(k); get(input); 495 end; 496 end 497else if k_opt<n_opt then 498 begin incr(k_opt); 499 {Copy command line option number |k_opt| into |byte_mem| array!} 500 end; 501end; 502@y 503procedure input_ln; {inputs a line from the terminal} 504var k:0..terminal_line_length; 505begin print('Enter option: '); update_terminal; 506{|if eoln(input) then read_ln(input);|} 507k:=0; pckt_room(terminal_line_length); 508while (k<terminal_line_length)and not eoln(input) do 509 begin append_byte(xord[getc(input)]); incr(k); 510 end; 511end; 512@z 513 514@x [241] No dialog, remove unused final label. 515dialog; {get options} 516@y 517@z 518@x 519final_end:end. 520@y 521end. 522@z 523 524@x [245] Do this later, to avoid creating empty files. 525@<Open output file(s)@>= 526rewrite(out_file); {prepares to write packed bytes to |out_file|} 527@y 528@<Open output file(s)@>= 529@z 530 531@x [247] Use external routine to output bytes. 532@d out_byte(#) == write(out_file,#) {write next \.{DVI} byte} 533@y 534@d out_byte(#) == put_byte(#,out_file) {write next \.{DVI} byte} 535@z 536 537@x [260] String declaration. 538@!comment:packed array[1..comm_length] of char; {preamble comment prefix} 539@y 540@!comment:const_c_string; {preamble comment prefix} 541@z 542 543@x [261] Output the string from 0 to len-1, not 1 to len. 544for k:=1 to comm_length do append_byte(xord[comment[k]]); 545@y 546for k:=0 to comm_length - 1 do append_byte(xord[ucharcast(comment[k])]); 547@z 548 549@x [293] System-dependent changes. 550This section should be replaced, if necessary, by changes to the program 551that are necessary to make \.{DVIcopy} work at a particular installation. 552It is usually best to design your change file so that all changes to 553previous sections preserve the section numbering; then everybody's version 554will be consistent with the printed program. More extensive changes, 555which introduce new sections, can be inserted here; then only the index 556itself will get a new section number. 557@^system dependencies@> 558@y 559Parse a Unix-style command line. 560 561This macro tests if its argument is the current option, as represented 562by the index variable |option_index|. 563 564@d argument_is (#) == (strcmp (long_options[option_index].name, #) = 0) 565 566@<Define |parse_arguments|@> = 567procedure parse_arguments; 568const n_options = 5; {Pascal won't count array lengths for us.} 569var @!long_options: array[0..n_options] of getopt_struct; 570 @!getopt_return_val: integer; 571 @!option_index: c_int_type; 572 @!current_option: 0..n_options; 573 @!k, @!m: c_int_type; 574 @!end_num: ^char; 575begin 576 @<Define the option table@>; 577 @<Initialize options@>; 578 repeat 579 getopt_return_val := getopt_long_only (argc, argv, '', long_options, 580 address_of (option_index)); 581 if getopt_return_val = -1 then begin 582 {End of arguments; we exit the loop below.} ; 583 584 end else if getopt_return_val = "?" then begin 585 usage (my_name); 586 587 end else if argument_is ('help') then begin 588 usage_help (ODVICOPY_HELP, nil); 589 590 end else if argument_is ('version') then begin 591 print_version_and_exit 592 (banner, 'J. Plaice, Y. Haralambous, P. Breitenlohner', nil, nil); 593 594 end else if argument_is ('magnification') then begin 595 out_mag := atou (optarg); 596 597 end else if argument_is ('max-pages') then begin 598 max_pages := atou (optarg); 599 incr (cur_select); 600 601 end else if argument_is ('page-start') then begin 602 @<Determine the desired |start_count| values from |optarg|@>; 603 604 end; {Else it was a flag; |getopt| has already done the assignment.} 605 until getopt_return_val = -1; 606 607 {Now |optind| is the index of first non-option on the command line. 608 We can have zero, one, or two remaining arguments.} 609 if (optind > argc) or (optind + 2 < argc) then begin 610 write_ln (stderr, my_name, ': Need at most two file arguments.'); 611 usage (my_name); 612 end; 613 614 if optind = argc then begin 615 dvi_name := '<stdin>'; 616 dvi_file := make_binary_file (stdin); 617 random_reading := false; 618 end else begin 619 dvi_name := extend_filename (cmdline (optind), 'dvi'); 620 resetbin (dvi_file, dvi_name); 621 random_reading := true; 622 end; 623 624 if optind + 2 = argc then begin 625 rewritebin (out_file, extend_filename (cmdline (optind + 1), 'dvi')); 626 term_out := stdout; 627 end else begin 628 out_file := make_binary_file (stdout); 629 term_out := stderr; 630 end; 631end; 632 633@ Here is the first of the options we allow. 634@.-help@> 635 636@<Define the option...@> = 637current_option := 0; 638long_options[0].name := 'help'; 639long_options[0].has_arg := 0; 640long_options[0].flag := 0; 641long_options[0].val := 0; 642incr (current_option); 643 644@ Another of the standard options. 645@.-version@> 646 647@<Define the option...@> = 648long_options[current_option].name := 'version'; 649long_options[current_option].has_arg := 0; 650long_options[current_option].flag := 0; 651long_options[current_option].val := 0; 652incr (current_option); 653 654@ Magnification to apply. 655@.-magnification@> 656 657@<Define the option...@> = 658long_options[current_option].name := 'magnification'; 659long_options[current_option].has_arg := 1; 660long_options[current_option].flag := 0; 661long_options[current_option].val := 0; 662incr (current_option); 663 664@ How many pages to do. 665@.-max-pages@> 666 667@<Define the option...@> = 668long_options[current_option].name := 'max-pages'; 669long_options[current_option].has_arg := 1; 670long_options[current_option].flag := 0; 671long_options[current_option].val := 0; 672incr (current_option); 673 674@ What page to start at. 675@.-page-start@> 676 677@<Define the option...@> = 678long_options[current_option].name := 'page-start'; 679long_options[current_option].has_arg := 1; 680long_options[current_option].flag := 0; 681long_options[current_option].val := 0; 682incr (current_option); 683 684@ Parsing the starting page specification is a bit complicated. 685(This is the same as in \.{DVItype}.) 686 687@<Determine the desired |start_count|...@> = 688k := 0; {which \.{\\count} register we're on} 689m := 0; {position in |optarg|} 690while optarg[m] do begin 691 if optarg[m] = "*" then begin 692 start_there[k] := false; 693 incr (m); 694 695 end else if optarg[m] = "." then begin 696 incr (k); 697 if k >= 10 then begin 698 write_ln (stderr, my_name, ': More than ten count registers specified.'); 699 uexit (1); 700 end; 701 incr (m); 702 703 end else begin 704 start_count[k] := strtol (optarg + m, address_of (end_num), 10); 705 if end_num = optarg + m then begin 706 write_ln (stderr, my_name, ': -page-start values must be numeric or *.'); 707 uexit (1); 708 end; 709 start_there[k] := true; 710 m := m + end_num - (optarg + m); 711 end; 712end; 713start_vals := k; 714selected := false; 715 716@ An element with all zeros always ends the list. 717 718@<Define the option...@> = 719long_options[current_option].name := 0; 720long_options[current_option].has_arg := 0; 721long_options[current_option].flag := 0; 722long_options[current_option].val := 0; 723 724@ @<Glob...@> = 725@!term_out:text; 726@!dvi_name:const_c_string; 727@z 728