OSDN Git Service

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