OSDN Git Service

long options.
[putex/putex.git] / src / texsourc / tex3.c
1 #ifdef _WINDOWS
2   #define NOCOMM
3   #define NOSOUND
4   #define NODRIVERS
5   #define STRICT
6   #pragma warning(disable:4115) // kill rpcasync.h complaint
7   #include <windows.h>
8   #define MYLIBAPI __declspec(dllexport)
9 #endif
10
11 #pragma warning(disable:4996)
12 #pragma warning(disable:4131) // old style declarator
13 #pragma warning(disable:4135) // conversion between different integral types 
14 #pragma warning(disable:4127) // conditional expression is constant
15
16 #include <setjmp.h>
17
18 #define EXTERN extern
19
20 #include "texd.h"
21
22 #pragma warning(disable:4244)       /* 96/Jan/10 */
23
24 /* sec 0440 */
25 void scan_int (void)
26 {
27   bool negative;
28   integer m;
29   small_number d;
30   bool vacuous;
31   bool OKsofar;
32
33   radix = 0;
34   OKsofar = true;
35   negative = false;
36
37   do
38     {
39       do 
40         {
41           get_x_token();
42         }
43       while (!(cur_cmd != spacer));
44
45       if (cur_tok == other_token + '-')
46       {
47         negative = !negative;
48         cur_tok = other_token + '+';
49       }
50     }
51   while (!(cur_tok != other_token + '+'));
52
53   if (cur_tok == alpha_token)
54   {
55     get_token();
56
57     if (cur_tok < cs_token_flag)
58     {
59       cur_val = cur_chr;
60
61       if (cur_cmd <= right_brace)
62         if (cur_cmd == right_brace)
63           incr(align_state);
64         else
65           decr(align_state);
66     }
67     else if (cur_tok < cs_token_flag + single_base)
68       cur_val = cur_tok - cs_token_flag - active_base;
69     else
70       cur_val = cur_tok - cs_token_flag - single_base;
71
72     if (cur_val > 255)
73     {
74       print_err("Improper alphabetic constant");
75       help2("A one-character control sequence belongs after a ` mark.",
76         "So I'm essentially inserting \\0 here.");
77       cur_val = '0';
78       back_error();
79     }
80     else
81     {
82       get_x_token();
83
84       if (cur_cmd != spacer)
85         back_input();
86     }
87   }
88   else if ((cur_cmd >= min_internal) && (cur_cmd <= max_internal))
89   {
90     scan_something_internal(int_val, false);
91   }
92   else
93   {
94     radix = 10;
95     m = 214748364L;   /* 7FFFFFFF hex */
96
97     if (cur_tok == octal_token)
98     {
99       radix = 8;
100       m = 268435456L;   /* 2^28 */
101       get_x_token();
102     }
103     else if (cur_tok == hex_token)
104     {
105       radix = 16;
106       m = 134217728L;   /* 2^27 8000000 hex */
107       get_x_token();
108     }
109
110     vacuous = true;
111     cur_val = 0;
112
113     while (true)
114     {
115       if ((cur_tok < zero_token + radix) && (cur_tok >= zero_token) && (cur_tok <= zero_token + 9))
116         d = cur_tok - zero_token;
117       else if (radix == 16)
118         if ((cur_tok <= A_token + 5) && (cur_tok >= A_token))
119           d = cur_tok - A_token + 10;
120         else if ((cur_tok <= other_A_token + 5) && (cur_tok >= other_A_token))
121           d = cur_tok - other_A_token;
122         else
123           goto lab30;
124       else
125         goto lab30;
126
127       vacuous = false;
128
129       if ((cur_val >= m) && ((cur_val > m) || (d > 7) || (radix != 10)))
130       {
131         if (OKsofar)
132         {
133           print_err("Number too big");
134           help2("I can only go up to 2147483647='17777777777=\"7FFFFFFF,",
135             "so I'm using that number instead of yours.");
136           error();
137           cur_val = 2147483647L;    /* 7FFFFFFF hex */
138           OKsofar = false;
139         }
140       }
141       else
142         cur_val = cur_val * radix + d;
143       get_x_token();
144     }
145 lab30:;
146
147     if (vacuous)
148     {
149       print_err("Missing number, treated as zero");
150       help3("A number should have been here; I inserted `0'.",
151         "(If you can't figure out why I needed to see a number,",
152         "look up `weird error' in the index to The TeXbook.)");
153       back_error();
154     } 
155     else if (cur_cmd != spacer)
156       back_input();
157   }
158
159   if (negative)
160     cur_val = - (integer) cur_val;
161 }
162 /* sec 0448 */
163 void scan_dimen_(bool mu, bool inf, bool shortcut)
164 {
165   bool negative;
166   integer f;
167   integer num, denom;
168   small_number k, kk;
169   halfword p, q;
170   scaled v;
171   integer savecurval;
172
173   f = 0;
174   arith_error = false;
175   cur_order = 0;
176   negative = false;
177
178   if (!shortcut)
179   {
180     negative = false;
181
182     do
183       {
184         do
185           {
186             get_x_token();
187           }
188         while (!(cur_cmd != spacer));
189
190         if (cur_tok == other_token + '-')
191         {
192           negative = ! negative;
193           cur_tok = other_token + '+';
194         }
195       }
196     while (!(cur_tok != other_token + '+'));
197
198     if ((cur_cmd >= min_internal) && (cur_cmd <= max_internal))
199     {
200       if (mu)
201       {
202         scan_something_internal(mu_val, false);
203
204         if (cur_val_level >= glue_val)
205         {
206           v = width(cur_val);
207           delete_glue_ref(cur_val);
208           cur_val = v;
209         }
210
211         if (cur_val_level == mu_val)
212           goto lab89;
213
214         if (cur_val_level != int_val)
215           mu_error();
216       }
217       else
218       {
219         scan_something_internal(dimen_val, false);
220
221         if (cur_val_level == dimen_val)
222           goto lab89;
223       }
224     }
225     else
226     {
227       back_input();
228
229       if (cur_tok == continental_point_token)
230         cur_tok = point_token;
231
232       if (cur_tok != point_token)
233       {
234         scan_int();
235       }
236       else
237       {
238         radix = 10;
239         cur_val = 0;
240       }
241
242       if (cur_tok == continental_point_token)
243         cur_tok = point_token;
244
245       if ((radix == 10) && (cur_tok == point_token))
246       {
247         k = 0;
248         p = 0;      /* p:=null l.8883 */
249         get_token();
250
251         while (true)
252         {
253           get_x_token();
254
255           if ((cur_tok > zero_token + 9) || (cur_tok < zero_token))
256             goto lab31;
257
258           if (k < 17)
259           {
260             q = get_avail();
261             link(q) = p;
262             info(q) = cur_tok - zero_token;
263             p = q;
264             incr(k);
265           }
266         }
267 lab31:
268         for (kk = k; kk >= 1; kk--)
269         {
270           dig[kk - 1] = info(p);
271           q = p;
272           p = link(p);
273           free_avail(q);
274         }
275
276         f = round_decimals(k);
277
278         if (cur_cmd != spacer)
279           back_input();
280         }
281       }
282   }
283
284   if (cur_val < 0)
285   {
286     negative = !negative;
287     cur_val = - (integer) cur_val;
288   }
289
290   if (inf)
291   {
292     if (scan_keyword("fil"))
293     {
294       cur_order = fil;
295
296       while (scan_keyword("l"))
297       {
298         if (cur_order == filll)
299         {
300           print_err("Illegal unit of measure (");
301           print_string("replaced by filll)");
302           help1("I dddon't go any higher than filll.");
303           error();
304         }
305         else
306           incr(cur_order);
307       }
308       goto lab88;
309     }
310   }
311
312   savecurval = cur_val;
313
314   do
315     {
316       get_x_token();
317     }
318   while (!(cur_cmd != spacer));
319
320   if ((cur_cmd < min_internal) || (cur_cmd > max_internal))
321     back_input();
322   else
323   {
324     if (mu)
325     {
326       scan_something_internal(mu_val, false);
327
328       if (cur_val_level >= glue_val)
329       {
330         v = width(cur_val);
331         delete_glue_ref(cur_val);
332         cur_val = v;
333       }
334
335       if (cur_val_level != mu_val)
336       {
337         mu_error();
338       }
339     }
340     else
341     {
342       scan_something_internal(dimen_val, false);
343     }
344
345     v = cur_val;
346     goto lab40;
347   }
348
349   if (mu)
350     goto lab45;
351
352   if (scan_keyword("em"))
353     v = quad(cur_font);
354   else if (scan_keyword("ex"))
355     v = x_height(cur_font);
356   else
357     goto lab45;
358
359   {
360     get_x_token();
361
362     if (cur_cmd != spacer)
363       back_input();
364   }
365 lab40:
366   cur_val = mult_and_add(savecurval, v, xn_over_d(v, f, 65536L), 1073741823L);   /* 2^30 - 1 */
367   goto lab89;
368 lab45:
369   if (mu)
370   {
371     if (scan_keyword("mu"))
372       goto lab88;
373     else
374     {
375       print_err("Illegal unit of measure (");
376       print_string("mu inserted)");
377       help4("The unit of measurement in math glue must be mu.",
378           "To recover gracefully from this error, it's best to",
379           "delete the erroneous units; e.g., type `2' to delete",
380           "two letters. (See Chapter 27 of The TeXbook.)");
381       error();
382       goto lab88;
383     }
384   }
385
386   if (scan_keyword("true"))
387   {
388     prepare_mag();
389
390     if (mag != 1000)
391     {
392       cur_val = xn_over_d(cur_val, 1000, mag);
393       f = (1000 * f + 65536L * tex_remainder) / mag;
394       cur_val = cur_val + (f / 65536L);
395       f = f % 65536L;
396     }
397   }
398
399   if (scan_keyword("pt"))
400     goto lab88;
401
402   if (scan_keyword("in"))
403   {
404     num = 7227;
405     denom = 100;
406   }
407   else if (scan_keyword("pc"))
408   {
409     num = 12;
410     denom = 1;
411   }
412   else if (scan_keyword("cm"))
413   {
414     num = 7227;
415     denom = 254;
416   }
417   else if (scan_keyword("mm"))
418   {
419     num = 7227;
420     denom = 2540;
421   }
422   else if (scan_keyword("bp"))
423   {
424     num = 7227;
425     denom = 7200;
426   }
427   else if (scan_keyword("dd"))
428   {
429     num = 1238;
430     denom = 1157;
431   }
432   else if (scan_keyword("cc"))
433   {
434     num = 14856;
435     denom = 1157;
436   }
437   else if (scan_keyword("Q"))
438   {
439     num = 7227;
440     denom = 10160;
441   }
442   else if (scan_keyword("H"))
443   {
444     num = 7227;
445     denom = 10160;
446   }
447   else if (scan_keyword("sp"))
448     goto lab30;
449   else
450   {
451     print_err("Illegal unit of measure (");
452     print_string("pt inserted)");
453     help6("Dimensions can be in units of em, ex, in, pt, pc,",
454       "cm, mm, dd, cc, bp, or sp; but yours is a new one!",
455       "I'll assume that you meant to say pt, for printer's points.",
456       "To recover gracefully from this error, it's best to",
457       "delete the erroneous units; e.g., type `2' to delete",
458       "two letters. (See Chapter 27 of The TeXbook.)");
459     error();
460     goto lab32;
461   }
462
463   cur_val = xn_over_d(cur_val, num, denom);
464   f = (num * f + 65536L * tex_remainder) / denom;
465   cur_val = cur_val +(f / 65536L);
466   f = f % 65536L;
467 lab32:;
468 lab88:
469   if (cur_val >= 16384)     /* 2^14 */
470     arith_error = true;
471   else
472     cur_val = cur_val * 65536L + f;
473 lab30:;
474   {
475     get_x_token();
476
477     if (cur_cmd != spacer)
478       back_input();
479   }
480 lab89:
481   if (arith_error || (abs(cur_val) >= 1073741824L)) /* 2^30 */
482   {
483     print_err("Dimension too large");
484     help2("I can't work with sizes bigger than about 19 feet.",
485         "Continue and I'll use the largest value I can.");
486     error();
487     cur_val = 1073741823L;  /* 2^30 - 1 */
488     arith_error = false;
489   }
490
491   if (negative)
492     cur_val = - (integer) cur_val;
493 }
494 /* sec 0461 */
495 void scan_glue_(small_number level)
496 {
497   bool negative;
498   halfword q;
499   bool mu;
500
501   mu = (level == mu_val);
502   negative = false;
503
504   do
505     {
506       do
507         {
508           get_x_token();
509         }
510       while (!(cur_cmd != spacer));
511
512       if (cur_tok == other_token + '-')
513       {
514         negative = !negative;
515         cur_tok = other_token + '+';
516       }
517     }
518   while (!(cur_tok != other_token + '+'));
519
520   if ((cur_cmd >= min_internal) && (cur_cmd <= max_internal))
521   {
522     scan_something_internal(level, negative);
523
524     if (cur_val_level >= glue_val)
525     {
526       if (cur_val_level != level)
527       {
528         mu_error();
529       }
530       return;
531     }
532
533     if (cur_val_level == int_val)
534     {
535       scan_dimen(mu, false, true);
536     }
537     else if (level == mu_val)
538     {
539       mu_error();
540     }
541   }
542   else
543   {
544     back_input();
545     scan_dimen(mu, false, false);
546
547     if (negative)
548       cur_val = - (integer) cur_val;
549   }
550   q = new_spec(zero_glue);
551   width(q) = cur_val;
552
553   if (scan_keyword("plus"))
554   {
555     scan_dimen(mu, true, false);
556     stretch(q) = cur_val;
557     stretch_order(q) = cur_order;
558   }
559
560   if (scan_keyword("minus"))
561   {
562     scan_dimen(mu, true, false);
563     shrink(q) = cur_val;
564     shrink_order(q) = cur_order;
565   }
566
567   cur_val = q;
568 }
569 /* sec 0463 */
570 halfword scan_rule_spec (void)
571 {
572   halfword q;
573
574   q = new_rule();
575
576   if (cur_cmd == vrule)
577     width(q) = default_rule;
578   else
579   {
580     height(q) = default_rule;
581     depth(q) = 0;
582   }
583
584 lab21:
585
586   if (scan_keyword("width"))
587   {
588     scan_dimen(false, false, false);
589     width(q) = cur_val;
590     goto lab21;
591   }
592
593   if (scan_keyword("height"))
594   {
595     scan_dimen(false, false, false);
596     height(q) = cur_val;
597     goto lab21;
598   }
599
600   if (scan_keyword("depth"))
601   {
602     scan_dimen(false, false, false);
603     depth(q) = cur_val;
604     goto lab21;
605   }
606
607   return q;
608 }
609 /* sec 0464 */
610 halfword str_toks_(pool_pointer b)
611 {
612   halfword p;
613   halfword q;
614   halfword t;
615   pool_pointer k;
616
617   str_room(1);
618   p = temp_head;
619   link(p) = 0;
620   k = b;
621
622   while (k < pool_ptr)
623   {
624     t = str_pool[k];
625
626     if (t == ' ')
627       t = space_token;
628     else
629       t = other_token + t;
630     {
631       {
632         q = avail;
633
634         if (q == 0)
635           q = get_avail();
636         else
637         {
638           avail = mem[q].hh.v.RH;
639           mem[q].hh.v.RH = 0;
640 #ifdef STAT
641           incr(dyn_used); 
642 #endif /* STAT */
643         }
644       } 
645       mem[p].hh.v.RH = q;
646       mem[q].hh.v.LH = t;
647       p = q;
648     }
649     incr(k);
650   }
651   pool_ptr = b;
652
653   return p;
654 }
655 /* sec 0465 */
656 halfword the_toks (void)
657 {
658   register halfword Result;
659   char old_setting;
660   halfword p, q, r;
661   pool_pointer b;
662
663   get_x_token();
664   scan_something_internal(tok_val, false);
665
666   if (cur_val_level >= ident_val)
667   {
668     p = temp_head; 
669     link(p) = 0;
670
671     if (cur_val_level == ident_val)
672     {
673       q = get_avail();
674       mem[p].hh.v.RH = q;
675       mem[q].hh.v.LH = cs_token_flag + cur_val;
676       p = q;
677     }
678     else if (cur_val != 0)
679     {
680       r = link(cur_val);
681
682       while (r != 0) { /*   while r<>null do l.9178 */
683         {
684           {
685             q = avail;
686             if (q == 0)
687               q = get_avail();
688             else
689             {
690               avail = mem[q].hh.v.RH;
691               mem[q].hh.v.RH = 0;
692 #ifdef STAT
693               incr(dyn_used);
694 #endif /* STAT */
695             }
696           }
697           mem[p].hh.v.RH = q;
698           mem[q].hh.v.LH = mem[r].hh.v.LH;
699           p = q;
700         }
701         r = link(r);
702       }
703     }
704     Result = p;
705   }
706   else
707   {
708     old_setting = selector;
709     selector = new_string;
710     b = pool_ptr;
711
712     switch (cur_val_level)
713     {
714       case int_val:
715         print_int(cur_val);
716         break;
717       case dimen_val:
718         {
719           print_scaled(cur_val);
720           print_string("pt");
721         }
722         break;
723       case glue_val:
724         {
725           print_spec(cur_val, "pt");
726           delete_glue_ref(cur_val);
727         }
728         break;
729       case mu_val:
730         {
731           print_spec(cur_val, "mu");
732           delete_glue_ref(cur_val);
733         }
734         break;
735     }
736     selector = old_setting;
737     Result = str_toks(b);
738   }
739
740   return Result;
741 }
742 /* sec 0467 */
743 void ins_the_toks (void) 
744
745   link(garbage) = the_toks();
746   begin_token_list(link(temp_head), 4);
747 }
748 /* sec 0470 */
749 void conv_toks (void)
750 {
751   char old_setting;
752   char c;
753   small_number savescannerstatus;
754   pool_pointer b;
755
756   c = cur_chr;
757
758   switch (c)
759   {
760     case number_code:
761     case roman_numeral_code:
762       scan_int();
763       break;
764
765     case string_code:
766     case meaning_code:
767       savescannerstatus = scanner_status;
768       scanner_status = 0;
769       get_token();
770       scanner_status = savescannerstatus;
771       break;
772
773     case font_name_code:
774       scan_font_ident();
775       break;
776
777     case job_name_code:
778       if (job_name == 0)
779         open_log_file();
780       break;
781   }
782
783   old_setting = selector;
784   selector = new_string;
785   b = pool_ptr;
786
787   switch (c)
788   {
789     case number_code:
790       print_int(cur_val);
791       break;
792
793     case roman_numeral_code:
794       print_roman_int(cur_val);
795       break;
796
797     case string_code:
798       if (cur_cs != 0)
799         sprint_cs(cur_cs);
800       else
801         print_char(cur_chr);
802       break;
803
804     case meaning_code:
805       print_meaning();
806       break;
807
808     case font_name_code:
809       print(font_name[cur_val]);
810
811       if (font_size[cur_val] != font_dsize[cur_val])
812       {
813         print_string(" at ");
814         print_scaled(font_size[cur_val]);
815         print_string("pt");
816       }
817       break;
818
819     case job_name_code:
820       print(job_name);
821       break;
822   }
823
824   selector = old_setting;
825   link(garbage) = str_toks(b);
826   begin_token_list(link(temp_head), 4);
827 }
828 /* sec 0473 */
829 halfword scan_toks_(bool macrodef, bool xpand)
830 {
831   register halfword Result;
832   halfword t;
833   halfword s;
834   halfword p;
835   halfword q;
836   halfword unbalance;
837   halfword hashbrace;
838
839   if (macrodef)
840     scanner_status = defining;
841   else
842     scanner_status = absorbing;
843
844   warning_index = cur_cs;
845   def_ref = get_avail();
846   token_ref_count(def_ref) = 0;
847   p = def_ref;
848   hashbrace = 0;
849   t = zero_token;
850
851   if (macrodef)
852   {
853     while (true)
854     {
855       get_token();
856
857       if (cur_tok < right_brace_limit)
858         goto lab31;
859
860       if (cur_cmd == mac_param)
861       {
862         s = match_token + cur_chr;
863         get_token();
864
865         if (cur_cmd == left_brace)
866         {
867           hashbrace = cur_tok;
868           {
869             q = get_avail();
870             mem[p].hh.v.RH = q;
871             mem[q].hh.v.LH = cur_tok;
872             p = q;
873           }
874           {
875             q = get_avail();
876             mem[p].hh.v.RH = q;
877             mem[q].hh.v.LH = end_match_token;
878             p = q;
879           }
880           goto lab30;
881         }
882
883         if (t == zero_token + 9)
884         {
885           print_err("You already have nine parameters");
886           help1("I'm going to ignore the # sign you just used.");
887           error();
888         }
889         else
890         {
891           incr(t);
892
893           if (cur_tok != t)
894           {
895             print_err("Parameters must be numbered consecutively");
896             help2("I've inserted the digit you should have used after the #.",
897                 "Type `1' to delete what you did use.");
898             back_error();
899           }
900           cur_tok = s;
901         }
902       }
903       {
904         q = get_avail();
905         mem[p].hh.v.RH = q;
906         mem[q].hh.v.LH = cur_tok;
907         p = q;
908       }
909     }
910 lab31:
911     {
912       q = get_avail();
913       mem[p].hh.v.RH = q;
914       mem[q].hh.v.LH = end_match_token;
915       p = q;
916     }
917
918     if (cur_cmd == right_brace)
919     {
920       print_err("Missing { inserted");
921       incr(align_state);
922       help2("Where was the left brace? You said something like `\\def\\a}',",
923           "which I'm going to interpret as `\\def\\a{}'.");
924       error();
925       goto lab40;
926     }
927 lab30:;
928   }
929   else
930   {
931     scan_left_brace();
932   }
933
934   unbalance = 1;
935
936   while (true)
937   {
938     if (xpand)
939     {
940       while (true)
941       {
942         get_next();
943
944         if (cur_cmd <= max_command)
945           goto lab32;
946
947         if (cur_cmd != the)
948         {
949           expand();
950         }
951         else
952         {
953           q = the_toks();
954
955           if (link(temp_head) != 0)
956           {
957             link(p) = link(temp_head);
958             p = q;
959           }
960         }
961       }
962 lab32:
963       x_token();
964     }
965     else
966       get_token();
967
968     if (cur_tok < right_brace_limit)
969       if (cur_cmd < right_brace)
970         incr(unbalance);
971       else
972       {
973         decr(unbalance);
974
975         if (unbalance == 0)
976           goto lab40;
977       }
978     else if (cur_cmd == mac_param)
979       if (macrodef)
980       {
981         s = cur_tok;
982
983         if (xpand)
984           get_x_token();
985         else
986           get_token();
987
988         if (cur_cmd != mac_param)
989           if ((cur_tok <= zero_token) || (cur_tok > t))
990           {
991             print_err("Illegal parameter number in definition of ");
992             sprint_cs(warning_index);
993             help3("You meant to type ## instead of #, right?",
994                 "Or maybe a } was forgotten somewhere earlier, and things",
995                 "are all screwed up? I'm going to assume that you meant ##.");
996             back_error();
997             cur_tok = s;
998           }
999           else
1000             cur_tok = out_param_token - '0' + cur_chr;
1001       }
1002     {
1003       q = get_avail();
1004       mem[p].hh.v.RH = q;
1005       mem[q].hh.v.LH = cur_tok;
1006       p = q;
1007     }
1008   }
1009 lab40:
1010   scanner_status = 0;
1011
1012   if (hashbrace != 0)
1013   {
1014     q = get_avail();
1015     mem[p].hh.v.RH = q;
1016     mem[q].hh.v.LH = hashbrace;
1017     p = q;
1018   }
1019   Result = p;
1020   return Result;
1021 }
1022 /* used only in ITEX.C */
1023 /* sec 0482 */
1024 void read_toks_(integer n, halfword r)
1025 {
1026   halfword p;
1027   halfword q;
1028   integer s;
1029 /*  small_number m;  */
1030   int m; /* 95/Jan/7 */
1031
1032   scanner_status = defining;
1033   warning_index = r;
1034   def_ref = get_avail();
1035   token_ref_count(def_ref) = 0;
1036   p = def_ref;
1037
1038   {
1039     q = get_avail();
1040     mem[p].hh.v.RH = q;
1041     mem[q].hh.v.LH = end_match_token;
1042     p = q;
1043   }
1044
1045   if ((n < 0) || (n > 15))
1046     m = 16;
1047   else
1048     m = n;
1049
1050   s = align_state;
1051   align_state = 1000000L;
1052
1053   do
1054     {
1055       begin_file_reading();
1056       cur_input.name_field = m + 1;
1057
1058       if (read_open[m] == closed)
1059         if (interaction > nonstop_mode)
1060           if (n < 0)
1061           {
1062             print_string("");
1063             term_input("", 0);
1064           }
1065           else
1066           {
1067             print_ln();
1068             sprint_cs(r);
1069             {
1070               print_string("=");
1071               term_input("=", 0);
1072             }
1073             n = -1;
1074           }
1075         else
1076         {
1077           fatal_error("*** (cannot \\read from terminal in nonstop modes)");
1078           return;     // abort_flag set
1079         }
1080       else if (read_open[m] == 1)
1081         if (input_ln(read_file[m], false))
1082           read_open[m] = 0;
1083         else
1084         {
1085           (void) a_close(read_file[m]);
1086           read_open[m] = 2;
1087         }
1088       else
1089       {
1090         if (!input_ln(read_file[m], true))
1091         {
1092           (void) a_close(read_file[m]);
1093           read_open[m] = 2;
1094
1095           if (align_state != 1000000L)
1096           {
1097             runaway();
1098             print_err("File ended within ");
1099             print_esc("read");
1100             help1("This \\read has unbalanced braces.");
1101             align_state = 1000000L;
1102             error();
1103           }
1104         }
1105       }
1106
1107       cur_input.limit_field = last;
1108
1109       if ((end_line_char < 0) || (end_line_char > 255))
1110         decr(cur_input.limit_field);
1111       else
1112         buffer[cur_input.limit_field] = end_line_char;
1113
1114       first = cur_input.limit_field + 1;
1115       cur_input.loc_field = cur_input.start_field;
1116       cur_input.state_field = new_line;
1117
1118       while (true)
1119       {
1120         get_token();
1121
1122         if (cur_tok == 0)
1123           goto lab30;
1124
1125         if (align_state < 1000000L)
1126         {
1127           do
1128             {
1129               get_token();
1130             }
1131           while(!(cur_tok == 0));
1132
1133           align_state = 1000000L;
1134           goto lab30;
1135         }
1136
1137         {
1138           q = get_avail();
1139           mem[p].hh.v.RH = q;
1140           mem[q].hh.v.LH = cur_tok;
1141           p = q;
1142         }
1143       }
1144 lab30:
1145       end_file_reading();
1146     }
1147   while(!(align_state == 1000000L));
1148
1149   cur_val = def_ref;
1150   scanner_status = normal;
1151   align_state = s;
1152 }
1153 /* sec 0494 */
1154 void pass_text (void)
1155 {
1156   integer l;
1157   small_number savescannerstatus;
1158
1159   savescannerstatus = scanner_status;
1160   scanner_status = skipping;
1161   l = 0;
1162   skip_line = line;
1163
1164   while (true)
1165   {
1166     get_next();
1167
1168     if (cur_cmd == fi_or_else)
1169     {
1170       if (l == 0)
1171         goto lab30;
1172
1173       if (cur_chr == 2)
1174         decr(l);
1175     }
1176     else if (cur_cmd == if_test)
1177       incr(l);
1178   }
1179 lab30:
1180   scanner_status = savescannerstatus;
1181 }
1182 /* sec 0497 */
1183 void change_if_limit_(small_number l, halfword p)
1184 {
1185   halfword q;
1186
1187   if (p == cond_ptr)
1188     if_limit = l;
1189   else
1190   {
1191     q = cond_ptr;
1192
1193     while (true)
1194     {
1195       if (q == 0)
1196       {
1197         confusion("if");
1198         return;       // abort_flag set
1199       }
1200
1201       if (link(q) == p)
1202       {
1203         type(p) = l;
1204         return;
1205       }
1206
1207       q = link(q);
1208     }
1209   }
1210 }
1211 /* called from tex2.c */
1212 /* sec 0498 */
1213 void conditional (void)
1214 {
1215   bool b;
1216   char r;
1217   integer m, n;
1218   halfword p, q;
1219   small_number savescannerstatus;
1220   halfword savecondptr;
1221   small_number thisif;
1222
1223   {
1224     p = get_node(if_node_size);
1225     link(p) = cond_ptr;
1226     type(p) = if_limit;
1227     subtype(p) = cur_if;
1228     if_line_field(p) = if_line;
1229     cond_ptr = p;
1230     cur_if = cur_chr;
1231     if_limit = if_code;
1232     if_line = line;
1233   }
1234
1235   savecondptr = cond_ptr;
1236   thisif = cur_chr;
1237
1238   switch (thisif)
1239   {
1240     case if_char_code:
1241     case if_cat_code:
1242       {
1243         {
1244           get_x_token();
1245
1246           if (cur_cmd == relax)
1247             if (cur_chr == no_expand_flag)
1248             {
1249               cur_cmd = active_char;
1250               cur_chr = cur_tok - cs_token_flag - active_base;
1251             }
1252         }
1253
1254         if ((cur_cmd > active_char) || (cur_chr > 255))
1255         {
1256           m = relax;
1257           n = 256;
1258         }
1259         else
1260         {
1261           m = cur_cmd;
1262           n = cur_chr;
1263         }
1264         {
1265           get_x_token();
1266
1267           if (cur_cmd == relax)
1268             if (cur_chr == no_expand_flag)
1269             {
1270               cur_cmd = active_char;
1271               cur_chr = cur_tok - cs_token_flag - active_base;
1272             }
1273         }
1274
1275         if ((cur_cmd > active_char) || (cur_chr > 255))
1276         {
1277           cur_cmd = relax;
1278           cur_chr = 256;
1279         }
1280
1281         if (thisif == if_char_code)
1282           b = (n == cur_chr); 
1283         else
1284           b = (m == cur_cmd);
1285       }
1286       break;
1287
1288     case if_int_code:
1289     case if_dim_code:
1290       {
1291         if (thisif == if_int_code)
1292           scan_int();
1293         else
1294           scan_dimen(false, false, false);
1295
1296         n = cur_val;
1297         
1298         do
1299           {
1300             get_x_token();
1301           }
1302         while(!(cur_cmd != spacer));
1303
1304         if ((cur_tok >= other_token + '<') && (cur_tok <= other_token + '>'))
1305           r = cur_tok - other_token;
1306         else
1307         {
1308           print_err("Missing = inserted for ");
1309           print_cmd_chr(if_test, thisif);
1310           help1("I was expecting to see `<', `=', or `>'. Didn't.");
1311           back_error();
1312           r = '=';
1313         }
1314
1315         if (thisif == if_int_code)
1316           scan_int();
1317         else 
1318           scan_dimen(false, false, false);
1319
1320         switch (r)
1321         {
1322           case '<':
1323             b = (n < cur_val);
1324             break;
1325
1326           case '=':
1327             b = (n == cur_val);
1328             break;
1329
1330           case '>':
1331             b = (n > cur_val);
1332             break;
1333         }
1334       }
1335       break;
1336
1337     case if_odd_code:
1338       scan_int();
1339       b = odd(cur_val);
1340       break;
1341
1342     case if_vmode_code:
1343       b = (abs(mode) == 1);
1344       break;
1345
1346     case if_hmode_code:
1347       b = (abs(mode) == 102);
1348       break;
1349
1350     case if_mmode_code:
1351       b = (abs(mode) == 203);
1352       break;
1353
1354     case if_inner_code:
1355       b = (mode < 0);
1356       break;
1357
1358     case if_void_code:
1359     case if_hbox_code:
1360     case if_vbox_code:
1361       {
1362         scan_eight_bit_int();
1363         p = box(cur_val);
1364
1365         if (thisif == if_void_code)
1366           b = (p == 0);
1367         else if (p == 0)
1368           b = false;
1369         else if (thisif == if_hbox_code)
1370           b = (type(p) == hlist_node);
1371         else
1372           b = (type(p) == vlist_node);
1373       }
1374       break;
1375
1376     case ifx_code:
1377       {
1378         savescannerstatus = scanner_status;
1379         scanner_status = 0;
1380         get_next();
1381         n = cur_cs;
1382         p = cur_cmd;
1383         q = cur_chr;
1384         get_next();
1385
1386         if (cur_cmd != p)
1387           b = false;
1388         else if (cur_cmd < call)
1389           b = (cur_chr == q);
1390         else
1391         {
1392           p = link(cur_chr);
1393           q = link(equiv(n));
1394
1395           if (p == q)
1396             b = true;
1397           else
1398           {
1399             while ((p != 0) && (q != 0))
1400               if (info(p) != info(q))
1401                 p = 0;
1402               else
1403               {
1404                 p = link(p);
1405                 q = link(q);
1406               }
1407
1408             b = ((p == 0) && (q == 0));
1409           }
1410         }
1411
1412         scanner_status = savescannerstatus;
1413       }
1414       break;
1415
1416     case if_eof_code:
1417       {
1418         scan_four_bit_int();
1419         b = (read_open[cur_val] == closed);
1420       }
1421       break;
1422
1423     case if_true_code:
1424       b = true;
1425       break;
1426
1427     case if_false_code:
1428       b = false;
1429       break;
1430
1431     case if_case_code:
1432       {
1433         scan_int();
1434         n = cur_val;
1435
1436         if (tracing_commands > 1)
1437         {
1438           begin_diagnostic();
1439           print_string("{case ");
1440           print_int(n); 
1441           print_char('}');
1442           end_diagnostic(false);
1443         }
1444
1445         while (n != 0)
1446         {
1447           pass_text();
1448
1449           if (cond_ptr == savecondptr)
1450             if (cur_chr == or_code)
1451               decr(n);
1452             else 
1453               goto lab50;
1454           else if (cur_chr == fi_code)
1455           {
1456             p = cond_ptr;
1457             if_line = if_line_field(p);
1458             cur_if = subtype(p);
1459             if_limit = type(p);
1460             cond_ptr = link(p);
1461             free_node(p, if_node_size);
1462           }
1463         }
1464
1465         change_if_limit(or_code, savecondptr);
1466         return;
1467       }
1468       break;
1469   }
1470
1471   if (tracing_commands > 1)
1472   {
1473     begin_diagnostic();
1474
1475     if (b)
1476       print_string("{true}");
1477     else
1478       print_string("{false}");
1479
1480     end_diagnostic(false);
1481   }
1482
1483   if (b)     /* b may be used without ... */
1484   {
1485     change_if_limit(else_code, savecondptr);
1486     return;
1487   }
1488
1489   while (true)
1490   {
1491     pass_text();
1492
1493     if (cond_ptr == savecondptr)
1494     {
1495       if (cur_chr != or_code)
1496         goto lab50;
1497
1498       print_err("Extra ");
1499       print_esc("or");
1500       help1("I'm ignoring this; it doesn't match any \\if.");
1501       error();
1502     }
1503     else if (cur_chr == fi_code)
1504     {
1505       p = cond_ptr;
1506       if_line = if_line_field(p);
1507       cur_if = subtype(p);
1508       if_limit = type(p);
1509       cond_ptr = link(p);
1510       free_node(p, if_node_size);
1511     }
1512   }
1513
1514 lab50:
1515   if (cur_chr == fi_code)
1516   {
1517     p = cond_ptr;
1518     if_line = if_line_field(p);
1519     cur_if = subtype(p);
1520     if_limit = type(p);
1521     cond_ptr = link(p);
1522     free_node(p, if_node_size);
1523   }
1524   else
1525     if_limit = fi_code;
1526 }
1527 /* sec 0515 */
1528 void begin_name (void)
1529 {
1530   area_delimiter = 0; /* index between `file area' and `file name' */
1531   ext_delimiter = 0;  /* index between `file name' and `file extension' */
1532 }
1533 /* This gathers up a file name and makes a string of it */
1534 /* Also tries to break it into `file area' `file name' and `file extension' */
1535 /* Used by scan_file_name and prompt_file_name */
1536 /* We assume tilde has been converted to pseudo_tilde and space to pseudo_space */
1537 /* returns false if it is given a space character - end of file name */
1538 /* sec 0516 */
1539 bool more_name_(ASCII_code c)
1540 {
1541   if (quoted_file_name == 0 && c == ' ')
1542     return false;
1543   else if (quoted_file_name != 0 && c == '"')
1544   {
1545     quoted_file_name = 0; /* catch next space character */
1546     return true;    /* accept ending quote, but throw away */
1547   }
1548   else
1549   {
1550 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1551 /*  convert pseudo tilde back to '~' 95/Sep/26 */ /* moved here 97/June/5 */
1552 /*  if (pseudo_tilde != 0 && c == pseudo_tilde) c = '~'; */
1553 /*  convert pseudo space back to ' ' 97/June/5 */ /* moved here 97/June/5 */
1554 /*  if (pseudo_space != 0 && c == pseudo_space) c = ' '; */
1555 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */      
1556     str_room(1);
1557     append_char(c);
1558 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1559 //  if ((c == 47))   /* / */
1560 //  for DOS/Windows
1561     if ((c == '/' || c == '\\' || c == ':')) /* 94/Mar/1 */
1562 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1563     {
1564       area_delimiter = cur_length;
1565       ext_delimiter = 0;
1566     } 
1567     else if (c == '.')
1568       ext_delimiter = cur_length;
1569     return true;
1570   }
1571 }
1572 /******************************** 2000 August 15th start ***********************/
1573
1574 // The following code is to save string space used by TeX for filenames
1575 // Not really critical in a system that has dynamic memory allocation
1576 // And may slow it down slightly - although this linear search only
1577 // occurs when opening a file, which is somewhat slow inany case...
1578
1579 // see if string from str_pool[start] to str_pool[end]
1580 // occurs elsewhere in string pool - returns string number
1581 // returns -1 if not found in string pool 2000 Aug 15
1582
1583 int find_string (int start, int end)
1584 {
1585   int k, nlen = end - start;
1586   char *s;
1587
1588 //  int trace_flag = 1;     // debugging only
1589
1590   if (trace_flag)
1591   {
1592     sprintf(log_line, "\nLOOKING for string (str_ptr %d nlen %d) ", str_ptr, end - start);
1593     s = log_line + strlen(log_line);
1594     strncpy(s, (const char *) str_pool + start, nlen);
1595     strcpy(s + nlen, "");
1596     show_line(log_line, 0);
1597   }
1598
1599 //  avoid problems with(cur_name == flushablestring)by going only up to str_ptr-1
1600 //  code in new_font (tex8.c) will take care of reuse of font name already
1601   for (k = 0; k < str_ptr - 1; k++)
1602   {
1603     if (length(k) != nlen)
1604       continue;
1605
1606     if (strncmp((const char *) str_pool + start, (const char *) str_pool + str_start[k], nlen) == 0)
1607     {
1608       if (trace_flag)
1609       {
1610         sprintf(log_line, "\nFOUND the string %d (%d) ", k, str_start[k+1]-str_start[k]);
1611         s = log_line + strlen(log_line);
1612         strncpy(s, (const char *)str_pool + start, nlen);
1613         strcpy(s+nlen, "\n");
1614         show_line(log_line, 0);
1615       }
1616       return k;     // return number of matching string
1617     }
1618   }
1619
1620   if (trace_flag)
1621   {
1622     sprintf(log_line, "\nNOT FOUND string ");
1623     s = log_line + strlen(log_line);
1624     strncpy(s, (const char*)str_pool + start, nlen);
1625     strcpy(s + nlen, "\n");
1626     show_line(log_line, 0);
1627   }
1628
1629   return -1;          // no match found
1630 }
1631
1632 // snip out the string from str_pool[start] to str_pool[end]
1633 // and move everything above it down 2000 Aug 15
1634
1635 void remove_string (int start, int end)
1636 {
1637   int nlen = pool_ptr - end;  // how many bytes to move down
1638   char *s;
1639   
1640 //  int trace_flag=1;   // debugging only
1641 //  if (end < start) show_line("\nEND < START", 1);
1642 //  if (pool_ptr < end) show_line("\nPOOLPTR < END", 1);
1643
1644   if (trace_flag)
1645   {
1646     int n = end - start;
1647     sprintf(log_line, "\nSTRIPPING OUT %d %d ", n, nlen);
1648     s = log_line + strlen(log_line);
1649     strncpy(s, (const char *)str_pool + start, n);
1650     strcpy(s + n, "\n");
1651     show_line(log_line, 0);
1652   }
1653
1654   if (nlen > 0)
1655     memcpy(str_pool + start, str_pool + end, nlen);
1656
1657   pool_ptr = start + nlen;    // poolprt - (end-start);
1658 }
1659
1660 void show_string (int k)
1661 {
1662   int nlen = length(k);
1663   char *s;
1664   
1665   sprintf(log_line, "\nSTRING %5d (%3d) %5d--%5d ",
1666       k, nlen, str_start[k], str_start[k+1]);
1667   s = log_line + strlen(log_line);      
1668   strncpy(s, (const char *)str_pool + str_start[k], nlen);
1669   strcpy(s + nlen, "");
1670   show_line(log_line, 0);
1671 }
1672
1673 void show_all_strings (void)
1674 {
1675   int k;
1676
1677   for (k = 0; k < str_ptr; k++)
1678     show_string(k);
1679 }
1680
1681 // int notfirst=0;    // debugging only
1682
1683 /********************************** 2000 August 15 end ****************************/
1684 /* sec 0517 */
1685 void end_name (void) 
1686 {
1687 #ifdef ALLOCATESTRING
1688   if (str_ptr + 3 > current_max_strings)
1689     str_start = realloc_str_start(increment_max_strings + 3);
1690
1691   if (str_ptr + 3 > current_max_strings)
1692   {
1693     overflow("number of strings", current_max_strings - init_str_ptr);  /* 97/Mar/7 */
1694     return;     // abort_flag set
1695   }
1696 #else
1697   if (str_ptr + 3 > max_strings)
1698   {
1699     overflow("number of strings", max_strings - init_str_ptr); /* number of strings */
1700     return;     // abort_flag set
1701   }
1702 #endif
1703
1704 //  if (notfirst++ == 0) show_all_strings();  // debugging only
1705   
1706   if (area_delimiter == 0)   // no area delimiter ':' '/' or '\' found
1707     cur_area = 335;     // "" default area 
1708   else
1709   {
1710     if (save_strings_flag && (cur_area = find_string(str_start[str_ptr], str_start[str_ptr] + area_delimiter)) > 0)
1711     {
1712       remove_string(str_start[str_ptr], str_start[str_ptr] + area_delimiter);
1713       area_delimiter = 0; // area_delimiter - area_delimiter;
1714
1715       if (ext_delimiter != 0)
1716         ext_delimiter = ext_delimiter - area_delimiter;
1717
1718 //      str_start[str_ptr + 1]= str_start[str_ptr]+ area_delimiter; // test only
1719 //      incr(str_ptr);    // test only
1720     }
1721     else         // carve out string for "cur_area"
1722     {
1723       cur_area = str_ptr; 
1724       str_start[str_ptr + 1] = str_start[str_ptr] + area_delimiter; 
1725       incr(str_ptr);
1726     }
1727   }
1728
1729   if (ext_delimiter == 0) // no extension delimiter '.' found
1730   {
1731     cur_ext = 335;        // "" default extension 
1732
1733     if (save_strings_flag && (cur_name = find_string(str_start[str_ptr], pool_ptr)) > 0)
1734     {
1735       remove_string(str_start[str_ptr], pool_ptr);
1736 //    (void) make_string();  // test only
1737     }
1738     else            // Make string from str_start[str_ptr]to pool_ptr
1739       cur_name = make_string();
1740   } 
1741   else            // did find an extension
1742   {
1743     if (save_strings_flag &&
1744       (cur_name = find_string(str_start[str_ptr], str_start[str_ptr] + ext_delimiter - area_delimiter-1)) > 0)
1745     {
1746       remove_string(str_start[str_ptr], str_start[str_ptr] + ext_delimiter - area_delimiter - 1);
1747 //    str_start[str_ptr + 1]= str_start[str_ptr]+ ext_delimiter - area_delimiter - 1;   // test only
1748 //    incr(str_ptr);    // test only
1749     }
1750     else             // carve out string for "cur_name"
1751     {
1752       cur_name = str_ptr;
1753       str_start[str_ptr + 1]= str_start[str_ptr]+ ext_delimiter - area_delimiter - 1;
1754       incr(str_ptr);
1755     }
1756
1757     if (save_strings_flag && (cur_ext = find_string(str_start[str_ptr], pool_ptr)) > 0)
1758     {
1759       remove_string(str_start[str_ptr], pool_ptr);
1760 //    (void) make_string();  // test only
1761     }
1762     else            // Make string from str_start[str_ptr]to pool_ptr
1763       cur_ext = make_string();
1764   }
1765 }
1766
1767 /* n current name, a current area, e current extension */
1768 /* result in name_of_file[] */
1769 /* sec 0519 */
1770 void pack_file_name_(str_number n, str_number a, str_number e)
1771 {
1772   integer k;
1773   ASCII_code c;
1774   pool_pointer j;
1775
1776   k = 0;
1777
1778   for (j = str_start[a]; j <= str_start[a + 1] - 1; j++)
1779   {
1780     c = str_pool[j];
1781     incr(k);
1782
1783     if (k <= PATHMAX)
1784       name_of_file[k] = xchr[c];
1785   }
1786
1787   for (j = str_start[n]; j <= str_start[n + 1] - 1; j++)
1788   {
1789     c = str_pool[j];
1790     incr(k);
1791
1792     if (k <= PATHMAX)
1793       name_of_file[k] = xchr[c];
1794   }
1795
1796   for (j = str_start[e]; j <= str_start[e + 1] - 1; j++)
1797   {
1798     c = str_pool[j];
1799     incr(k);
1800
1801     if (k <= PATHMAX)
1802       name_of_file[k] = xchr[c];
1803   }
1804
1805   if (k < PATHMAX)
1806     name_length = k;
1807   else
1808     name_length = PATHMAX - 1;
1809
1810 /*  pad it out with spaces ... what for ? in case we modify and forget  ? */
1811   for (k = name_length + 1; k <= PATHMAX; k++)
1812     name_of_file[k] = ' ';
1813
1814   name_of_file[PATHMAX] = '\0';    /* paranoia 94/Mar/24 */
1815
1816   {
1817     name_of_file [name_length+1] = '\0';
1818
1819     if (trace_flag)
1820     {
1821       sprintf(log_line, " pack_file_name `%s' (%d) ", name_of_file + 1, name_length); /* debugging */
1822       show_line(log_line, 0);
1823     }
1824
1825     name_of_file [name_length + 1] = ' ';
1826   }
1827 }
1828 /* Called only from two places tex9.c for format name - specified and default */
1829 /* for specified format name args are 0, a, b name in buffer[a] --- buffer[b] */
1830 /* for default args are format_default_length-4, 1, 0 */
1831 /* sec 0523 */
1832 void pack_buffered_name_(small_number n, integer a, integer b)
1833 {
1834   integer k;
1835   ASCII_code c;
1836   integer j;
1837
1838   if (n + b - a + 5 > PATHMAX)
1839     b = a + PATHMAX - n - 5;
1840
1841   k = 0;
1842
1843 /*  This loop kicks in when we want the default format name */
1844   for (j = 1; j <= n; j++)
1845   {
1846     c = xord[TEX_format_default[j]];
1847     incr(k);
1848
1849     if (k <= PATHMAX)
1850       name_of_file[k] = xchr[c];
1851   }
1852 /*  This loop kicks in when we want a specififed format name */
1853   for (j = a; j <= b; j++)
1854   {
1855     c = buffer[j];
1856     incr(k);
1857
1858     if (k <= PATHMAX)
1859       name_of_file[k] = xchr[c];
1860   }
1861
1862 /*  This adds the extension from the default format name */
1863   for (j = format_default_length - 3; j <= format_default_length; j++)
1864   {
1865     c = xord[TEX_format_default[j]];
1866     incr(k);
1867
1868     if (k <= PATHMAX)
1869       name_of_file[k] = xchr[c];
1870   }
1871
1872   if (k < PATHMAX)
1873     name_length = k;
1874   else
1875     name_length = PATHMAX - 1;
1876
1877  /*  pad it out with spaces ... what for ? */
1878   for (k = name_length + 1; k <= PATHMAX; k++)
1879     name_of_file[k]= ' ';
1880
1881   name_of_file[PATHMAX] = '\0';    /* paranoia 94/Mar/24 */
1882 }
1883 /* sec 0525 */
1884 str_number make_name_string (void)
1885 {
1886   integer k;
1887
1888 #ifdef ALLOCATESTRING
1889   if (pool_ptr + name_length > current_pool_size)
1890     str_pool = realloc_str_pool(increment_pool_size + name_length);
1891
1892   if (str_ptr == current_max_strings)
1893     str_start = realloc_str_start(increment_max_strings);
1894
1895   if ((pool_ptr + name_length > current_pool_size) || (str_ptr == current_max_strings) || (cur_length > 0))
1896 #else
1897   if ((pool_ptr + name_length > pool_size) || (str_ptr == max_strings) || (cur_length > 0))
1898 #endif
1899   {
1900     return '?';
1901   }
1902   else
1903   {
1904     for (k = 1; k <= name_length; k++)
1905       append_char(xord[name_of_file[k]]);
1906
1907     return make_string();
1908   }
1909 }
1910 /* sec 0525 */
1911 str_number a_make_name_string_(alpha_file * f)
1912 {
1913   return make_name_string();
1914 }
1915 /* sec 0525 */
1916 str_number b_make_name_string_(byte_file * f)
1917 {
1918   return make_name_string(); 
1919 }
1920 /* sec 0525 */
1921 str_number w_make_name_string_(word_file * f)
1922 {
1923   return make_name_string();
1924 }
1925
1926 /* Used by start_input to scan file name on command line */
1927 /* Also in tex8.c new_font_, open_or_close_in, and do_extension */
1928 /* sec 0526 */
1929 void scan_file_name (void)
1930 {
1931   name_in_progress = true;
1932   begin_name();
1933
1934   do
1935     {
1936       get_x_token(); 
1937     }
1938   while (!(cur_cmd != spacer));
1939
1940   quoted_file_name = 0;         /* 98/March/15 */
1941
1942   if (allow_quoted_names) /* check whether quoted name */
1943   {
1944     if (cur_chr == '"')
1945     {
1946       quoted_file_name = 1;
1947       get_x_token();
1948     }
1949   }
1950
1951   while (true)
1952   {
1953     if ((cur_cmd > other_char) || (cur_chr > 255)) 
1954     {
1955       back_input(); /* not a character put it back and leave */
1956       goto lab30; 
1957     } 
1958 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1959 /*  convert tilde '~' to pseudo tilde */
1960 /*  if (pseudo_tilde != 0 && cur_chr == '~') cur_chr = pseudo_tilde; */
1961 /*  convert space ' ' to pseudo space */
1962 /*  if (pseudo_space != 0 && cur_chr == ' ') cur_chr = pseudo_space; */
1963 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1964     if (!more_name(cur_chr))    /* up to next white space */
1965       goto lab30;
1966
1967     get_x_token();
1968   }
1969 lab30:
1970   end_name();
1971   name_in_progress = false;
1972 }
1973 /* argument is string .fmt, .log, or .dvi */
1974 /* sec 0529 */
1975 void pack_job_name_(str_number s)
1976 {
1977   cur_area = 335;       /* "" */
1978   cur_ext  = s;
1979   cur_name = job_name;
1980   pack_file_name(cur_name, cur_area, cur_ext);
1981 }
1982
1983 /**********************************************************************/
1984 /* show TEXINPUTS=... or format specific  */
1985 /* only show this if name was not fully qualified ? */
1986 void show_tex_inputs (void)
1987 {
1988   char *s, *t, *v;
1989
1990   s = "TEXINPUTS";        /* default */
1991
1992   if (format_specific)
1993   {
1994     s = format_name;                /* try specific */
1995
1996     if (grabenv(s) == NULL)
1997       s = "TEXINPUTS";  /* no format specific */
1998   }
1999
2000   if (grabenv(s) == NULL)
2001     s = "TEXINPUT";     /* 94/May/19 */
2002
2003   print_nl("  ");
2004   print_char(' ');
2005   print_char('(');
2006   t = s;
2007
2008   while (*t > '\0')
2009     print_char(*t++);
2010
2011   print_char('=');
2012   v = grabenv(s);
2013
2014   if (v != NULL)
2015   {
2016     t = v;
2017
2018     while (*t > '\0')
2019       print_char(*t++);
2020   }
2021
2022   print_char(')');
2023 }
2024
2025 /**********************************************************************/
2026 /* sec 0530 */
2027 /*  s - what can't be found, e - default */
2028 void prompt_file_name_(char * s, str_number e) 
2029 {
2030   integer k;
2031
2032   if (interaction == scroll_mode);
2033
2034   if (!strcmp("input file name", s))
2035     print_err("I can't find file `");
2036   else
2037     print_err("I can't write on file `");
2038
2039   print_file_name(cur_name, cur_area, cur_ext);
2040   print_string("'.");
2041
2042   if (!strcmp("input file name", s))
2043   {
2044     if (cur_area == 335) /* "" only if path not specified */
2045     {
2046       if (show_texinput_flag)
2047         show_tex_inputs();
2048     }
2049   }
2050
2051   if (e == 785)    /* .tex */
2052     show_context();
2053
2054   print_nl("Please type another ");
2055   print_string(s); 
2056
2057   if (interaction < 2)
2058   {
2059     fatal_error("*** (job aborted, file error in nonstop mode)");
2060     return;     // abort_flag set
2061   }
2062
2063   if (!knuth_flag)
2064 #ifdef _WINDOWS
2065     show_line(" (or ^z to exit)", 0);
2066 #else
2067     show_line(" (or Ctrl-Z to exit)", 0);
2068 #endif
2069   {
2070     print_string(": ");
2071     term_input(": ", 0);
2072   }
2073 /*  should we deal with tilde and space in file name here ??? */
2074   {
2075     begin_name();
2076     k = first;
2077
2078     while ((buffer[k] == ' ') && (k < last))
2079       incr(k);
2080 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2081     quoted_file_name = 0;         /* 98/March/15 */
2082
2083     if (allow_quoted_names && k < last) /* check whether quoted name */
2084     {
2085       if (buffer[k]== '"')
2086       {
2087         quoted_file_name = 1;
2088         incr(k);
2089       }
2090     }
2091
2092     while (true)
2093     {
2094       if (k == last)
2095         goto lab30;
2096 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2097 /*  convert tilde '~' to pseudo tilde */
2098       if (pseudo_tilde != 0 && buffer[k]== '~')
2099         buffer[k] = pseudo_tilde;
2100 /*  convert space ' ' to pseudo space */
2101       if (pseudo_space != 0 && buffer[k]== ' ')
2102         buffer[k] = pseudo_space;
2103 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2104       if (!more_name(buffer[k]))
2105         goto lab30;
2106
2107       incr(k);
2108     }
2109 lab30:
2110     end_name();
2111   }
2112
2113   if (cur_ext == 335)    /* "" */
2114     cur_ext = e;      /* use default extension */
2115
2116   pack_file_name(cur_name, cur_area, cur_ext);
2117 }
2118 /* sec 0534 */
2119 void open_log_file (void)
2120 {
2121   char old_setting;
2122   integer k;
2123   integer l;
2124   char * months;
2125
2126   old_setting = selector;
2127
2128   if (job_name == 0)
2129     job_name = 790;   /* default:  texput */
2130
2131   pack_job_name(".log");
2132
2133   while (!a_open_out(log_file))
2134   {
2135     selector = term_only;
2136     prompt_file_name("transcript file name", ".log");
2137   }
2138
2139   texmf_log_name = a_make_name_string(log_file);
2140   selector = log_only;
2141   log_opened = true;
2142
2143   {
2144 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2145   if (want_version)
2146   {
2147     stamp_it(log_line);         // ??? use log_line ???
2148     strcat(log_line, "\n");
2149     (void) fputs(log_line, log_file);
2150     stampcopy(log_line);
2151     strcat(log_line, "\n");
2152     (void) fputs(log_line, log_file);
2153   }
2154 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2155 /*  also change following in itex.c - bkph */
2156   (void) fputs(tex_version, log_file); 
2157   (void) fprintf(log_file, " (%s %s)", application, yandyversion);
2158
2159   if (format_ident > 0)
2160     slow_print(format_ident);     /* bkph */
2161
2162   print_string("  ");
2163 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2164   if (civilize_flag)
2165     print_int(year);
2166   else
2167     print_int(day);
2168 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2169     print_char(' ');
2170     months = " JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
2171
2172     for (k = 3 * month - 2; k <= 3 * month; k++)
2173       (void) putc(months[k],  log_file);
2174
2175     print_char(' ');
2176 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2177     if (civilize_flag)
2178       print_int(day);
2179     else
2180       print_int(year);
2181 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2182     print_char(' ');
2183     print_two(tex_time / 60);  /* hour */
2184     print_char(':');
2185     print_two(tex_time % 60);  /* minute */
2186   }
2187
2188   input_stack[input_ptr] = cur_input;
2189   print_nl("**");
2190   l = input_stack[0].limit_field;
2191
2192   if (buffer[l] == end_line_char)
2193     decr(l);
2194
2195   for (k = 1; k <= l; k++)
2196     print(buffer[k]);
2197
2198   print_ln(); 
2199 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2200 /* a good place to show the fmt file name or pool file name ? 94/June/21 */
2201   if (show_fmt_flag)
2202   {
2203     if (string_file != NULL)
2204     {
2205       fprintf(log_file, "(%s)\n", string_file);
2206       free(string_file);  /* this was allocated by strdup in openinou */
2207       string_file = NULL;   /* for safety */
2208     }
2209
2210     if (format_file != NULL)
2211     {
2212       fprintf(log_file, "(%s)\n", format_file);
2213       free(format_file);  /* this was allocated by strdup in openinou */
2214       format_file = NULL;   /* for safety */
2215     }
2216   }
2217 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2218   selector = old_setting + 2;
2219 }
2220
2221 /**************************** start of insertion 98/Feb/7 **************/
2222
2223 // Attempt to deal with foo.bar.tex given as foo.bar on command line
2224 // Makes copy of job_name with extension
2225
2226 void morenamecopy(ASCII_code c)
2227 {
2228 #ifdef ALLOCATESTRING
2229   if (pool_ptr + 1 > current_pool_size)
2230     str_pool = realloc_str_pool (increment_pool_size);
2231
2232   if (pool_ptr + 1 > current_pool_size) /* in case it failed 94/Jan/24 */
2233   {
2234     overflow("pool size", current_pool_size - init_pool_ptr); /* 97/Mar/7 */
2235     return;     // abort_flag set
2236   }
2237 #else
2238   if (pool_ptr + 1 > pool_size)
2239   {
2240     overflow("pool size", pool_size - init_pool_ptr); /* pool size */
2241     return;     // abort_flag set
2242   }
2243 #endif
2244   str_pool[pool_ptr] = c; 
2245   incr(pool_ptr);
2246 }
2247
2248 int endnamecopy(void)
2249 {
2250 #ifdef ALLOCATESTRING
2251     if (str_ptr + 1 > current_max_strings)
2252       str_start = realloc_str_start(increment_max_strings + 1);
2253
2254     if (str_ptr + 1 > current_max_strings) /* in case it failed 94/Jan/24 */
2255     {
2256       overflow("number of strings", current_max_strings - init_str_ptr);  /* 97/Mar/7 */
2257       return 0;     // abort_flag set
2258     }
2259 #else
2260     if (str_ptr + 1 > max_strings)
2261     {
2262       overflow("number of strings", max_strings - init_str_ptr); /* number of strings */
2263       return 0;     // abort_flag set
2264     }
2265 #endif
2266     return make_string();
2267 }
2268
2269 /* add extension to job_name */
2270 void jobnameappend (void)
2271
2272   int k, n;
2273 /*  copy job_name */
2274   k = str_start[job_name];
2275   n = str_start[job_name + 1];
2276
2277   while (k < n)
2278     morenamecopy(str_pool[k++]);
2279 /*  copy `extension' */
2280   k = str_start[cur_ext];
2281   n = str_start[cur_ext + 1];
2282
2283   while (k < n)
2284     morenamecopy(str_pool[k++]);
2285
2286   job_name = endnamecopy();
2287 }
2288
2289 /**************************** end of insertion 98/Feb/7 **************/
2290 /* sec 0537 */
2291 void start_input (void)
2292 {
2293   bool addedextension = false;
2294
2295   scan_file_name();
2296   pack_file_name(cur_name, cur_area, cur_ext); 
2297
2298   while (true)        /* loop until we get a valid file name */
2299   {
2300     addedextension = false;
2301     begin_file_reading(); 
2302 /* *** *** *** *** *** following is new in 3.14159 *** *** *** *** *** *** */
2303 /*  if current extension is *not* empty, try to open using name as is */
2304 /*  string 335 is "" the empty string */
2305 /*  should be updated to current Kpathsea. */
2306     if ((cur_ext != 335) && a_open_in(input_file[cur_input.index_field], TEXINPUTPATH))
2307       goto lab30;
2308 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2309 /*  we get here if extension is "", or file with extension failed to open */
2310 /*  if current extension is not `tex,' and `tex' is not irrelevant, try it */
2311 /*  string 785 is .tex */
2312     if ((cur_ext != 785) && (name_length + 5 < PATHMAX))
2313     {
2314       //strcpy(name_of_file + name_length + 1, ".tex ");
2315       name_of_file[name_length + 1] = '.';
2316       name_of_file[name_length + 2] = 't';
2317       name_of_file[name_length + 3] = 'e';
2318       name_of_file[name_length + 4] = 'x';
2319       name_of_file[name_length + 5] = ' ';
2320       name_length = name_length + 4;
2321
2322       addedextension = true;
2323
2324       if (a_open_in(input_file[cur_input.index_field], TEXINPUTPATH))
2325         goto lab30;
2326
2327       name_length = name_length - 4;      /* strip extension again */
2328       name_of_file[name_length + 1] = ' ';  /* ' ' */
2329       addedextension = false;
2330 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2331     }
2332 /* *** *** *** *** major changes here in 3.14159 *** *** *** *** *** *** */
2333 /*  string 335 is "" the empty string */
2334     if ((cur_ext == 335) && a_open_in(input_file[cur_input.index_field], TEXINPUTPATH))
2335       goto lab30;
2336
2337 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2338     end_file_reading();
2339     prompt_file_name("input file name", ".tex");
2340   }   /* end of while(true)trying to get valid file name */
2341
2342 /* maybe set  pseudo_tilde = 0  at this point ? 95/Sep/26 */
2343 lab30: 
2344   cur_input.name_field = a_make_name_string(input_file[cur_input.index_field]);
2345
2346   if (job_name == 0)       /* only the first time */
2347   {
2348     job_name = cur_name;        /* here we set the job_name */
2349 /*  did file name have an `extension' already and we added ".tex" ? */
2350     if (cur_ext != 335 && addedextension)     /* 98/Feb/7 */
2351       jobnameappend();   /* append `extension' to job_name */
2352
2353     open_log_file();
2354   }
2355
2356   if (term_offset + length(cur_input.name_field) > max_print_line - 2) /* was 3 ? */
2357     print_ln();
2358   else if ((term_offset > 0) || (file_offset > 0))
2359     print_char(' ');
2360
2361   print_char('(');
2362 //  print_char('@');       // debugging only marker
2363   incr(open_parens);
2364
2365   if (open_parens > max_open_parens)
2366     max_open_parens = open_parens;    /* 1999/Jan/17 */
2367
2368   slow_print(cur_input.name_field);
2369 //  print_char('@');       // debugging only marker
2370 #ifndef _WINDOWS
2371   fflush(stdout);
2372 #endif
2373   cur_input.state_field = new_line;
2374
2375   {
2376     line = 1;
2377
2378     if (input_ln(input_file[cur_input.index_field], false));
2379
2380     firm_up_the_line();
2381
2382     if ((end_line_char < 0) || (end_line_char > 255))
2383       decr(cur_input.limit_field);
2384     else
2385       buffer[cur_input.limit_field] = end_line_char;
2386
2387     first = cur_input.limit_field + 1;
2388     cur_input.loc_field = cur_input.start_field;
2389   }
2390 }
2391
2392 /**********************************************************************/
2393 /* show TEXFONTS=... or format specific  */
2394 /* only show this if name was not fully qualified ? */
2395 void show_tex_fonts (void)
2396 {     /* 98/Jan/28 */
2397   char *s, *t, *v, *u;
2398   int n;
2399
2400   s = "TEXFONTS";
2401
2402   if (encoding_specific)
2403   {
2404     u = encoding_name;                /* try specific */
2405
2406     if ((t = grabenv(u)) != NULL)
2407     {
2408       if (strchr(t, ':') != NULL && sscanf(t, "%d", &n) == 0)
2409       {
2410         s = u;        /* look here instead of TEXFONTS=... */
2411       }
2412     }
2413   }
2414
2415   print_nl("  ");
2416   print_char(' ');
2417   print_char('(');
2418   t = s;
2419
2420   while (*t > '\0')
2421     print_char(*t++);
2422
2423   print_char('=');
2424   v = grabenv(s);
2425
2426   if (v != NULL)
2427   {
2428     t = v;
2429
2430     while (*t > '\0')
2431       print_char(*t++);
2432   }
2433
2434   print_char(')');
2435 }
2436
2437 /**********************************************************************/
2438
2439 /* called only from tex8.c */
2440 /* sec 0560 */
2441 internal_font_number read_font_info_(halfword u, str_number nom, str_number aire, scaled s)
2442 {
2443   font_index k;
2444   bool fileopened;
2445 /*  halfword lf, lh, bc, ec, nw, nh, nd, ni, nl, nk, ne, np;  */
2446   halfword lf, lh, nw, nh, nd, ni, nl, nk, ne, np;
2447 /*  halfword bc, ec; */
2448   int bc, ec;             /* 95/Jan/7 */
2449   internal_font_number f;
2450   internal_font_number g;
2451   eight_bits a, b, c, d;
2452   ffourquarters qw;
2453   scaled sw;
2454   integer bchlabel;
2455   short bchar;
2456   scaled z;
2457   integer alpha;
2458   char beta;
2459
2460   g = 0;
2461   fileopened = false;
2462   pack_file_name(nom, aire, 805); /* .tfm */
2463
2464   if (!b_open_in(tfm_file)) /* new in C version d */
2465   {
2466     goto lab11;
2467   } 
2468 /*   was just: goto lab11; */
2469   fileopened = true; 
2470   {
2471 /*  tfm_temp = getc(tfm_file);  */ /* done already in open_input, but why? */
2472     //tfm_temp = getc(tfm_file);
2473     {
2474       lf = tfm_temp;
2475       if (lf > 127)
2476         goto lab11;
2477       tfm_temp = getc(tfm_file);
2478       lf = lf * 256 + tfm_temp;
2479     }
2480     tfm_temp = getc(tfm_file);
2481     {
2482       lh = tfm_temp;
2483       if (lh > 127)
2484         goto lab11;
2485       tfm_temp = getc(tfm_file);
2486       lh = lh * 256 + tfm_temp;
2487     }
2488     tfm_temp = getc(tfm_file);
2489     {
2490       bc = tfm_temp;
2491       if (bc > 127)
2492         goto lab11;
2493       tfm_temp = getc(tfm_file);
2494       bc = bc * 256 + tfm_temp;
2495     }
2496     tfm_temp = getc(tfm_file);
2497     {
2498       ec = tfm_temp;
2499       if (ec > 127)
2500         goto lab11;
2501       tfm_temp = getc(tfm_file);
2502       ec = ec * 256 + tfm_temp;
2503     }
2504     if ((bc > ec + 1)||(ec > 255))
2505       goto lab11;
2506     if (bc > 255)
2507     {
2508       bc = 1;
2509       ec = 0;
2510     }
2511     tfm_temp = getc(tfm_file);
2512     {
2513       nw = tfm_temp;
2514       if (nw > 127)
2515         goto lab11;
2516       tfm_temp = getc(tfm_file);
2517       nw = nw * 256 + tfm_temp;
2518     }
2519     tfm_temp = getc(tfm_file);
2520     {
2521       nh = tfm_temp;
2522       if (nh > 127)
2523         goto lab11;
2524       tfm_temp = getc(tfm_file);
2525       nh = nh * 256 + tfm_temp;
2526     }
2527     tfm_temp = getc(tfm_file);
2528     {
2529       nd = tfm_temp;
2530       if (nd > 127)
2531         goto lab11;
2532       tfm_temp = getc(tfm_file);
2533       nd = nd * 256 + tfm_temp;
2534     }
2535     tfm_temp = getc(tfm_file);
2536     {
2537       ni = tfm_temp;
2538       if (ni > 127)
2539         goto lab11;
2540       tfm_temp = getc(tfm_file);
2541       ni = ni * 256 + tfm_temp;
2542     }
2543     tfm_temp = getc(tfm_file);
2544     {
2545       nl = tfm_temp;
2546       if (nl > 127)
2547         goto lab11;
2548       tfm_temp = getc(tfm_file);
2549       nl = nl * 256 + tfm_temp;
2550     }
2551     tfm_temp = getc(tfm_file);
2552     {
2553       nk = tfm_temp;
2554       if (nk > 127)
2555         goto lab11;
2556       tfm_temp = getc(tfm_file);
2557       nk = nk * 256 + tfm_temp;
2558     }
2559     tfm_temp = getc(tfm_file);
2560     {
2561       ne = tfm_temp;
2562       if (ne > 127)
2563         goto lab11;
2564       tfm_temp = getc(tfm_file);
2565       ne = ne * 256 + tfm_temp;
2566     }
2567     tfm_temp = getc(tfm_file);
2568     {
2569       np = tfm_temp;
2570       if (np > 127)
2571         goto lab11;
2572       tfm_temp = getc(tfm_file);
2573       np = np * 256 + tfm_temp;
2574     }
2575     if (lf != 6 + lh + (ec - bc + 1) + nw + nh + nd + ni + nl + nk + ne + np)
2576       goto lab11;
2577
2578     if ((nw == 0) || (nh == 0) || (nd == 0) || (ni == 0))
2579       goto lab11;
2580   }
2581
2582   lf = lf - 6 - lh;
2583
2584   if (np < 7)
2585     lf = lf + 7 - np;
2586 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2587 #ifdef ALLOCATEFONT
2588   if ((fmem_ptr + lf > current_font_mem_size))   /* 93/Nov/28 */
2589     font_info = realloc_font_info (increment_font_mem_size + lf);
2590
2591   if ((font_ptr == font_max) || (fmem_ptr + lf > current_font_mem_size))
2592 #else
2593   if ((font_ptr == font_max) || (fmem_ptr + lf > font_mem_size))
2594 #endif
2595   {
2596     if (trace_flag)
2597     {
2598       sprintf(log_line, "font_ptr %d font_max %d fmem_ptr %d lf %d font_mem_size %d\n",
2599           font_ptr, font_max, fmem_ptr, lf, font_mem_size); /* debugging */
2600       show_line(log_line, 0);
2601     }
2602
2603     print_err("Font ");
2604     sprint_cs(u);
2605     print_char('=');
2606     print_file_name(nom, aire, 335); /* "" */
2607
2608     if (s >= 0)
2609     {
2610       print_string(" at ");
2611       print_scaled(s);
2612       print_string("pt");
2613     }
2614     else if (s != -1000)
2615     {
2616       print_string(" scaled ");
2617       print_int(- (integer) s);
2618     }
2619
2620     print_string(" not loaded: Not enough room left");
2621     help4("I'm afraid I won't be able to make use of this font,",
2622         "because my memory for character-size data is too small.",
2623         "If you're really stuck, ask a wizard to enlarge me.",
2624         "Or maybe try `I\\font<same font id>=<name of loaded font>'.");
2625     error();
2626     goto lab30;
2627   }
2628
2629   f = font_ptr + 1;
2630   char_base[f] = fmem_ptr - bc;
2631   width_base[f] = char_base[f] + ec + 1;
2632   height_base[f] = width_base[f] + nw;
2633   depth_base[f] = height_base[f] + nh;
2634   italic_base[f] = depth_base[f] + nd;
2635   lig_kern_base[f] = italic_base[f] + ni;
2636   kern_base[f] = lig_kern_base[f] + nl - 256 * (128);
2637   exten_base[f] = kern_base[f] + 256 * (128) + nk;
2638   param_base[f] = exten_base[f] + ne;
2639
2640   {
2641     if (lh < 2)
2642       goto lab11;
2643 /*  build the font checksum now */
2644     {
2645       tfm_temp = getc(tfm_file);
2646       a = tfm_temp;
2647       qw.b0 = a;
2648       tfm_temp = getc(tfm_file);
2649       b = tfm_temp;
2650       qw.b1 = b;
2651       tfm_temp = getc(tfm_file);
2652       c = tfm_temp;
2653       qw.b2 = c;
2654       tfm_temp = getc(tfm_file);
2655       d = tfm_temp;
2656       qw.b3 = d;
2657       font_check[f] = qw;
2658     }
2659
2660     tfm_temp = getc(tfm_file);
2661     {
2662       z = tfm_temp;
2663       if (z > 127)
2664         goto lab11;
2665       tfm_temp = getc(tfm_file);
2666       z = z * 256 + tfm_temp;
2667     }
2668
2669     tfm_temp = getc(tfm_file);
2670     z = z * 256 + tfm_temp;
2671     tfm_temp = getc(tfm_file);
2672     z =(z * 16) + (tfm_temp / 16);
2673
2674     if (z < 65536L)
2675       goto lab11; 
2676
2677     while (lh > 2)
2678     {
2679       tfm_temp = getc(tfm_file);
2680       tfm_temp = getc(tfm_file);
2681       tfm_temp = getc(tfm_file);
2682       tfm_temp = getc(tfm_file);
2683       decr(lh);
2684     }
2685
2686     font_dsize[f] = z;
2687
2688     if (s != -1000)
2689       if (s >= 0)
2690         z = s;
2691       else
2692         z = xn_over_d(z, - (integer) s, 1000);
2693
2694     font_size[f] = z;
2695   }
2696
2697   for (k = fmem_ptr; k <= width_base[f] - 1; k++)
2698   {
2699     {
2700       tfm_temp = getc(tfm_file);
2701       a = tfm_temp;
2702       qw.b0 = a;
2703       tfm_temp = getc(tfm_file);
2704       b = tfm_temp;
2705       qw.b1 = b;
2706       tfm_temp = getc(tfm_file);
2707       c = tfm_temp;
2708       qw.b2 = c;
2709       tfm_temp = getc(tfm_file);
2710       d = tfm_temp;
2711       qw.b3 = d;
2712       font_info[k].qqqq = qw;
2713     }
2714
2715     if ((a >= nw) || (b / 16 >= nh) || (b % 16 >= nd) || (c / 4 >= ni))
2716       goto lab11;
2717
2718     switch (c % 4)
2719     {
2720       case 1 :
2721         if (d >= nl)
2722           goto lab11;
2723         break;
2724
2725       case 3 :
2726         if (d >= ne)
2727           goto lab11;
2728         break;
2729
2730       case 2 :
2731         {
2732           {
2733             if ((d < bc)||(d > ec))
2734               goto lab11;
2735           }
2736
2737           while (d < k + bc - fmem_ptr)
2738           {
2739             qw = font_info[char_base[f]+ d].qqqq;
2740  
2741             if (((qw.b2)% 4)!= 2)
2742               goto lab45;
2743
2744             d = qw.b3;
2745           }
2746
2747           if (d == k + bc - fmem_ptr)
2748             goto lab11;
2749 lab45:; 
2750         }
2751         break;
2752
2753       default:
2754         break;
2755     }
2756   }
2757   {
2758     {
2759       alpha = 16;
2760
2761       while (z >= 8388608L)   /* 2^23 */
2762       {
2763         z = z / 2;
2764         alpha = alpha + alpha;
2765       }
2766
2767       beta = (char) (256 / alpha);
2768       alpha = alpha * z;
2769     }
2770
2771     for (k = width_base[f]; k <= lig_kern_base[f] - 1; k++)
2772     {
2773       tfm_temp = getc(tfm_file);
2774       a = tfm_temp;
2775       tfm_temp = getc(tfm_file);
2776       b = tfm_temp;
2777       tfm_temp = getc(tfm_file);
2778       c = tfm_temp;
2779       tfm_temp = getc(tfm_file);
2780       d = tfm_temp;
2781       sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2782
2783       if (a == 0)
2784         font_info[k].cint = sw;
2785       else if (a == 255)
2786         font_info[k].cint = sw - alpha;
2787       else
2788         goto lab11;
2789     }
2790
2791     if (font_info[width_base[f]].cint != 0)
2792       goto lab11;
2793
2794     if (font_info[height_base[f]].cint != 0)
2795       goto lab11;
2796
2797     if (font_info[depth_base[f]].cint != 0)
2798       goto lab11;
2799
2800     if (font_info[italic_base[f]].cint != 0)
2801       goto lab11;
2802   }
2803 /*  read ligature/kern program */
2804   bchlabel = 32767;     /* '77777 */
2805   bchar = 256;
2806
2807   if (nl > 0)
2808   {
2809     for (k = lig_kern_base[f]; k <= kern_base[f] + 256 * (128) - 1; k++)
2810     {
2811       {
2812         tfm_temp = getc(tfm_file);
2813         a = tfm_temp;
2814         qw.b0 = a;
2815         tfm_temp = getc(tfm_file);
2816         b = tfm_temp;
2817         qw.b1 = b;
2818         tfm_temp = getc(tfm_file);
2819         c = tfm_temp;
2820         qw.b2 = c;
2821         tfm_temp = getc(tfm_file);
2822         d = tfm_temp;
2823         qw.b3 = d;
2824         font_info[k].qqqq = qw; /* store_four_quarters(font_info[k].qqqq */
2825       }
2826
2827       if (a > 128)
2828       {
2829         if (256 * c + d >= nl)
2830           goto lab11;       /* error in TFM, abort */
2831
2832         if (a == 255)
2833           if (k == lig_kern_base[f])
2834             bchar = b;
2835       }
2836       else
2837       {
2838         if (b != bchar)
2839         {
2840           {
2841             if ((b < bc) || (b > ec))  /* check-existence(b) */
2842               goto lab11;         /* error in TFM, abort */
2843           }
2844
2845           qw = font_info[char_base[f] + b].qqqq;
2846
2847           if (!(qw.b0 > 0))
2848             goto lab11;         /* error in TFM, abort */
2849         }
2850
2851         if (c < 128)
2852         {
2853           {
2854             if ((d < bc) || (d > ec))  /* check-existence(d) */
2855               goto lab11;         /* error in TFM, abort */
2856           }
2857
2858           qw = font_info[char_base[f] + d].qqqq;
2859
2860           if (!(qw.b0 > 0))
2861             goto lab11;         /* error in TFM, abort */
2862         }
2863         else if (256 * (c - 128) + d >= nk)
2864           goto lab11;           /* error in TFM, abort */
2865         if (a < 128)
2866           if (k - lig_kern_base[f] + a + 1 >= nl)
2867             goto lab11;         /* error in TFM, abort */
2868       }
2869     }
2870
2871     if (a == 255)
2872       bchlabel = 256 * c + d;
2873   }
2874
2875   for (k = kern_base[f] + 256 * (128); k <= exten_base[f] - 1; k++)
2876   {
2877     tfm_temp = getc(tfm_file);
2878     a = tfm_temp;
2879     tfm_temp = getc(tfm_file);
2880     b = tfm_temp;
2881     tfm_temp = getc(tfm_file);
2882     c = tfm_temp;
2883     tfm_temp = getc(tfm_file);
2884     d = tfm_temp;
2885     sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2886
2887     if (a == 0)
2888       font_info[k].cint = sw;
2889     else if (a == 255)
2890       font_info[k].cint = sw - alpha;
2891     else goto lab11;
2892   }
2893 /*  read extensible character recipes */
2894 /*  for k:=exten_base[f] to param_base[f]-1 do */
2895   for (k = exten_base[f]; k <= param_base[f] - 1; k++)
2896   {
2897     {
2898       tfm_temp = getc(tfm_file);
2899       a = tfm_temp;
2900       qw.b0 = a;
2901       tfm_temp = getc(tfm_file);
2902       b = tfm_temp;
2903       qw.b1 = b;
2904       tfm_temp = getc(tfm_file);
2905       c = tfm_temp;
2906       qw.b2 = c;
2907       tfm_temp = getc(tfm_file);
2908       d = tfm_temp;
2909       qw.b3 = d;
2910 /*    store_four_quarters(font_info[k].qqqq); */
2911       font_info[k].qqqq = qw;
2912     }
2913
2914     if (a != 0)
2915     {
2916       {
2917         if ((a < bc) || (a > ec))
2918           goto lab11;
2919       }
2920
2921       qw = font_info[char_base[f] + a].qqqq;
2922
2923       if (!(qw.b0 > 0))
2924         goto lab11;
2925     }
2926
2927     if (b != 0)
2928     {
2929       {
2930         if ((b < bc) || (b > ec))
2931           goto lab11;
2932       }
2933
2934       qw = font_info[char_base[f] + b].qqqq;
2935
2936       if (!(qw.b0 > 0))
2937         goto lab11;
2938     }
2939
2940     if (c != 0)
2941     {
2942       {
2943         if ((c < bc) || (c > ec))
2944           goto lab11;
2945       }
2946
2947       qw = font_info[char_base[f] + c].qqqq;
2948
2949       if (!(qw.b0 > 0))
2950         goto lab11;
2951     }
2952     {
2953       {
2954         if ((d < bc) || (d > ec))
2955           goto lab11;
2956       }
2957
2958       qw = font_info[char_base[f] + d].qqqq;
2959
2960       if (!(qw.b0 > 0))
2961         goto lab11;
2962     }
2963   }
2964   {
2965     for (k = 1; k <= np; k++)
2966       if (k == 1)
2967       {
2968         tfm_temp = getc(tfm_file);
2969         sw = tfm_temp;
2970
2971         if (sw > 127)
2972           sw = sw - 256;
2973
2974         tfm_temp = getc(tfm_file);
2975         sw = sw * 256 + tfm_temp;
2976         tfm_temp = getc(tfm_file);
2977         sw = sw * 256 + tfm_temp;
2978         tfm_temp = getc(tfm_file);
2979         font_info[param_base[f]].cint = (sw * 16) + (tfm_temp / 16);
2980       }
2981       else
2982       {
2983         tfm_temp = getc(tfm_file);
2984         a = tfm_temp;
2985         tfm_temp = getc(tfm_file);
2986         b = tfm_temp;
2987         tfm_temp = getc(tfm_file);
2988         c = tfm_temp;
2989         tfm_temp = getc(tfm_file);
2990         d = tfm_temp;
2991         sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2992
2993         if (a == 0)
2994           font_info[param_base[f] + k - 1].cint = sw;
2995         else if (a == 255)
2996           font_info[param_base[f] + k - 1].cint = sw - alpha;
2997         else goto lab11;
2998       }
2999 /*  use test_eof() here instead ? */
3000     if (feof(tfm_file))
3001       goto lab11;
3002
3003     for (k = np + 1; k <= 7; k++)
3004       font_info[param_base[f] + k - 1].cint = 0;
3005   }
3006 /* @<Make final adjustments...@>= l.11174 */
3007   if (np >= 7)
3008     font_params[f] = np;
3009   else
3010     font_params[f] = 7;
3011
3012   hyphen_char[f] = default_hyphen_char;
3013   skew_char[f] = default_skew_char;
3014
3015   if (bchlabel < nl)
3016     bchar_label[f] = bchlabel + lig_kern_base[f];
3017   else
3018     bchar_label[f]= non_address; /* i.e. 0 --- 96/Jan/15 */
3019
3020   font_bchar[f] = bchar;
3021   font_false_bchar[f] = bchar;
3022
3023   if (bchar <= ec)
3024     if (bchar >= bc)
3025     {
3026       qw = font_info[char_base[f] + bchar].qqqq;
3027
3028       if ((qw.b0 > 0))
3029         font_false_bchar[f] = 256;
3030     }
3031
3032   font_name[f] = nom;
3033   font_area[f] = aire;
3034   font_bc[f] = bc;
3035   font_ec[f] = ec;
3036   font_glue[f] = 0;  /* font_glue[f]:=null; l.11184 */
3037   char_base[f] = char_base[f];
3038   width_base[f] = width_base[f];
3039   lig_kern_base[f] = lig_kern_base[f];
3040   kern_base[f] = kern_base[f];
3041   exten_base[f] = exten_base[f];
3042   decr(param_base[f]);
3043   fmem_ptr = fmem_ptr + lf;
3044   font_ptr = f;
3045   g = f;
3046   goto lab30;
3047 lab11:
3048   print_err("Font ");
3049   sprint_cs(u); 
3050   print_char('=');
3051   print_file_name(nom, aire, 335);  /* "" */
3052
3053   if (s >= 0)
3054   {
3055     print_string(" at ");
3056     print_scaled(s);
3057     print_string("pt");
3058   }
3059   else if (s != -1000)
3060   {
3061     print_string("scaled");
3062     print_int(- (integer) s);
3063   } 
3064
3065   if (fileopened)
3066     print_string(" not loadable: Bad metric (TFM) file");
3067   else
3068     print_string(" not loadable: Metric (TFM) file not found");
3069
3070   if (aire == 335) /* "" only if path not specified */
3071   {
3072     if (show_texinput_flag)
3073       show_tex_fonts();   /* 98/Jan/31 */
3074   }
3075
3076   help5("I wasn't able to read the size data for this font,",
3077       "so I will ignore the font specification.",
3078       "[Wizards can fix TFM files using TFtoPL/PLtoTF.]",
3079       "You might try inserting a different font spec;",
3080       "e.g., type `I\\font<same font id>=<substitute font name>'.");
3081   error();
3082 lab30:
3083   if (fileopened)
3084     b_close(tfm_file);
3085
3086   return g;
3087 }