OSDN Git Service

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