OSDN Git Service

code clean.
[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.v.RH;
637           mem[q].hh.v.RH = 0;
638 #ifdef STAT
639           incr(dyn_used); 
640 #endif /* STAT */
641         }
642       } 
643       mem[p].hh.v.RH = q;
644       mem[q].hh.v.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.v.RH = q;
673       mem[q].hh.v.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.v.RH;
689               mem[q].hh.v.RH = 0;
690 #ifdef STAT
691               incr(dyn_used);
692 #endif /* STAT */
693             }
694           }
695           mem[p].hh.v.RH = q;
696           mem[q].hh.v.LH = mem[r].hh.v.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.v.RH = q;
869             mem[q].hh.v.LH = cur_tok;
870             p = q;
871           }
872           {
873             q = get_avail();
874             mem[p].hh.v.RH = q;
875             mem[q].hh.v.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.v.RH = q;
904         mem[q].hh.v.LH = cur_tok;
905         p = q;
906       }
907     }
908 lab31:
909     {
910       q = get_avail();
911       mem[p].hh.v.RH = q;
912       mem[q].hh.v.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.v.RH = q;
1003       mem[q].hh.v.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.v.RH = q;
1014     mem[q].hh.v.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.v.RH = q;
1039     mem[q].hh.v.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.v.RH = q;
1138           mem[q].hh.v.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; /* index between `file area' and `file name' */
1529   ext_delimiter = 0;  /* index between `file name' and `file extension' */
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 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1549 /*  convert pseudo tilde back to '~' 95/Sep/26 */ /* moved here 97/June/5 */
1550 /*  if (pseudo_tilde != 0 && c == pseudo_tilde) c = '~'; */
1551 /*  convert pseudo space back to ' ' 97/June/5 */ /* moved here 97/June/5 */
1552 /*  if (pseudo_space != 0 && c == pseudo_space) c = ' '; */
1553 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */      
1554     str_room(1);
1555     append_char(c);
1556 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1557 //  if ((c == 47))   /* / */
1558 //  for DOS/Windows
1559     if ((c == '/' || c == '\\' || c == ':')) /* 94/Mar/1 */
1560 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1561     {
1562       area_delimiter = cur_length;
1563       ext_delimiter = 0;
1564     } 
1565     else if (c == '.')
1566       ext_delimiter = cur_length;
1567     return true;
1568   }
1569 }
1570 /******************************** 2000 August 15th start ***********************/
1571
1572 // The following code is to save string space used by TeX for filenames
1573 // Not really critical in a system that has dynamic memory allocation
1574 // And may slow it down slightly - although this linear search only
1575 // occurs when opening a file, which is somewhat slow inany case...
1576
1577 // see if string from str_pool[start] to str_pool[end]
1578 // occurs elsewhere in string pool - returns string number
1579 // returns -1 if not found in string pool 2000 Aug 15
1580
1581 int find_string (int start, int end)
1582 {
1583   int k, nlen = end - start;
1584   char *s;
1585
1586 //  int trace_flag = 1;     // debugging only
1587
1588   if (trace_flag)
1589   {
1590     sprintf(log_line, "\nLOOKING for string (str_ptr %d nlen %d) ", str_ptr, end - start);
1591     s = log_line + strlen(log_line);
1592     strncpy(s, (const char *) str_pool + start, nlen);
1593     strcpy(s + nlen, "");
1594     show_line(log_line, 0);
1595   }
1596
1597 //  avoid problems with(cur_name == flushablestring)by going only up to str_ptr-1
1598 //  code in new_font (tex8.c) will take care of reuse of font name already
1599   for (k = 0; k < str_ptr - 1; k++)
1600   {
1601     if (length(k) != nlen)
1602       continue;
1603
1604     if (strncmp((const char *) str_pool + start, (const char *) str_pool + str_start[k], nlen) == 0)
1605     {
1606       if (trace_flag)
1607       {
1608         sprintf(log_line, "\nFOUND the string %d (%d) ", k, str_start[k+1]-str_start[k]);
1609         s = log_line + strlen(log_line);
1610         strncpy(s, (const char *)str_pool + start, nlen);
1611         strcpy(s+nlen, "\n");
1612         show_line(log_line, 0);
1613       }
1614       return k;     // return number of matching string
1615     }
1616   }
1617
1618   if (trace_flag)
1619   {
1620     sprintf(log_line, "\nNOT FOUND string ");
1621     s = log_line + strlen(log_line);
1622     strncpy(s, (const char*)str_pool + start, nlen);
1623     strcpy(s + nlen, "\n");
1624     show_line(log_line, 0);
1625   }
1626
1627   return -1;          // no match found
1628 }
1629
1630 // snip out the string from str_pool[start] to str_pool[end]
1631 // and move everything above it down 2000 Aug 15
1632
1633 void remove_string (int start, int end)
1634 {
1635   int nlen = pool_ptr - end;  // how many bytes to move down
1636   char *s;
1637   
1638 //  int trace_flag=1;   // debugging only
1639 //  if (end < start) show_line("\nEND < START", 1);
1640 //  if (pool_ptr < end) show_line("\nPOOLPTR < END", 1);
1641
1642   if (trace_flag)
1643   {
1644     int n = end - start;
1645     sprintf(log_line, "\nSTRIPPING OUT %d %d ", n, nlen);
1646     s = log_line + strlen(log_line);
1647     strncpy(s, (const char *)str_pool + start, n);
1648     strcpy(s + n, "\n");
1649     show_line(log_line, 0);
1650   }
1651
1652   if (nlen > 0)
1653     memcpy(str_pool + start, str_pool + end, nlen);
1654
1655   pool_ptr = start + nlen;    // poolprt - (end-start);
1656 }
1657
1658 void show_string (int k)
1659 {
1660   int nlen = length(k);
1661   char *s;
1662   
1663   sprintf(log_line, "\nSTRING %5d (%3d) %5d--%5d ",
1664       k, nlen, str_start[k], str_start[k+1]);
1665   s = log_line + strlen(log_line);      
1666   strncpy(s, (const char *)str_pool + str_start[k], nlen);
1667   strcpy(s + nlen, "");
1668   show_line(log_line, 0);
1669 }
1670
1671 void show_all_strings (void)
1672 {
1673   int k;
1674
1675   for (k = 0; k < str_ptr; k++)
1676     show_string(k);
1677 }
1678
1679 /********************************** 2000 August 15 end ****************************/
1680 /* sec 0517 */
1681 void end_name (void) 
1682 {
1683 #ifdef ALLOCATESTRING
1684   if (str_ptr + 3 > current_max_strings)
1685     str_start = realloc_str_start(increment_max_strings + 3);
1686
1687   if (str_ptr + 3 > current_max_strings)
1688   {
1689     overflow("number of strings", current_max_strings - init_str_ptr);  /* 97/Mar/7 */
1690     return;     // abort_flag set
1691   }
1692 #else
1693   if (str_ptr + 3 > max_strings)
1694   {
1695     overflow("number of strings", max_strings - init_str_ptr); /* number of strings */
1696     return;     // abort_flag set
1697   }
1698 #endif
1699
1700 //  if (notfirst++ == 0) show_all_strings();  // debugging only
1701   
1702   if (area_delimiter == 0)   // no area delimiter ':' '/' or '\' found
1703     cur_area = 335;     // "" default area 
1704   else
1705   {
1706     if (save_strings_flag && (cur_area = find_string(str_start[str_ptr], str_start[str_ptr] + area_delimiter)) > 0)
1707     {
1708       remove_string(str_start[str_ptr], str_start[str_ptr] + area_delimiter);
1709       area_delimiter = 0; // area_delimiter - area_delimiter;
1710
1711       if (ext_delimiter != 0)
1712         ext_delimiter = ext_delimiter - area_delimiter;
1713
1714 //      str_start[str_ptr + 1]= str_start[str_ptr]+ area_delimiter; // test only
1715 //      incr(str_ptr);    // test only
1716     }
1717     else         // carve out string for "cur_area"
1718     {
1719       cur_area = str_ptr; 
1720       str_start[str_ptr + 1] = str_start[str_ptr] + area_delimiter; 
1721       incr(str_ptr);
1722     }
1723   }
1724
1725   if (ext_delimiter == 0) // no extension delimiter '.' found
1726   {
1727     cur_ext = 335;        // "" default extension 
1728
1729     if (save_strings_flag && (cur_name = find_string(str_start[str_ptr], pool_ptr)) > 0)
1730     {
1731       remove_string(str_start[str_ptr], pool_ptr);
1732 //    (void) make_string();  // test only
1733     }
1734     else            // Make string from str_start[str_ptr]to pool_ptr
1735       cur_name = make_string();
1736   } 
1737   else            // did find an extension
1738   {
1739     if (save_strings_flag &&
1740       (cur_name = find_string(str_start[str_ptr], str_start[str_ptr] + ext_delimiter - area_delimiter-1)) > 0)
1741     {
1742       remove_string(str_start[str_ptr], str_start[str_ptr] + ext_delimiter - area_delimiter - 1);
1743 //    str_start[str_ptr + 1]= str_start[str_ptr]+ ext_delimiter - area_delimiter - 1;   // test only
1744 //    incr(str_ptr);    // test only
1745     }
1746     else             // carve out string for "cur_name"
1747     {
1748       cur_name = str_ptr;
1749       str_start[str_ptr + 1]= str_start[str_ptr]+ ext_delimiter - area_delimiter - 1;
1750       incr(str_ptr);
1751     }
1752
1753     if (save_strings_flag && (cur_ext = find_string(str_start[str_ptr], pool_ptr)) > 0)
1754     {
1755       remove_string(str_start[str_ptr], pool_ptr);
1756 //    (void) make_string();  // test only
1757     }
1758     else            // Make string from str_start[str_ptr]to pool_ptr
1759       cur_ext = make_string();
1760   }
1761 }
1762
1763 /* n current name, a current area, e current extension */
1764 /* result in name_of_file[] */
1765 /* sec 0519 */
1766 void pack_file_name_(str_number n, str_number a, str_number e)
1767 {
1768   integer k;
1769   ASCII_code c;
1770   pool_pointer j;
1771
1772   k = 0;
1773
1774   for (j = str_start[a]; j <= str_start[a + 1] - 1; j++)
1775   {
1776     c = str_pool[j];
1777     incr(k);
1778
1779     if (k <= PATHMAX)
1780       name_of_file[k] = xchr[c];
1781   }
1782
1783   for (j = str_start[n]; j <= str_start[n + 1] - 1; j++)
1784   {
1785     c = str_pool[j];
1786     incr(k);
1787
1788     if (k <= PATHMAX)
1789       name_of_file[k] = xchr[c];
1790   }
1791
1792   for (j = str_start[e]; j <= str_start[e + 1] - 1; j++)
1793   {
1794     c = str_pool[j];
1795     incr(k);
1796
1797     if (k <= PATHMAX)
1798       name_of_file[k] = xchr[c];
1799   }
1800
1801   if (k < PATHMAX)
1802     name_length = k;
1803   else
1804     name_length = PATHMAX - 1;
1805
1806 /*  pad it out with spaces ... what for ? in case we modify and forget  ? */
1807   for (k = name_length + 1; k <= PATHMAX; k++)
1808     name_of_file[k] = ' ';
1809
1810   name_of_file[PATHMAX] = '\0';    /* paranoia 94/Mar/24 */
1811
1812   {
1813     name_of_file [name_length+1] = '\0';
1814
1815     if (trace_flag)
1816     {
1817       sprintf(log_line, " pack_file_name `%s' (%d) ", name_of_file + 1, name_length); /* debugging */
1818       show_line(log_line, 0);
1819     }
1820
1821     name_of_file [name_length + 1] = ' ';
1822   }
1823 }
1824 /* Called only from two places tex9.c for format name - specified and default */
1825 /* for specified format name args are 0, a, b name in buffer[a] --- buffer[b] */
1826 /* for default args are format_default_length-4, 1, 0 */
1827 /* sec 0523 */
1828 void pack_buffered_name_(small_number n, integer a, integer b)
1829 {
1830   integer k;
1831   ASCII_code c;
1832   integer j;
1833
1834   if (n + b - a + 5 > PATHMAX)
1835     b = a + PATHMAX - n - 5;
1836
1837   k = 0;
1838
1839 /*  This loop kicks in when we want the default format name */
1840   for (j = 1; j <= n; j++)
1841   {
1842     c = xord[TEX_format_default[j]];
1843     incr(k);
1844
1845     if (k <= PATHMAX)
1846       name_of_file[k] = xchr[c];
1847   }
1848 /*  This loop kicks in when we want a specififed format name */
1849   for (j = a; j <= b; j++)
1850   {
1851     c = buffer[j];
1852     incr(k);
1853
1854     if (k <= PATHMAX)
1855       name_of_file[k] = xchr[c];
1856   }
1857
1858 /*  This adds the extension from the default format name */
1859   for (j = format_default_length - 3; j <= format_default_length; j++)
1860   {
1861     c = xord[TEX_format_default[j]];
1862     incr(k);
1863
1864     if (k <= PATHMAX)
1865       name_of_file[k] = xchr[c];
1866   }
1867
1868   if (k < PATHMAX)
1869     name_length = k;
1870   else
1871     name_length = PATHMAX - 1;
1872
1873  /*  pad it out with spaces ... what for ? */
1874   for (k = name_length + 1; k <= PATHMAX; k++)
1875     name_of_file[k]= ' ';
1876
1877   name_of_file[PATHMAX] = '\0';    /* paranoia 94/Mar/24 */
1878 }
1879 /* sec 0525 */
1880 str_number make_name_string (void)
1881 {
1882   integer k;
1883
1884 #ifdef ALLOCATESTRING
1885   if (pool_ptr + name_length > current_pool_size)
1886     str_pool = realloc_str_pool(increment_pool_size + name_length);
1887
1888   if (str_ptr == current_max_strings)
1889     str_start = realloc_str_start(increment_max_strings);
1890
1891   if ((pool_ptr + name_length > current_pool_size) || (str_ptr == current_max_strings) || (cur_length > 0))
1892 #else
1893   if ((pool_ptr + name_length > pool_size) || (str_ptr == max_strings) || (cur_length > 0))
1894 #endif
1895   {
1896     return '?';
1897   }
1898   else
1899   {
1900     for (k = 1; k <= name_length; k++)
1901       append_char(xord[name_of_file[k]]);
1902
1903     return make_string();
1904   }
1905 }
1906 /* sec 0525 */
1907 str_number a_make_name_string_(alpha_file * f)
1908 {
1909   return make_name_string();
1910 }
1911 /* sec 0525 */
1912 str_number b_make_name_string_(byte_file * f)
1913 {
1914   return make_name_string(); 
1915 }
1916 /* sec 0525 */
1917 str_number w_make_name_string_(word_file * f)
1918 {
1919   return make_name_string();
1920 }
1921
1922 /* Used by start_input to scan file name on command line */
1923 /* Also in tex8.c new_font_, open_or_close_in, and do_extension */
1924 /* sec 0526 */
1925 void scan_file_name (void)
1926 {
1927   name_in_progress = true;
1928   begin_name();
1929
1930   do
1931     {
1932       get_x_token(); 
1933     }
1934   while (!(cur_cmd != spacer));
1935
1936   quoted_file_name = false;
1937
1938   if (allow_quoted_names)
1939   {
1940     if (cur_chr == '"')
1941     {
1942       quoted_file_name = 1;
1943       get_x_token();
1944     }
1945   }
1946
1947   while (true)
1948   {
1949     if ((cur_cmd > other_char) || (cur_chr > 255)) 
1950     {
1951       back_input();
1952       goto lab30; 
1953     } 
1954
1955     if (!more_name(cur_chr))    /* up to next white space */
1956       goto lab30;
1957
1958     get_x_token();
1959   }
1960
1961 lab30:
1962   end_name();
1963   name_in_progress = false;
1964 }
1965 /* argument is string .fmt, .log, or .dvi */
1966 /* sec 0529 */
1967 void pack_job_name_(str_number s)
1968 {
1969   cur_area = 335;       /* "" */
1970   cur_ext  = s;
1971   cur_name = job_name;
1972   pack_file_name(cur_name, cur_area, cur_ext);
1973 }
1974
1975 /**********************************************************************/
1976 /* show TEXINPUTS=... or format specific  */
1977 /* only show this if name was not fully qualified ? */
1978 void show_tex_inputs (void)
1979 {
1980   char *s, *t, *v;
1981
1982   s = "TEXINPUTS";        /* default */
1983
1984   if (format_specific)
1985   {
1986     s = format_name;                /* try specific */
1987
1988     if (grabenv(s) == NULL)
1989       s = "TEXINPUTS";  /* no format specific */
1990   }
1991
1992   if (grabenv(s) == NULL)
1993     s = "TEXINPUT";     /* 94/May/19 */
1994
1995   print_nl("  ");
1996   print_char(' ');
1997   print_char('(');
1998   t = s;
1999
2000   while (*t > '\0')
2001     print_char(*t++);
2002
2003   print_char('=');
2004   v = grabenv(s);
2005
2006   if (v != NULL)
2007   {
2008     t = v;
2009
2010     while (*t > '\0')
2011       print_char(*t++);
2012   }
2013
2014   print_char(')');
2015 }
2016
2017 /**********************************************************************/
2018 /* sec 0530 */
2019 /* s - what can't be found, e - default */
2020 void prompt_file_name_(char * s, str_number e) 
2021 {
2022   integer k;
2023
2024   if (interaction == scroll_mode);
2025
2026   if (!strcmp("input file name", s))
2027     print_err("I can't find file `");
2028   else
2029     print_err("I can't write on file `");
2030
2031   print_file_name(cur_name, cur_area, cur_ext);
2032   print_string("'.");
2033
2034   if (!strcmp("input file name", s))
2035   {
2036     if (cur_area == 335) /* "" only if path not specified */
2037     {
2038       if (show_texinput_flag)
2039         show_tex_inputs();
2040     }
2041   }
2042
2043   if (e == 785)    /* .tex */
2044     show_context();
2045
2046   print_nl("Please type another ");
2047   print_string(s); 
2048
2049   if (interaction < 2)
2050   {
2051     fatal_error("*** (job aborted, file error in nonstop mode)");
2052     return;     // abort_flag set
2053   }
2054
2055   if (!knuth_flag)
2056 #ifdef _WINDOWS
2057     show_line(" (or ^z to exit)", 0);
2058 #else
2059     show_line(" (or Ctrl-Z to exit)", 0);
2060 #endif
2061   {
2062     print_string(": ");
2063     term_input(": ", 0);
2064   }
2065 /*  should we deal with tilde and space in file name here ??? */
2066   {
2067     begin_name();
2068     k = first;
2069
2070     while ((buffer[k] == ' ') && (k < last))
2071       incr(k);
2072 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2073     quoted_file_name = 0;         /* 98/March/15 */
2074
2075     if (allow_quoted_names && k < last) /* check whether quoted name */
2076     {
2077       if (buffer[k]== '"')
2078       {
2079         quoted_file_name = 1;
2080         incr(k);
2081       }
2082     }
2083
2084     while (true)
2085     {
2086       if (k == last)
2087         goto lab30;
2088 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2089 /*  convert tilde '~' to pseudo tilde */
2090       if (pseudo_tilde != 0 && buffer[k]== '~')
2091         buffer[k] = pseudo_tilde;
2092 /*  convert space ' ' to pseudo space */
2093       if (pseudo_space != 0 && buffer[k]== ' ')
2094         buffer[k] = pseudo_space;
2095 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2096       if (!more_name(buffer[k]))
2097         goto lab30;
2098
2099       incr(k);
2100     }
2101 lab30:
2102     end_name();
2103   }
2104
2105   if (cur_ext == 335)    /* "" */
2106     cur_ext = e;      /* use default extension */
2107
2108   pack_file_name(cur_name, cur_area, cur_ext);
2109 }
2110 /* sec 0534 */
2111 void open_log_file (void)
2112 {
2113   char old_setting;
2114   integer k;
2115   integer l;
2116   char * months;
2117
2118   old_setting = selector;
2119
2120   if (job_name == 0)
2121     job_name = 790;
2122
2123   pack_job_name(".log");
2124
2125   while (!a_open_out(log_file))
2126   {
2127     selector = term_only;
2128     prompt_file_name("transcript file name", ".log");
2129   }
2130
2131   texmf_log_name = a_make_name_string(log_file);
2132   selector = log_only;
2133   log_opened = true;
2134
2135   {
2136     if (want_version)
2137     {
2138       stamp_it(log_line);
2139       strcat(log_line, "\n");
2140       (void) fputs(log_line, log_file);
2141       stampcopy(log_line);
2142       strcat(log_line, "\n");
2143       (void) fputs(log_line, log_file);
2144     }
2145     
2146     (void) fputs(tex_version, log_file); 
2147     (void) fprintf(log_file, " (%s %s)", application, yandyversion);
2148
2149     if (format_ident > 0)
2150       slow_print(format_ident);
2151
2152     print_string("  ");
2153
2154     if (civilize_flag)
2155       print_int(year);
2156     else
2157       print_int(day);
2158
2159     print_char(' ');
2160     months = " JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
2161
2162     for (k = 3 * month - 2; k <= 3 * month; k++)
2163       (void) putc(months[k],  log_file);
2164
2165     print_char(' ');
2166
2167     if (civilize_flag)
2168       print_int(day);
2169     else
2170       print_int(year);
2171
2172     print_char(' ');
2173     print_two(tex_time / 60);
2174     print_char(':');
2175     print_two(tex_time % 60);
2176   }
2177
2178   input_stack[input_ptr] = cur_input;
2179   print_nl("**");
2180   l = input_stack[0].limit_field;
2181
2182   if (buffer[l] == end_line_char)
2183     decr(l);
2184
2185   for (k = 1; k <= l; k++)
2186     print(buffer[k]);
2187
2188   print_ln(); 
2189
2190   if (show_fmt_flag)
2191   {
2192     if (format_file != NULL)
2193     {
2194       fprintf(log_file, "(%s)\n", format_file);
2195       free(format_file);
2196       format_file = NULL;
2197     }
2198   }
2199
2200   selector = old_setting + 2;
2201 }
2202
2203 /**************************** start of insertion 98/Feb/7 **************/
2204 // Attempt to deal with foo.bar.tex given as foo.bar on command line
2205 // Makes copy of job_name with extension
2206
2207 void more_name_copy(ASCII_code c)
2208 {
2209 #ifdef ALLOCATESTRING
2210   if (pool_ptr + 1 > current_pool_size)
2211     str_pool = realloc_str_pool (increment_pool_size);
2212
2213   if (pool_ptr + 1 > current_pool_size)
2214   {
2215     overflow("pool size", current_pool_size - init_pool_ptr);
2216     return;
2217   }
2218 #else
2219   if (pool_ptr + 1 > pool_size)
2220   {
2221     overflow("pool size", pool_size - init_pool_ptr);
2222     return;
2223   }
2224 #endif
2225
2226   str_pool[pool_ptr] = c; 
2227   incr(pool_ptr);
2228 }
2229
2230 int end_name_copy(void)
2231 {
2232 #ifdef ALLOCATESTRING
2233   if (str_ptr + 1 > current_max_strings)
2234     str_start = realloc_str_start(increment_max_strings + 1);
2235
2236   if (str_ptr + 1 > current_max_strings)
2237   {
2238     overflow("number of strings", current_max_strings - init_str_ptr);
2239     return 0;
2240   }
2241 #else
2242   if (str_ptr + 1 > max_strings)
2243   {
2244     overflow("number of strings", max_strings - init_str_ptr);
2245     return 0;
2246   }
2247 #endif
2248
2249   return make_string();
2250 }
2251
2252 void job_name_append (void)
2253
2254   int k, n;
2255
2256   k = str_start[job_name];
2257   n = str_start[job_name + 1];
2258
2259   while (k < n)
2260     more_name_copy(str_pool[k++]);
2261
2262   k = str_start[cur_ext];
2263   n = str_start[cur_ext + 1];
2264
2265   while (k < n)
2266     more_name_copy(str_pool[k++]);
2267
2268   job_name = end_name_copy();
2269 }
2270
2271 /**************************** end of insertion 98/Feb/7 **************/
2272 /* sec 0537 */
2273 void start_input(void)
2274 {
2275   bool added_extension = false;
2276
2277   scan_file_name();
2278   pack_file_name(cur_name, cur_area, cur_ext); 
2279
2280   while (true)
2281   {
2282     added_extension = false;
2283     begin_file_reading(); 
2284
2285     if ((cur_ext != 335) && a_open_in(input_file[cur_input.index_field], TEXINPUTPATH))
2286       goto lab30;
2287
2288     if ((cur_ext != 785) && (name_length + 5 < PATHMAX))
2289     {
2290       name_of_file[name_length + 1] = '.';
2291       name_of_file[name_length + 2] = 't';
2292       name_of_file[name_length + 3] = 'e';
2293       name_of_file[name_length + 4] = 'x';
2294       name_of_file[name_length + 5] = ' ';
2295       name_length = name_length + 4;
2296
2297       added_extension = true;
2298
2299       if (a_open_in(input_file[cur_input.index_field], TEXINPUTPATH))
2300         goto lab30;
2301
2302       name_length = name_length - 4;
2303       name_of_file[name_length + 1] = ' ';
2304       added_extension = false;
2305     }
2306
2307     if ((cur_ext == 335) && a_open_in(input_file[cur_input.index_field], TEXINPUTPATH))
2308       goto lab30;
2309
2310     end_file_reading();
2311     prompt_file_name("input file name", ".tex");
2312   }
2313
2314 lab30: 
2315   cur_input.name_field = a_make_name_string(input_file[cur_input.index_field]);
2316
2317   if (job_name == 0)
2318   {
2319     job_name = cur_name;
2320
2321     if (cur_ext != 335 && added_extension)
2322       job_name_append();
2323
2324     open_log_file();
2325   }
2326
2327   if (term_offset + length(cur_input.name_field) > max_print_line - 2)
2328     print_ln();
2329   else if ((term_offset > 0) || (file_offset > 0))
2330     print_char(' ');
2331
2332   print_char('(');
2333   incr(open_parens);
2334
2335   if (open_parens > max_open_parens)
2336     max_open_parens = open_parens;
2337
2338   slow_print(cur_input.name_field);
2339
2340 #ifndef _WINDOWS
2341   fflush(stdout);
2342 #endif
2343
2344   cur_input.state_field = new_line;
2345
2346   {
2347     line = 1;
2348
2349     if (input_ln(input_file[cur_input.index_field], false));
2350
2351     firm_up_the_line();
2352
2353     if ((end_line_char < 0) || (end_line_char > 255))
2354       decr(cur_input.limit_field);
2355     else
2356       buffer[cur_input.limit_field] = end_line_char;
2357
2358     first = cur_input.limit_field + 1;
2359     cur_input.loc_field = cur_input.start_field;
2360   }
2361 }
2362
2363 /**********************************************************************/
2364 /* show TEXFONTS=... or format specific  */
2365 /* only show this if name was not fully qualified ? */
2366 void show_tex_fonts (void)
2367 {
2368   char *s, *t, *v, *u;
2369   int n;
2370
2371   s = "TEXFONTS";
2372
2373   if (encoding_specific)
2374   {
2375     u = encoding_name;                /* try specific */
2376
2377     if ((t = grabenv(u)) != NULL)
2378     {
2379       if (strchr(t, ':') != NULL && sscanf(t, "%d", &n) == 0)
2380       {
2381         s = u;        /* look here instead of TEXFONTS=... */
2382       }
2383     }
2384   }
2385
2386   print_nl("  ");
2387   print_char(' ');
2388   print_char('(');
2389   t = s;
2390
2391   while (*t > '\0')
2392     print_char(*t++);
2393
2394   print_char('=');
2395   v = grabenv(s);
2396
2397   if (v != NULL)
2398   {
2399     t = v;
2400
2401     while (*t > '\0')
2402       print_char(*t++);
2403   }
2404
2405   print_char(')');
2406 }
2407 /* sec 0560 */
2408 internal_font_number read_font_info_(halfword u, str_number nom, str_number aire, scaled s)
2409 {
2410   font_index k;
2411   bool fileopened;
2412 /*  halfword lf, lh, bc, ec, nw, nh, nd, ni, nl, nk, ne, np;  */
2413   halfword lf, lh, nw, nh, nd, ni, nl, nk, ne, np;
2414 /*  halfword bc, ec; */
2415   int bc, ec;             /* 95/Jan/7 */
2416   internal_font_number f;
2417   internal_font_number g;
2418   eight_bits a, b, c, d;
2419   ffourquarters qw;
2420   scaled sw;
2421   integer bchlabel;
2422   short bchar;
2423   scaled z;
2424   integer alpha;
2425   char beta;
2426
2427   g = 0;
2428   fileopened = false;
2429   pack_file_name(nom, aire, 805); /* .tfm */
2430
2431   if (!b_open_in(tfm_file)) /* new in C version d */
2432   {
2433     goto lab11;
2434   } 
2435 /*   was just: goto lab11; */
2436   fileopened = true; 
2437   {
2438 /*  tfm_temp = getc(tfm_file);  */ /* done already in open_input, but why? */
2439     //tfm_temp = getc(tfm_file);
2440     {
2441       lf = tfm_temp;
2442       if (lf > 127)
2443         goto lab11;
2444       tfm_temp = getc(tfm_file);
2445       lf = lf * 256 + tfm_temp;
2446     }
2447     tfm_temp = getc(tfm_file);
2448     {
2449       lh = tfm_temp;
2450       if (lh > 127)
2451         goto lab11;
2452       tfm_temp = getc(tfm_file);
2453       lh = lh * 256 + tfm_temp;
2454     }
2455     tfm_temp = getc(tfm_file);
2456     {
2457       bc = tfm_temp;
2458       if (bc > 127)
2459         goto lab11;
2460       tfm_temp = getc(tfm_file);
2461       bc = bc * 256 + tfm_temp;
2462     }
2463     tfm_temp = getc(tfm_file);
2464     {
2465       ec = tfm_temp;
2466       if (ec > 127)
2467         goto lab11;
2468       tfm_temp = getc(tfm_file);
2469       ec = ec * 256 + tfm_temp;
2470     }
2471     if ((bc > ec + 1)||(ec > 255))
2472       goto lab11;
2473     if (bc > 255)
2474     {
2475       bc = 1;
2476       ec = 0;
2477     }
2478     tfm_temp = getc(tfm_file);
2479     {
2480       nw = tfm_temp;
2481       if (nw > 127)
2482         goto lab11;
2483       tfm_temp = getc(tfm_file);
2484       nw = nw * 256 + tfm_temp;
2485     }
2486     tfm_temp = getc(tfm_file);
2487     {
2488       nh = tfm_temp;
2489       if (nh > 127)
2490         goto lab11;
2491       tfm_temp = getc(tfm_file);
2492       nh = nh * 256 + tfm_temp;
2493     }
2494     tfm_temp = getc(tfm_file);
2495     {
2496       nd = tfm_temp;
2497       if (nd > 127)
2498         goto lab11;
2499       tfm_temp = getc(tfm_file);
2500       nd = nd * 256 + tfm_temp;
2501     }
2502     tfm_temp = getc(tfm_file);
2503     {
2504       ni = tfm_temp;
2505       if (ni > 127)
2506         goto lab11;
2507       tfm_temp = getc(tfm_file);
2508       ni = ni * 256 + tfm_temp;
2509     }
2510     tfm_temp = getc(tfm_file);
2511     {
2512       nl = tfm_temp;
2513       if (nl > 127)
2514         goto lab11;
2515       tfm_temp = getc(tfm_file);
2516       nl = nl * 256 + tfm_temp;
2517     }
2518     tfm_temp = getc(tfm_file);
2519     {
2520       nk = tfm_temp;
2521       if (nk > 127)
2522         goto lab11;
2523       tfm_temp = getc(tfm_file);
2524       nk = nk * 256 + tfm_temp;
2525     }
2526     tfm_temp = getc(tfm_file);
2527     {
2528       ne = tfm_temp;
2529       if (ne > 127)
2530         goto lab11;
2531       tfm_temp = getc(tfm_file);
2532       ne = ne * 256 + tfm_temp;
2533     }
2534     tfm_temp = getc(tfm_file);
2535     {
2536       np = tfm_temp;
2537       if (np > 127)
2538         goto lab11;
2539       tfm_temp = getc(tfm_file);
2540       np = np * 256 + tfm_temp;
2541     }
2542     if (lf != 6 + lh + (ec - bc + 1) + nw + nh + nd + ni + nl + nk + ne + np)
2543       goto lab11;
2544
2545     if ((nw == 0) || (nh == 0) || (nd == 0) || (ni == 0))
2546       goto lab11;
2547   }
2548
2549   lf = lf - 6 - lh;
2550
2551   if (np < 7)
2552     lf = lf + 7 - np;
2553 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2554 #ifdef ALLOCATEFONT
2555   if ((fmem_ptr + lf > current_font_mem_size))   /* 93/Nov/28 */
2556     font_info = realloc_font_info (increment_font_mem_size + lf);
2557
2558   if ((font_ptr == font_max) || (fmem_ptr + lf > current_font_mem_size))
2559 #else
2560   if ((font_ptr == font_max) || (fmem_ptr + lf > font_mem_size))
2561 #endif
2562   {
2563     if (trace_flag)
2564     {
2565       sprintf(log_line, "font_ptr %d font_max %d fmem_ptr %d lf %d font_mem_size %d\n",
2566           font_ptr, font_max, fmem_ptr, lf, font_mem_size); /* debugging */
2567       show_line(log_line, 0);
2568     }
2569
2570     print_err("Font ");
2571     sprint_cs(u);
2572     print_char('=');
2573     print_file_name(nom, aire, 335); /* "" */
2574
2575     if (s >= 0)
2576     {
2577       print_string(" at ");
2578       print_scaled(s);
2579       print_string("pt");
2580     }
2581     else if (s != -1000)
2582     {
2583       print_string(" scaled ");
2584       print_int(- (integer) s);
2585     }
2586
2587     print_string(" not loaded: Not enough room left");
2588     help4("I'm afraid I won't be able to make use of this font,",
2589         "because my memory for character-size data is too small.",
2590         "If you're really stuck, ask a wizard to enlarge me.",
2591         "Or maybe try `I\\font<same font id>=<name of loaded font>'.");
2592     error();
2593     goto lab30;
2594   }
2595
2596   f = font_ptr + 1;
2597   char_base[f] = fmem_ptr - bc;
2598   width_base[f] = char_base[f] + ec + 1;
2599   height_base[f] = width_base[f] + nw;
2600   depth_base[f] = height_base[f] + nh;
2601   italic_base[f] = depth_base[f] + nd;
2602   lig_kern_base[f] = italic_base[f] + ni;
2603   kern_base[f] = lig_kern_base[f] + nl - 256 * (128);
2604   exten_base[f] = kern_base[f] + 256 * (128) + nk;
2605   param_base[f] = exten_base[f] + ne;
2606
2607   {
2608     if (lh < 2)
2609       goto lab11;
2610 /*  build the font checksum now */
2611     {
2612       tfm_temp = getc(tfm_file);
2613       a = tfm_temp;
2614       qw.b0 = a;
2615       tfm_temp = getc(tfm_file);
2616       b = tfm_temp;
2617       qw.b1 = b;
2618       tfm_temp = getc(tfm_file);
2619       c = tfm_temp;
2620       qw.b2 = c;
2621       tfm_temp = getc(tfm_file);
2622       d = tfm_temp;
2623       qw.b3 = d;
2624       font_check[f] = qw;
2625     }
2626
2627     tfm_temp = getc(tfm_file);
2628     {
2629       z = tfm_temp;
2630       if (z > 127)
2631         goto lab11;
2632       tfm_temp = getc(tfm_file);
2633       z = z * 256 + tfm_temp;
2634     }
2635
2636     tfm_temp = getc(tfm_file);
2637     z = z * 256 + tfm_temp;
2638     tfm_temp = getc(tfm_file);
2639     z =(z * 16) + (tfm_temp / 16);
2640
2641     if (z < 65536L)
2642       goto lab11; 
2643
2644     while (lh > 2)
2645     {
2646       tfm_temp = getc(tfm_file);
2647       tfm_temp = getc(tfm_file);
2648       tfm_temp = getc(tfm_file);
2649       tfm_temp = getc(tfm_file);
2650       decr(lh);
2651     }
2652
2653     font_dsize[f] = z;
2654
2655     if (s != -1000)
2656       if (s >= 0)
2657         z = s;
2658       else
2659         z = xn_over_d(z, - (integer) s, 1000);
2660
2661     font_size[f] = z;
2662   }
2663
2664   for (k = fmem_ptr; k <= width_base[f] - 1; k++)
2665   {
2666     {
2667       tfm_temp = getc(tfm_file);
2668       a = tfm_temp;
2669       qw.b0 = a;
2670       tfm_temp = getc(tfm_file);
2671       b = tfm_temp;
2672       qw.b1 = b;
2673       tfm_temp = getc(tfm_file);
2674       c = tfm_temp;
2675       qw.b2 = c;
2676       tfm_temp = getc(tfm_file);
2677       d = tfm_temp;
2678       qw.b3 = d;
2679       font_info[k].qqqq = qw;
2680     }
2681
2682     if ((a >= nw) || (b / 16 >= nh) || (b % 16 >= nd) || (c / 4 >= ni))
2683       goto lab11;
2684
2685     switch (c % 4)
2686     {
2687       case 1 :
2688         if (d >= nl)
2689           goto lab11;
2690         break;
2691
2692       case 3 :
2693         if (d >= ne)
2694           goto lab11;
2695         break;
2696
2697       case 2 :
2698         {
2699           {
2700             if ((d < bc)||(d > ec))
2701               goto lab11;
2702           }
2703
2704           while (d < k + bc - fmem_ptr)
2705           {
2706             qw = font_info[char_base[f]+ d].qqqq;
2707  
2708             if (((qw.b2)% 4)!= 2)
2709               goto lab45;
2710
2711             d = qw.b3;
2712           }
2713
2714           if (d == k + bc - fmem_ptr)
2715             goto lab11;
2716 lab45:; 
2717         }
2718         break;
2719
2720       default:
2721         break;
2722     }
2723   }
2724   {
2725     {
2726       alpha = 16;
2727
2728       while (z >= 8388608L)   /* 2^23 */
2729       {
2730         z = z / 2;
2731         alpha = alpha + alpha;
2732       }
2733
2734       beta = (char) (256 / alpha);
2735       alpha = alpha * z;
2736     }
2737
2738     for (k = width_base[f]; k <= lig_kern_base[f] - 1; k++)
2739     {
2740       tfm_temp = getc(tfm_file);
2741       a = tfm_temp;
2742       tfm_temp = getc(tfm_file);
2743       b = tfm_temp;
2744       tfm_temp = getc(tfm_file);
2745       c = tfm_temp;
2746       tfm_temp = getc(tfm_file);
2747       d = tfm_temp;
2748       sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2749
2750       if (a == 0)
2751         font_info[k].cint = sw;
2752       else if (a == 255)
2753         font_info[k].cint = sw - alpha;
2754       else
2755         goto lab11;
2756     }
2757
2758     if (font_info[width_base[f]].cint != 0)
2759       goto lab11;
2760
2761     if (font_info[height_base[f]].cint != 0)
2762       goto lab11;
2763
2764     if (font_info[depth_base[f]].cint != 0)
2765       goto lab11;
2766
2767     if (font_info[italic_base[f]].cint != 0)
2768       goto lab11;
2769   }
2770 /*  read ligature/kern program */
2771   bchlabel = 32767;     /* '77777 */
2772   bchar = 256;
2773
2774   if (nl > 0)
2775   {
2776     for (k = lig_kern_base[f]; k <= kern_base[f] + 256 * (128) - 1; k++)
2777     {
2778       {
2779         tfm_temp = getc(tfm_file);
2780         a = tfm_temp;
2781         qw.b0 = a;
2782         tfm_temp = getc(tfm_file);
2783         b = tfm_temp;
2784         qw.b1 = b;
2785         tfm_temp = getc(tfm_file);
2786         c = tfm_temp;
2787         qw.b2 = c;
2788         tfm_temp = getc(tfm_file);
2789         d = tfm_temp;
2790         qw.b3 = d;
2791         font_info[k].qqqq = qw; /* store_four_quarters(font_info[k].qqqq */
2792       }
2793
2794       if (a > 128)
2795       {
2796         if (256 * c + d >= nl)
2797           goto lab11;       /* error in TFM, abort */
2798
2799         if (a == 255)
2800           if (k == lig_kern_base[f])
2801             bchar = b;
2802       }
2803       else
2804       {
2805         if (b != bchar)
2806         {
2807           {
2808             if ((b < bc) || (b > ec))  /* check-existence(b) */
2809               goto lab11;         /* error in TFM, abort */
2810           }
2811
2812           qw = font_info[char_base[f] + b].qqqq;
2813
2814           if (!(qw.b0 > 0))
2815             goto lab11;         /* error in TFM, abort */
2816         }
2817
2818         if (c < 128)
2819         {
2820           {
2821             if ((d < bc) || (d > ec))  /* check-existence(d) */
2822               goto lab11;         /* error in TFM, abort */
2823           }
2824
2825           qw = font_info[char_base[f] + d].qqqq;
2826
2827           if (!(qw.b0 > 0))
2828             goto lab11;         /* error in TFM, abort */
2829         }
2830         else if (256 * (c - 128) + d >= nk)
2831           goto lab11;           /* error in TFM, abort */
2832         if (a < 128)
2833           if (k - lig_kern_base[f] + a + 1 >= nl)
2834             goto lab11;         /* error in TFM, abort */
2835       }
2836     }
2837
2838     if (a == 255)
2839       bchlabel = 256 * c + d;
2840   }
2841
2842   for (k = kern_base[f] + 256 * (128); k <= exten_base[f] - 1; k++)
2843   {
2844     tfm_temp = getc(tfm_file);
2845     a = tfm_temp;
2846     tfm_temp = getc(tfm_file);
2847     b = tfm_temp;
2848     tfm_temp = getc(tfm_file);
2849     c = tfm_temp;
2850     tfm_temp = getc(tfm_file);
2851     d = tfm_temp;
2852     sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2853
2854     if (a == 0)
2855       font_info[k].cint = sw;
2856     else if (a == 255)
2857       font_info[k].cint = sw - alpha;
2858     else goto lab11;
2859   }
2860 /*  read extensible character recipes */
2861 /*  for k:=exten_base[f] to param_base[f]-1 do */
2862   for (k = exten_base[f]; k <= param_base[f] - 1; k++)
2863   {
2864     {
2865       tfm_temp = getc(tfm_file);
2866       a = tfm_temp;
2867       qw.b0 = a;
2868       tfm_temp = getc(tfm_file);
2869       b = tfm_temp;
2870       qw.b1 = b;
2871       tfm_temp = getc(tfm_file);
2872       c = tfm_temp;
2873       qw.b2 = c;
2874       tfm_temp = getc(tfm_file);
2875       d = tfm_temp;
2876       qw.b3 = d;
2877 /*    store_four_quarters(font_info[k].qqqq); */
2878       font_info[k].qqqq = qw;
2879     }
2880
2881     if (a != 0)
2882     {
2883       {
2884         if ((a < bc) || (a > ec))
2885           goto lab11;
2886       }
2887
2888       qw = font_info[char_base[f] + a].qqqq;
2889
2890       if (!(qw.b0 > 0))
2891         goto lab11;
2892     }
2893
2894     if (b != 0)
2895     {
2896       {
2897         if ((b < bc) || (b > ec))
2898           goto lab11;
2899       }
2900
2901       qw = font_info[char_base[f] + b].qqqq;
2902
2903       if (!(qw.b0 > 0))
2904         goto lab11;
2905     }
2906
2907     if (c != 0)
2908     {
2909       {
2910         if ((c < bc) || (c > ec))
2911           goto lab11;
2912       }
2913
2914       qw = font_info[char_base[f] + c].qqqq;
2915
2916       if (!(qw.b0 > 0))
2917         goto lab11;
2918     }
2919     {
2920       {
2921         if ((d < bc) || (d > ec))
2922           goto lab11;
2923       }
2924
2925       qw = font_info[char_base[f] + d].qqqq;
2926
2927       if (!(qw.b0 > 0))
2928         goto lab11;
2929     }
2930   }
2931   {
2932     for (k = 1; k <= np; k++)
2933       if (k == 1)
2934       {
2935         tfm_temp = getc(tfm_file);
2936         sw = tfm_temp;
2937
2938         if (sw > 127)
2939           sw = sw - 256;
2940
2941         tfm_temp = getc(tfm_file);
2942         sw = sw * 256 + tfm_temp;
2943         tfm_temp = getc(tfm_file);
2944         sw = sw * 256 + tfm_temp;
2945         tfm_temp = getc(tfm_file);
2946         font_info[param_base[f]].cint = (sw * 16) + (tfm_temp / 16);
2947       }
2948       else
2949       {
2950         tfm_temp = getc(tfm_file);
2951         a = tfm_temp;
2952         tfm_temp = getc(tfm_file);
2953         b = tfm_temp;
2954         tfm_temp = getc(tfm_file);
2955         c = tfm_temp;
2956         tfm_temp = getc(tfm_file);
2957         d = tfm_temp;
2958         sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2959
2960         if (a == 0)
2961           font_info[param_base[f] + k - 1].cint = sw;
2962         else if (a == 255)
2963           font_info[param_base[f] + k - 1].cint = sw - alpha;
2964         else goto lab11;
2965       }
2966
2967     if (feof(tfm_file))
2968       goto lab11;
2969
2970     for (k = np + 1; k <= 7; k++)
2971       font_info[param_base[f] + k - 1].cint = 0;
2972   }
2973
2974   if (np >= 7)
2975     font_params[f] = np;
2976   else
2977     font_params[f] = 7;
2978
2979   hyphen_char[f] = default_hyphen_char;
2980   skew_char[f] = default_skew_char;
2981
2982   if (bchlabel < nl)
2983     bchar_label[f] = bchlabel + lig_kern_base[f];
2984   else
2985     bchar_label[f] = non_address;
2986
2987   font_bchar[f] = bchar;
2988   font_false_bchar[f] = bchar;
2989
2990   if (bchar <= ec)
2991     if (bchar >= bc)
2992     {
2993       qw = font_info[char_base[f] + bchar].qqqq;
2994
2995       if ((qw.b0 > 0))
2996         font_false_bchar[f] = 256;
2997     }
2998
2999   font_name[f] = nom;
3000   font_area[f] = aire;
3001   font_bc[f] = bc;
3002   font_ec[f] = ec;
3003   font_glue[f] = 0;
3004   char_base[f] = char_base[f];
3005   width_base[f] = width_base[f];
3006   lig_kern_base[f] = lig_kern_base[f];
3007   kern_base[f] = kern_base[f];
3008   exten_base[f] = exten_base[f];
3009   decr(param_base[f]);
3010   fmem_ptr = fmem_ptr + lf;
3011   font_ptr = f;
3012   g = f;
3013   goto lab30;
3014
3015 lab11:
3016   print_err("Font ");
3017   sprint_cs(u); 
3018   print_char('=');
3019   print_file_name(nom, aire, 335);
3020
3021   if (s >= 0)
3022   {
3023     print_string(" at ");
3024     print_scaled(s);
3025     print_string("pt");
3026   }
3027   else if (s != -1000)
3028   {
3029     print_string("scaled");
3030     print_int(- (integer) s);
3031   } 
3032
3033   if (fileopened)
3034     print_string(" not loadable: Bad metric (TFM) file");
3035   else
3036     print_string(" not loadable: Metric (TFM) file not found");
3037
3038   if (aire == 335)
3039   {
3040     if (show_texinput_flag)
3041       show_tex_fonts();
3042   }
3043
3044   help5("I wasn't able to read the size data for this font,",
3045       "so I will ignore the font specification.",
3046       "[Wizards can fix TFM files using TFtoPL/PLtoTF.]",
3047       "You might try inserting a different font spec;",
3048       "e.g., type `I\\font<same font id>=<substitute font name>'.");
3049   error();
3050
3051 lab30:
3052   if (fileopened)
3053     b_close(tfm_file);
3054
3055   return g;
3056 }