OSDN Git Service

modified some WINDOWS-only codes.
[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;   /* default:  texput */
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 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2137   if (want_version)
2138   {
2139     stamp_it(log_line);         // ??? use log_line ???
2140     strcat(log_line, "\n");
2141     (void) fputs(log_line, log_file);
2142     stampcopy(log_line);
2143     strcat(log_line, "\n");
2144     (void) fputs(log_line, log_file);
2145   }
2146 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2147 /*  also change following in itex.c - bkph */
2148   (void) fputs(tex_version, log_file); 
2149   (void) fprintf(log_file, " (%s %s)", application, yandyversion);
2150
2151   if (format_ident > 0)
2152     slow_print(format_ident);     /* bkph */
2153
2154   print_string("  ");
2155 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2156   if (civilize_flag)
2157     print_int(year);
2158   else
2159     print_int(day);
2160 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2161     print_char(' ');
2162     months = " JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
2163
2164     for (k = 3 * month - 2; k <= 3 * month; k++)
2165       (void) putc(months[k],  log_file);
2166
2167     print_char(' ');
2168 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2169     if (civilize_flag)
2170       print_int(day);
2171     else
2172       print_int(year);
2173 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2174     print_char(' ');
2175     print_two(tex_time / 60);  /* hour */
2176     print_char(':');
2177     print_two(tex_time % 60);  /* minute */
2178   }
2179
2180   input_stack[input_ptr] = cur_input;
2181   print_nl("**");
2182   l = input_stack[0].limit_field;
2183
2184   if (buffer[l] == end_line_char)
2185     decr(l);
2186
2187   for (k = 1; k <= l; k++)
2188     print(buffer[k]);
2189
2190   print_ln(); 
2191 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2192 /* a good place to show the fmt file name or pool file name ? 94/June/21 */
2193   if (show_fmt_flag)
2194   {
2195     if (string_file != NULL)
2196     {
2197       fprintf(log_file, "(%s)\n", string_file);
2198       free(string_file);  /* this was allocated by strdup in openinou */
2199       string_file = NULL;   /* for safety */
2200     }
2201
2202     if (format_file != NULL)
2203     {
2204       fprintf(log_file, "(%s)\n", format_file);
2205       free(format_file);  /* this was allocated by strdup in openinou */
2206       format_file = NULL;   /* for safety */
2207     }
2208   }
2209 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2210   selector = old_setting + 2;
2211 }
2212
2213 /**************************** start of insertion 98/Feb/7 **************/
2214
2215 // Attempt to deal with foo.bar.tex given as foo.bar on command line
2216 // Makes copy of job_name with extension
2217
2218 void morenamecopy(ASCII_code c)
2219 {
2220 #ifdef ALLOCATESTRING
2221   if (pool_ptr + 1 > current_pool_size)
2222     str_pool = realloc_str_pool (increment_pool_size);
2223
2224   if (pool_ptr + 1 > current_pool_size) /* in case it failed 94/Jan/24 */
2225   {
2226     overflow("pool size", current_pool_size - init_pool_ptr); /* 97/Mar/7 */
2227     return;     // abort_flag set
2228   }
2229 #else
2230   if (pool_ptr + 1 > pool_size)
2231   {
2232     overflow("pool size", pool_size - init_pool_ptr); /* pool size */
2233     return;     // abort_flag set
2234   }
2235 #endif
2236   str_pool[pool_ptr] = c; 
2237   incr(pool_ptr);
2238 }
2239
2240 int endnamecopy(void)
2241 {
2242 #ifdef ALLOCATESTRING
2243     if (str_ptr + 1 > current_max_strings)
2244       str_start = realloc_str_start(increment_max_strings + 1);
2245
2246     if (str_ptr + 1 > current_max_strings) /* in case it failed 94/Jan/24 */
2247     {
2248       overflow("number of strings", current_max_strings - init_str_ptr);  /* 97/Mar/7 */
2249       return 0;     // abort_flag set
2250     }
2251 #else
2252     if (str_ptr + 1 > max_strings)
2253     {
2254       overflow("number of strings", max_strings - init_str_ptr); /* number of strings */
2255       return 0;     // abort_flag set
2256     }
2257 #endif
2258     return make_string();
2259 }
2260
2261 /* add extension to job_name */
2262 void jobnameappend (void)
2263
2264   int k, n;
2265 /*  copy job_name */
2266   k = str_start[job_name];
2267   n = str_start[job_name + 1];
2268
2269   while (k < n)
2270     morenamecopy(str_pool[k++]);
2271 /*  copy `extension' */
2272   k = str_start[cur_ext];
2273   n = str_start[cur_ext + 1];
2274
2275   while (k < n)
2276     morenamecopy(str_pool[k++]);
2277
2278   job_name = endnamecopy();
2279 }
2280
2281 /**************************** end of insertion 98/Feb/7 **************/
2282 /* sec 0537 */
2283 void start_input (void)
2284 {
2285   bool addedextension = false;
2286
2287   scan_file_name();
2288   pack_file_name(cur_name, cur_area, cur_ext); 
2289
2290   while (true)        /* loop until we get a valid file name */
2291   {
2292     addedextension = false;
2293     begin_file_reading(); 
2294 /* *** *** *** *** *** following is new in 3.14159 *** *** *** *** *** *** */
2295 /*  if current extension is *not* empty, try to open using name as is */
2296 /*  string 335 is "" the empty string */
2297 /*  should be updated to current Kpathsea. */
2298     if ((cur_ext != 335) && a_open_in(input_file[cur_input.index_field], TEXINPUTPATH))
2299       goto lab30;
2300 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2301 /*  we get here if extension is "", or file with extension failed to open */
2302 /*  if current extension is not `tex,' and `tex' is not irrelevant, try it */
2303 /*  string 785 is .tex */
2304     if ((cur_ext != 785) && (name_length + 5 < PATHMAX))
2305     {
2306       //strcpy(name_of_file + name_length + 1, ".tex ");
2307       name_of_file[name_length + 1] = '.';
2308       name_of_file[name_length + 2] = 't';
2309       name_of_file[name_length + 3] = 'e';
2310       name_of_file[name_length + 4] = 'x';
2311       name_of_file[name_length + 5] = ' ';
2312       name_length = name_length + 4;
2313
2314       addedextension = true;
2315
2316       if (a_open_in(input_file[cur_input.index_field], TEXINPUTPATH))
2317         goto lab30;
2318
2319       name_length = name_length - 4;      /* strip extension again */
2320       name_of_file[name_length + 1] = ' ';  /* ' ' */
2321       addedextension = false;
2322 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2323     }
2324 /* *** *** *** *** major changes here in 3.14159 *** *** *** *** *** *** */
2325 /*  string 335 is "" the empty string */
2326     if ((cur_ext == 335) && a_open_in(input_file[cur_input.index_field], TEXINPUTPATH))
2327       goto lab30;
2328
2329 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2330     end_file_reading();
2331     prompt_file_name("input file name", ".tex");
2332   }   /* end of while(true)trying to get valid file name */
2333
2334 /* maybe set  pseudo_tilde = 0  at this point ? 95/Sep/26 */
2335 lab30: 
2336   cur_input.name_field = a_make_name_string(input_file[cur_input.index_field]);
2337
2338   if (job_name == 0)       /* only the first time */
2339   {
2340     job_name = cur_name;        /* here we set the job_name */
2341 /*  did file name have an `extension' already and we added ".tex" ? */
2342     if (cur_ext != 335 && addedextension)     /* 98/Feb/7 */
2343       jobnameappend();   /* append `extension' to job_name */
2344
2345     open_log_file();
2346   }
2347
2348   if (term_offset + length(cur_input.name_field) > max_print_line - 2) /* was 3 ? */
2349     print_ln();
2350   else if ((term_offset > 0) || (file_offset > 0))
2351     print_char(' ');
2352
2353   print_char('(');
2354 //  print_char('@');       // debugging only marker
2355   incr(open_parens);
2356
2357   if (open_parens > max_open_parens)
2358     max_open_parens = open_parens;    /* 1999/Jan/17 */
2359
2360   slow_print(cur_input.name_field);
2361 //  print_char('@');       // debugging only marker
2362 #ifndef _WINDOWS
2363   fflush(stdout);
2364 #endif
2365   cur_input.state_field = new_line;
2366
2367   {
2368     line = 1;
2369
2370     if (input_ln(input_file[cur_input.index_field], false));
2371
2372     firm_up_the_line();
2373
2374     if ((end_line_char < 0) || (end_line_char > 255))
2375       decr(cur_input.limit_field);
2376     else
2377       buffer[cur_input.limit_field] = end_line_char;
2378
2379     first = cur_input.limit_field + 1;
2380     cur_input.loc_field = cur_input.start_field;
2381   }
2382 }
2383
2384 /**********************************************************************/
2385 /* show TEXFONTS=... or format specific  */
2386 /* only show this if name was not fully qualified ? */
2387 void show_tex_fonts (void)
2388 {     /* 98/Jan/28 */
2389   char *s, *t, *v, *u;
2390   int n;
2391
2392   s = "TEXFONTS";
2393
2394   if (encoding_specific)
2395   {
2396     u = encoding_name;                /* try specific */
2397
2398     if ((t = grabenv(u)) != NULL)
2399     {
2400       if (strchr(t, ':') != NULL && sscanf(t, "%d", &n) == 0)
2401       {
2402         s = u;        /* look here instead of TEXFONTS=... */
2403       }
2404     }
2405   }
2406
2407   print_nl("  ");
2408   print_char(' ');
2409   print_char('(');
2410   t = s;
2411
2412   while (*t > '\0')
2413     print_char(*t++);
2414
2415   print_char('=');
2416   v = grabenv(s);
2417
2418   if (v != NULL)
2419   {
2420     t = v;
2421
2422     while (*t > '\0')
2423       print_char(*t++);
2424   }
2425
2426   print_char(')');
2427 }
2428
2429 /**********************************************************************/
2430 /* called only from tex8.c */
2431 /* sec 0560 */
2432 internal_font_number read_font_info_(halfword u, str_number nom, str_number aire, scaled s)
2433 {
2434   font_index k;
2435   bool fileopened;
2436 /*  halfword lf, lh, bc, ec, nw, nh, nd, ni, nl, nk, ne, np;  */
2437   halfword lf, lh, nw, nh, nd, ni, nl, nk, ne, np;
2438 /*  halfword bc, ec; */
2439   int bc, ec;             /* 95/Jan/7 */
2440   internal_font_number f;
2441   internal_font_number g;
2442   eight_bits a, b, c, d;
2443   ffourquarters qw;
2444   scaled sw;
2445   integer bchlabel;
2446   short bchar;
2447   scaled z;
2448   integer alpha;
2449   char beta;
2450
2451   g = 0;
2452   fileopened = false;
2453   pack_file_name(nom, aire, 805); /* .tfm */
2454
2455   if (!b_open_in(tfm_file)) /* new in C version d */
2456   {
2457     goto lab11;
2458   } 
2459 /*   was just: goto lab11; */
2460   fileopened = true; 
2461   {
2462 /*  tfm_temp = getc(tfm_file);  */ /* done already in open_input, but why? */
2463     //tfm_temp = getc(tfm_file);
2464     {
2465       lf = tfm_temp;
2466       if (lf > 127)
2467         goto lab11;
2468       tfm_temp = getc(tfm_file);
2469       lf = lf * 256 + tfm_temp;
2470     }
2471     tfm_temp = getc(tfm_file);
2472     {
2473       lh = tfm_temp;
2474       if (lh > 127)
2475         goto lab11;
2476       tfm_temp = getc(tfm_file);
2477       lh = lh * 256 + tfm_temp;
2478     }
2479     tfm_temp = getc(tfm_file);
2480     {
2481       bc = tfm_temp;
2482       if (bc > 127)
2483         goto lab11;
2484       tfm_temp = getc(tfm_file);
2485       bc = bc * 256 + tfm_temp;
2486     }
2487     tfm_temp = getc(tfm_file);
2488     {
2489       ec = tfm_temp;
2490       if (ec > 127)
2491         goto lab11;
2492       tfm_temp = getc(tfm_file);
2493       ec = ec * 256 + tfm_temp;
2494     }
2495     if ((bc > ec + 1)||(ec > 255))
2496       goto lab11;
2497     if (bc > 255)
2498     {
2499       bc = 1;
2500       ec = 0;
2501     }
2502     tfm_temp = getc(tfm_file);
2503     {
2504       nw = tfm_temp;
2505       if (nw > 127)
2506         goto lab11;
2507       tfm_temp = getc(tfm_file);
2508       nw = nw * 256 + tfm_temp;
2509     }
2510     tfm_temp = getc(tfm_file);
2511     {
2512       nh = tfm_temp;
2513       if (nh > 127)
2514         goto lab11;
2515       tfm_temp = getc(tfm_file);
2516       nh = nh * 256 + tfm_temp;
2517     }
2518     tfm_temp = getc(tfm_file);
2519     {
2520       nd = tfm_temp;
2521       if (nd > 127)
2522         goto lab11;
2523       tfm_temp = getc(tfm_file);
2524       nd = nd * 256 + tfm_temp;
2525     }
2526     tfm_temp = getc(tfm_file);
2527     {
2528       ni = tfm_temp;
2529       if (ni > 127)
2530         goto lab11;
2531       tfm_temp = getc(tfm_file);
2532       ni = ni * 256 + tfm_temp;
2533     }
2534     tfm_temp = getc(tfm_file);
2535     {
2536       nl = tfm_temp;
2537       if (nl > 127)
2538         goto lab11;
2539       tfm_temp = getc(tfm_file);
2540       nl = nl * 256 + tfm_temp;
2541     }
2542     tfm_temp = getc(tfm_file);
2543     {
2544       nk = tfm_temp;
2545       if (nk > 127)
2546         goto lab11;
2547       tfm_temp = getc(tfm_file);
2548       nk = nk * 256 + tfm_temp;
2549     }
2550     tfm_temp = getc(tfm_file);
2551     {
2552       ne = tfm_temp;
2553       if (ne > 127)
2554         goto lab11;
2555       tfm_temp = getc(tfm_file);
2556       ne = ne * 256 + tfm_temp;
2557     }
2558     tfm_temp = getc(tfm_file);
2559     {
2560       np = tfm_temp;
2561       if (np > 127)
2562         goto lab11;
2563       tfm_temp = getc(tfm_file);
2564       np = np * 256 + tfm_temp;
2565     }
2566     if (lf != 6 + lh + (ec - bc + 1) + nw + nh + nd + ni + nl + nk + ne + np)
2567       goto lab11;
2568
2569     if ((nw == 0) || (nh == 0) || (nd == 0) || (ni == 0))
2570       goto lab11;
2571   }
2572
2573   lf = lf - 6 - lh;
2574
2575   if (np < 7)
2576     lf = lf + 7 - np;
2577 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2578 #ifdef ALLOCATEFONT
2579   if ((fmem_ptr + lf > current_font_mem_size))   /* 93/Nov/28 */
2580     font_info = realloc_font_info (increment_font_mem_size + lf);
2581
2582   if ((font_ptr == font_max) || (fmem_ptr + lf > current_font_mem_size))
2583 #else
2584   if ((font_ptr == font_max) || (fmem_ptr + lf > font_mem_size))
2585 #endif
2586   {
2587     if (trace_flag)
2588     {
2589       sprintf(log_line, "font_ptr %d font_max %d fmem_ptr %d lf %d font_mem_size %d\n",
2590           font_ptr, font_max, fmem_ptr, lf, font_mem_size); /* debugging */
2591       show_line(log_line, 0);
2592     }
2593
2594     print_err("Font ");
2595     sprint_cs(u);
2596     print_char('=');
2597     print_file_name(nom, aire, 335); /* "" */
2598
2599     if (s >= 0)
2600     {
2601       print_string(" at ");
2602       print_scaled(s);
2603       print_string("pt");
2604     }
2605     else if (s != -1000)
2606     {
2607       print_string(" scaled ");
2608       print_int(- (integer) s);
2609     }
2610
2611     print_string(" not loaded: Not enough room left");
2612     help4("I'm afraid I won't be able to make use of this font,",
2613         "because my memory for character-size data is too small.",
2614         "If you're really stuck, ask a wizard to enlarge me.",
2615         "Or maybe try `I\\font<same font id>=<name of loaded font>'.");
2616     error();
2617     goto lab30;
2618   }
2619
2620   f = font_ptr + 1;
2621   char_base[f] = fmem_ptr - bc;
2622   width_base[f] = char_base[f] + ec + 1;
2623   height_base[f] = width_base[f] + nw;
2624   depth_base[f] = height_base[f] + nh;
2625   italic_base[f] = depth_base[f] + nd;
2626   lig_kern_base[f] = italic_base[f] + ni;
2627   kern_base[f] = lig_kern_base[f] + nl - 256 * (128);
2628   exten_base[f] = kern_base[f] + 256 * (128) + nk;
2629   param_base[f] = exten_base[f] + ne;
2630
2631   {
2632     if (lh < 2)
2633       goto lab11;
2634 /*  build the font checksum now */
2635     {
2636       tfm_temp = getc(tfm_file);
2637       a = tfm_temp;
2638       qw.b0 = a;
2639       tfm_temp = getc(tfm_file);
2640       b = tfm_temp;
2641       qw.b1 = b;
2642       tfm_temp = getc(tfm_file);
2643       c = tfm_temp;
2644       qw.b2 = c;
2645       tfm_temp = getc(tfm_file);
2646       d = tfm_temp;
2647       qw.b3 = d;
2648       font_check[f] = qw;
2649     }
2650
2651     tfm_temp = getc(tfm_file);
2652     {
2653       z = tfm_temp;
2654       if (z > 127)
2655         goto lab11;
2656       tfm_temp = getc(tfm_file);
2657       z = z * 256 + tfm_temp;
2658     }
2659
2660     tfm_temp = getc(tfm_file);
2661     z = z * 256 + tfm_temp;
2662     tfm_temp = getc(tfm_file);
2663     z =(z * 16) + (tfm_temp / 16);
2664
2665     if (z < 65536L)
2666       goto lab11; 
2667
2668     while (lh > 2)
2669     {
2670       tfm_temp = getc(tfm_file);
2671       tfm_temp = getc(tfm_file);
2672       tfm_temp = getc(tfm_file);
2673       tfm_temp = getc(tfm_file);
2674       decr(lh);
2675     }
2676
2677     font_dsize[f] = z;
2678
2679     if (s != -1000)
2680       if (s >= 0)
2681         z = s;
2682       else
2683         z = xn_over_d(z, - (integer) s, 1000);
2684
2685     font_size[f] = z;
2686   }
2687
2688   for (k = fmem_ptr; k <= width_base[f] - 1; k++)
2689   {
2690     {
2691       tfm_temp = getc(tfm_file);
2692       a = tfm_temp;
2693       qw.b0 = a;
2694       tfm_temp = getc(tfm_file);
2695       b = tfm_temp;
2696       qw.b1 = b;
2697       tfm_temp = getc(tfm_file);
2698       c = tfm_temp;
2699       qw.b2 = c;
2700       tfm_temp = getc(tfm_file);
2701       d = tfm_temp;
2702       qw.b3 = d;
2703       font_info[k].qqqq = qw;
2704     }
2705
2706     if ((a >= nw) || (b / 16 >= nh) || (b % 16 >= nd) || (c / 4 >= ni))
2707       goto lab11;
2708
2709     switch (c % 4)
2710     {
2711       case 1 :
2712         if (d >= nl)
2713           goto lab11;
2714         break;
2715
2716       case 3 :
2717         if (d >= ne)
2718           goto lab11;
2719         break;
2720
2721       case 2 :
2722         {
2723           {
2724             if ((d < bc)||(d > ec))
2725               goto lab11;
2726           }
2727
2728           while (d < k + bc - fmem_ptr)
2729           {
2730             qw = font_info[char_base[f]+ d].qqqq;
2731  
2732             if (((qw.b2)% 4)!= 2)
2733               goto lab45;
2734
2735             d = qw.b3;
2736           }
2737
2738           if (d == k + bc - fmem_ptr)
2739             goto lab11;
2740 lab45:; 
2741         }
2742         break;
2743
2744       default:
2745         break;
2746     }
2747   }
2748   {
2749     {
2750       alpha = 16;
2751
2752       while (z >= 8388608L)   /* 2^23 */
2753       {
2754         z = z / 2;
2755         alpha = alpha + alpha;
2756       }
2757
2758       beta = (char) (256 / alpha);
2759       alpha = alpha * z;
2760     }
2761
2762     for (k = width_base[f]; k <= lig_kern_base[f] - 1; k++)
2763     {
2764       tfm_temp = getc(tfm_file);
2765       a = tfm_temp;
2766       tfm_temp = getc(tfm_file);
2767       b = tfm_temp;
2768       tfm_temp = getc(tfm_file);
2769       c = tfm_temp;
2770       tfm_temp = getc(tfm_file);
2771       d = tfm_temp;
2772       sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2773
2774       if (a == 0)
2775         font_info[k].cint = sw;
2776       else if (a == 255)
2777         font_info[k].cint = sw - alpha;
2778       else
2779         goto lab11;
2780     }
2781
2782     if (font_info[width_base[f]].cint != 0)
2783       goto lab11;
2784
2785     if (font_info[height_base[f]].cint != 0)
2786       goto lab11;
2787
2788     if (font_info[depth_base[f]].cint != 0)
2789       goto lab11;
2790
2791     if (font_info[italic_base[f]].cint != 0)
2792       goto lab11;
2793   }
2794 /*  read ligature/kern program */
2795   bchlabel = 32767;     /* '77777 */
2796   bchar = 256;
2797
2798   if (nl > 0)
2799   {
2800     for (k = lig_kern_base[f]; k <= kern_base[f] + 256 * (128) - 1; k++)
2801     {
2802       {
2803         tfm_temp = getc(tfm_file);
2804         a = tfm_temp;
2805         qw.b0 = a;
2806         tfm_temp = getc(tfm_file);
2807         b = tfm_temp;
2808         qw.b1 = b;
2809         tfm_temp = getc(tfm_file);
2810         c = tfm_temp;
2811         qw.b2 = c;
2812         tfm_temp = getc(tfm_file);
2813         d = tfm_temp;
2814         qw.b3 = d;
2815         font_info[k].qqqq = qw; /* store_four_quarters(font_info[k].qqqq */
2816       }
2817
2818       if (a > 128)
2819       {
2820         if (256 * c + d >= nl)
2821           goto lab11;       /* error in TFM, abort */
2822
2823         if (a == 255)
2824           if (k == lig_kern_base[f])
2825             bchar = b;
2826       }
2827       else
2828       {
2829         if (b != bchar)
2830         {
2831           {
2832             if ((b < bc) || (b > ec))  /* check-existence(b) */
2833               goto lab11;         /* error in TFM, abort */
2834           }
2835
2836           qw = font_info[char_base[f] + b].qqqq;
2837
2838           if (!(qw.b0 > 0))
2839             goto lab11;         /* error in TFM, abort */
2840         }
2841
2842         if (c < 128)
2843         {
2844           {
2845             if ((d < bc) || (d > ec))  /* check-existence(d) */
2846               goto lab11;         /* error in TFM, abort */
2847           }
2848
2849           qw = font_info[char_base[f] + d].qqqq;
2850
2851           if (!(qw.b0 > 0))
2852             goto lab11;         /* error in TFM, abort */
2853         }
2854         else if (256 * (c - 128) + d >= nk)
2855           goto lab11;           /* error in TFM, abort */
2856         if (a < 128)
2857           if (k - lig_kern_base[f] + a + 1 >= nl)
2858             goto lab11;         /* error in TFM, abort */
2859       }
2860     }
2861
2862     if (a == 255)
2863       bchlabel = 256 * c + d;
2864   }
2865
2866   for (k = kern_base[f] + 256 * (128); k <= exten_base[f] - 1; k++)
2867   {
2868     tfm_temp = getc(tfm_file);
2869     a = tfm_temp;
2870     tfm_temp = getc(tfm_file);
2871     b = tfm_temp;
2872     tfm_temp = getc(tfm_file);
2873     c = tfm_temp;
2874     tfm_temp = getc(tfm_file);
2875     d = tfm_temp;
2876     sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2877
2878     if (a == 0)
2879       font_info[k].cint = sw;
2880     else if (a == 255)
2881       font_info[k].cint = sw - alpha;
2882     else goto lab11;
2883   }
2884 /*  read extensible character recipes */
2885 /*  for k:=exten_base[f] to param_base[f]-1 do */
2886   for (k = exten_base[f]; k <= param_base[f] - 1; k++)
2887   {
2888     {
2889       tfm_temp = getc(tfm_file);
2890       a = tfm_temp;
2891       qw.b0 = a;
2892       tfm_temp = getc(tfm_file);
2893       b = tfm_temp;
2894       qw.b1 = b;
2895       tfm_temp = getc(tfm_file);
2896       c = tfm_temp;
2897       qw.b2 = c;
2898       tfm_temp = getc(tfm_file);
2899       d = tfm_temp;
2900       qw.b3 = d;
2901 /*    store_four_quarters(font_info[k].qqqq); */
2902       font_info[k].qqqq = qw;
2903     }
2904
2905     if (a != 0)
2906     {
2907       {
2908         if ((a < bc) || (a > ec))
2909           goto lab11;
2910       }
2911
2912       qw = font_info[char_base[f] + a].qqqq;
2913
2914       if (!(qw.b0 > 0))
2915         goto lab11;
2916     }
2917
2918     if (b != 0)
2919     {
2920       {
2921         if ((b < bc) || (b > ec))
2922           goto lab11;
2923       }
2924
2925       qw = font_info[char_base[f] + b].qqqq;
2926
2927       if (!(qw.b0 > 0))
2928         goto lab11;
2929     }
2930
2931     if (c != 0)
2932     {
2933       {
2934         if ((c < bc) || (c > ec))
2935           goto lab11;
2936       }
2937
2938       qw = font_info[char_base[f] + c].qqqq;
2939
2940       if (!(qw.b0 > 0))
2941         goto lab11;
2942     }
2943     {
2944       {
2945         if ((d < bc) || (d > ec))
2946           goto lab11;
2947       }
2948
2949       qw = font_info[char_base[f] + d].qqqq;
2950
2951       if (!(qw.b0 > 0))
2952         goto lab11;
2953     }
2954   }
2955   {
2956     for (k = 1; k <= np; k++)
2957       if (k == 1)
2958       {
2959         tfm_temp = getc(tfm_file);
2960         sw = tfm_temp;
2961
2962         if (sw > 127)
2963           sw = sw - 256;
2964
2965         tfm_temp = getc(tfm_file);
2966         sw = sw * 256 + tfm_temp;
2967         tfm_temp = getc(tfm_file);
2968         sw = sw * 256 + tfm_temp;
2969         tfm_temp = getc(tfm_file);
2970         font_info[param_base[f]].cint = (sw * 16) + (tfm_temp / 16);
2971       }
2972       else
2973       {
2974         tfm_temp = getc(tfm_file);
2975         a = tfm_temp;
2976         tfm_temp = getc(tfm_file);
2977         b = tfm_temp;
2978         tfm_temp = getc(tfm_file);
2979         c = tfm_temp;
2980         tfm_temp = getc(tfm_file);
2981         d = tfm_temp;
2982         sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2983
2984         if (a == 0)
2985           font_info[param_base[f] + k - 1].cint = sw;
2986         else if (a == 255)
2987           font_info[param_base[f] + k - 1].cint = sw - alpha;
2988         else goto lab11;
2989       }
2990 /*  use test_eof() here instead ? */
2991     if (feof(tfm_file))
2992       goto lab11;
2993
2994     for (k = np + 1; k <= 7; k++)
2995       font_info[param_base[f] + k - 1].cint = 0;
2996   }
2997 /* @<Make final adjustments...@>= l.11174 */
2998   if (np >= 7)
2999     font_params[f] = np;
3000   else
3001     font_params[f] = 7;
3002
3003   hyphen_char[f] = default_hyphen_char;
3004   skew_char[f] = default_skew_char;
3005
3006   if (bchlabel < nl)
3007     bchar_label[f] = bchlabel + lig_kern_base[f];
3008   else
3009     bchar_label[f]= non_address; /* i.e. 0 --- 96/Jan/15 */
3010
3011   font_bchar[f] = bchar;
3012   font_false_bchar[f] = bchar;
3013
3014   if (bchar <= ec)
3015     if (bchar >= bc)
3016     {
3017       qw = font_info[char_base[f] + bchar].qqqq;
3018
3019       if ((qw.b0 > 0))
3020         font_false_bchar[f] = 256;
3021     }
3022
3023   font_name[f] = nom;
3024   font_area[f] = aire;
3025   font_bc[f] = bc;
3026   font_ec[f] = ec;
3027   font_glue[f] = 0;  /* font_glue[f]:=null; l.11184 */
3028   char_base[f] = char_base[f];
3029   width_base[f] = width_base[f];
3030   lig_kern_base[f] = lig_kern_base[f];
3031   kern_base[f] = kern_base[f];
3032   exten_base[f] = exten_base[f];
3033   decr(param_base[f]);
3034   fmem_ptr = fmem_ptr + lf;
3035   font_ptr = f;
3036   g = f;
3037   goto lab30;
3038 lab11:
3039   print_err("Font ");
3040   sprint_cs(u); 
3041   print_char('=');
3042   print_file_name(nom, aire, 335);  /* "" */
3043
3044   if (s >= 0)
3045   {
3046     print_string(" at ");
3047     print_scaled(s);
3048     print_string("pt");
3049   }
3050   else if (s != -1000)
3051   {
3052     print_string("scaled");
3053     print_int(- (integer) s);
3054   } 
3055
3056   if (fileopened)
3057     print_string(" not loadable: Bad metric (TFM) file");
3058   else
3059     print_string(" not loadable: Metric (TFM) file not found");
3060
3061   if (aire == 335) /* "" only if path not specified */
3062   {
3063     if (show_texinput_flag)
3064       show_tex_fonts();   /* 98/Jan/31 */
3065   }
3066
3067   help5("I wasn't able to read the size data for this font,",
3068       "so I will ignore the font specification.",
3069       "[Wizards can fix TFM files using TFtoPL/PLtoTF.]",
3070       "You might try inserting a different font spec;",
3071       "e.g., type `I\\font<same font id>=<substitute font name>'.");
3072   error();
3073 lab30:
3074   if (fileopened)
3075     b_close(tfm_file);
3076
3077   return g;
3078 }