OSDN Git Service

show_inter_val().
[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 * unity + 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 save_scanner_status;
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       save_scanner_status = scanner_status;
703       scanner_status = 0;
704       get_token();
705       scanner_status = save_scanner_status;
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             prompt_input("");
965           else
966           {
967             print_ln();
968             sprint_cs(r);
969             prompt_input("=");
970             n = -1;
971           }
972         else
973         {
974           fatal_error("*** (cannot \\read from terminal in nonstop modes)");
975           return;     // abort_flag set
976         }
977       else if (read_open[m] == 1)
978         if (input_ln(read_file[m], false))
979           read_open[m] = 0;
980         else
981         {
982           (void) a_close(read_file[m]);
983           read_open[m] = 2;
984         }
985       else
986       {
987         if (!input_ln(read_file[m], true))
988         {
989           (void) a_close(read_file[m]);
990           read_open[m] = 2;
991
992           if (align_state != 1000000L)
993           {
994             runaway();
995             print_err("File ended within ");
996             print_esc("read");
997             help1("This \\read has unbalanced braces.");
998             align_state = 1000000L;
999             error();
1000           }
1001         }
1002       }
1003
1004       limit = last;
1005
1006       if (end_line_char_inactive())
1007         decr(limit);
1008       else
1009         buffer[limit] = end_line_char;
1010
1011       first = limit + 1;
1012       loc = start;
1013       state = new_line;
1014
1015       while (true)
1016       {
1017         get_token();
1018
1019         if (cur_tok == 0)
1020           goto lab30;
1021
1022         if (align_state < 1000000L)
1023         {
1024           do
1025             {
1026               get_token();
1027             }
1028           while (!(cur_tok == 0));
1029
1030           align_state = 1000000L;
1031           goto lab30;
1032         }
1033
1034         store_new_token(cur_tok);
1035       }
1036 lab30:
1037       end_file_reading();
1038     }
1039   while (!(align_state == 1000000L));
1040
1041   cur_val = def_ref;
1042   scanner_status = normal;
1043   align_state = s;
1044 }
1045 /* sec 0494 */
1046 void pass_text (void)
1047 {
1048   integer l;
1049   small_number save_scanner_status;
1050
1051   save_scanner_status = scanner_status;
1052   scanner_status = skipping;
1053   l = 0;
1054   skip_line = line;
1055
1056   while (true)
1057   {
1058     get_next();
1059
1060     if (cur_cmd == fi_or_else)
1061     {
1062       if (l == 0)
1063         goto lab30;
1064
1065       if (cur_chr == 2)
1066         decr(l);
1067     }
1068     else if (cur_cmd == if_test)
1069       incr(l);
1070   }
1071 lab30:
1072   scanner_status = save_scanner_status;
1073 }
1074 /* sec 0497 */
1075 void change_if_limit_(small_number l, halfword p)
1076 {
1077   halfword q;
1078
1079   if (p == cond_ptr)
1080     if_limit = l;
1081   else
1082   {
1083     q = cond_ptr;
1084
1085     while (true)
1086     {
1087       if (q == 0)
1088       {
1089         confusion("if");
1090         return;       // abort_flag set
1091       }
1092
1093       if (link(q) == p)
1094       {
1095         type(p) = l;
1096         return;
1097       }
1098
1099       q = link(q);
1100     }
1101   }
1102 }
1103 /* called from tex2.c */
1104 /* sec 0498 */
1105 void conditional (void)
1106 {
1107   boolean b;
1108   char r;
1109   integer m, n;
1110   halfword p, q;
1111   small_number save_scanner_status;
1112   halfword savecondptr;
1113   small_number thisif;
1114
1115   {
1116     p = get_node(if_node_size);
1117     link(p) = cond_ptr;
1118     type(p) = if_limit;
1119     subtype(p) = cur_if;
1120     if_line_field(p) = if_line;
1121     cond_ptr = p;
1122     cur_if = cur_chr;
1123     if_limit = if_code;
1124     if_line = line;
1125   }
1126
1127   savecondptr = cond_ptr;
1128   thisif = cur_chr;
1129
1130   switch (thisif)
1131   {
1132     case if_char_code:
1133     case if_cat_code:
1134       {
1135         {
1136           get_x_token();
1137
1138           if (cur_cmd == relax)
1139             if (cur_chr == no_expand_flag)
1140             {
1141               cur_cmd = active_char;
1142               cur_chr = cur_tok - cs_token_flag - active_base;
1143             }
1144         }
1145
1146         if ((cur_cmd > active_char) || (cur_chr > 255))
1147         {
1148           m = relax;
1149           n = 256;
1150         }
1151         else
1152         {
1153           m = cur_cmd;
1154           n = cur_chr;
1155         }
1156         {
1157           get_x_token();
1158
1159           if (cur_cmd == relax)
1160             if (cur_chr == no_expand_flag)
1161             {
1162               cur_cmd = active_char;
1163               cur_chr = cur_tok - cs_token_flag - active_base;
1164             }
1165         }
1166
1167         if ((cur_cmd > active_char) || (cur_chr > 255))
1168         {
1169           cur_cmd = relax;
1170           cur_chr = 256;
1171         }
1172
1173         if (thisif == if_char_code)
1174           b = (n == cur_chr); 
1175         else
1176           b = (m == cur_cmd);
1177       }
1178       break;
1179
1180     case if_int_code:
1181     case if_dim_code:
1182       {
1183         if (thisif == if_int_code)
1184           scan_int();
1185         else
1186           scan_dimen(false, false, false);
1187
1188         n = cur_val;
1189         
1190         do
1191           {
1192             get_x_token();
1193           }
1194         while (!(cur_cmd != spacer));
1195
1196         if ((cur_tok >= other_token + '<') && (cur_tok <= other_token + '>'))
1197           r = cur_tok - other_token;
1198         else
1199         {
1200           print_err("Missing = inserted for ");
1201           print_cmd_chr(if_test, thisif);
1202           help1("I was expecting to see `<', `=', or `>'. Didn't.");
1203           back_error();
1204           r = '=';
1205         }
1206
1207         if (thisif == if_int_code)
1208           scan_int();
1209         else 
1210           scan_dimen(false, false, false);
1211
1212         switch (r)
1213         {
1214           case '<':
1215             b = (n < cur_val);
1216             break;
1217
1218           case '=':
1219             b = (n == cur_val);
1220             break;
1221
1222           case '>':
1223             b = (n > cur_val);
1224             break;
1225         }
1226       }
1227       break;
1228
1229     case if_odd_code:
1230       scan_int();
1231       b = odd(cur_val);
1232       break;
1233
1234     case if_vmode_code:
1235       b = (abs(mode) == 1);
1236       break;
1237
1238     case if_hmode_code:
1239       b = (abs(mode) == 102);
1240       break;
1241
1242     case if_mmode_code:
1243       b = (abs(mode) == 203);
1244       break;
1245
1246     case if_inner_code:
1247       b = (mode < 0);
1248       break;
1249
1250     case if_void_code:
1251     case if_hbox_code:
1252     case if_vbox_code:
1253       {
1254         scan_eight_bit_int();
1255         p = box(cur_val);
1256
1257         if (thisif == if_void_code)
1258           b = (p == 0);
1259         else if (p == 0)
1260           b = false;
1261         else if (thisif == if_hbox_code)
1262           b = (type(p) == hlist_node);
1263         else
1264           b = (type(p) == vlist_node);
1265       }
1266       break;
1267
1268     case ifx_code:
1269       {
1270         save_scanner_status = scanner_status;
1271         scanner_status = 0;
1272         get_next();
1273         n = cur_cs;
1274         p = cur_cmd;
1275         q = cur_chr;
1276         get_next();
1277
1278         if (cur_cmd != p)
1279           b = false;
1280         else if (cur_cmd < call)
1281           b = (cur_chr == q);
1282         else
1283         {
1284           p = link(cur_chr);
1285           q = link(equiv(n));
1286
1287           if (p == q)
1288             b = true;
1289           else
1290           {
1291             while ((p != 0) && (q != 0))
1292               if (info(p) != info(q))
1293                 p = 0;
1294               else
1295               {
1296                 p = link(p);
1297                 q = link(q);
1298               }
1299
1300             b = ((p == 0) && (q == 0));
1301           }
1302         }
1303
1304         scanner_status = save_scanner_status;
1305       }
1306       break;
1307
1308     case if_eof_code:
1309       {
1310         scan_four_bit_int();
1311         b = (read_open[cur_val] == closed);
1312       }
1313       break;
1314
1315     case if_true_code:
1316       b = true;
1317       break;
1318
1319     case if_false_code:
1320       b = false;
1321       break;
1322
1323     case if_case_code:
1324       {
1325         scan_int();
1326         n = cur_val;
1327
1328         if (tracing_commands > 1)
1329         {
1330           begin_diagnostic();
1331           print_string("{case ");
1332           print_int(n); 
1333           print_char('}');
1334           end_diagnostic(false);
1335         }
1336
1337         while (n != 0)
1338         {
1339           pass_text();
1340
1341           if (cond_ptr == savecondptr)
1342             if (cur_chr == or_code)
1343               decr(n);
1344             else 
1345               goto lab50;
1346           else if (cur_chr == fi_code)
1347           {
1348             p = cond_ptr;
1349             if_line = if_line_field(p);
1350             cur_if = subtype(p);
1351             if_limit = type(p);
1352             cond_ptr = link(p);
1353             free_node(p, if_node_size);
1354           }
1355         }
1356
1357         change_if_limit(or_code, savecondptr);
1358         return;
1359       }
1360       break;
1361   }
1362
1363   if (tracing_commands > 1)
1364   {
1365     begin_diagnostic();
1366
1367     if (b)
1368       print_string("{true}");
1369     else
1370       print_string("{false}");
1371
1372     end_diagnostic(false);
1373   }
1374
1375   if (b)     /* b may be used without ... */
1376   {
1377     change_if_limit(else_code, savecondptr);
1378     return;
1379   }
1380
1381   while (true)
1382   {
1383     pass_text();
1384
1385     if (cond_ptr == savecondptr)
1386     {
1387       if (cur_chr != or_code)
1388         goto lab50;
1389
1390       print_err("Extra ");
1391       print_esc("or");
1392       help1("I'm ignoring this; it doesn't match any \\if.");
1393       error();
1394     }
1395     else if (cur_chr == fi_code)
1396     {
1397       p = cond_ptr;
1398       if_line = if_line_field(p);
1399       cur_if = subtype(p);
1400       if_limit = type(p);
1401       cond_ptr = link(p);
1402       free_node(p, if_node_size);
1403     }
1404   }
1405
1406 lab50:
1407   if (cur_chr == fi_code)
1408   {
1409     p = cond_ptr;
1410     if_line = if_line_field(p);
1411     cur_if = subtype(p);
1412     if_limit = type(p);
1413     cond_ptr = link(p);
1414     free_node(p, if_node_size);
1415   }
1416   else
1417     if_limit = fi_code;
1418 }
1419 /* sec 0515 */
1420 void begin_name (void)
1421 {
1422   area_delimiter = 0;
1423   ext_delimiter = 0;
1424 }
1425 /* This gathers up a file name and makes a string of it */
1426 /* Also tries to break it into `file area' `file name' and `file extension' */
1427 /* Used by scan_file_name and prompt_file_name */
1428 /* We assume tilde has been converted to pseudo_tilde and space to pseudo_space */
1429 /* returns false if it is given a space character - end of file name */
1430 /* sec 0516 */
1431 boolean more_name_(ASCII_code c)
1432 {
1433   if (quoted_file_name == 0 && c == ' ')
1434     return false;
1435   else if (quoted_file_name != 0 && c == '"')
1436   {
1437     quoted_file_name = 0; /* catch next space character */
1438     return true;    /* accept ending quote, but throw away */
1439   }
1440   else
1441   {   
1442     str_room(1);
1443     append_char(c);
1444     //  for DOS/Windows
1445     if ((c == '/' || c == '\\' || c == ':')) 
1446     {
1447       area_delimiter = cur_length;
1448       ext_delimiter = 0;
1449     } 
1450     else if (c == '.')
1451       ext_delimiter = cur_length;
1452
1453     return true;
1454   }
1455 }
1456
1457 /* sec 0517 */
1458 void end_name (void) 
1459 {
1460 #ifdef ALLOCATESTRING
1461   if (str_ptr + 3 > current_max_strings)
1462     str_start = realloc_str_start(increment_max_strings + 3);
1463
1464   if (str_ptr + 3 > current_max_strings)
1465   {
1466     overflow("number of strings", current_max_strings - init_str_ptr);
1467     return;
1468   }
1469 #else
1470   if (str_ptr + 3 > max_strings)
1471   {
1472     overflow("number of strings", max_strings - init_str_ptr);
1473     return;
1474   }
1475 #endif
1476
1477   if (area_delimiter == 0)   // no area delimiter ':' '/' or '\' found
1478     cur_area = 335;     // "" default area 
1479   else
1480   {
1481     cur_area = str_ptr;
1482     str_start[str_ptr + 1] = str_start[str_ptr] + area_delimiter;
1483     incr(str_ptr);
1484   }
1485
1486   if (ext_delimiter == 0) // no extension delimiter '.' found
1487   {
1488     cur_ext = 335;        // "" default extension 
1489     cur_name = make_string();
1490   } 
1491   else            // did find an extension
1492   {
1493     cur_name = str_ptr;
1494     str_start[str_ptr + 1] = str_start[str_ptr]+ ext_delimiter - area_delimiter - 1;
1495     incr(str_ptr);
1496     cur_ext = make_string();
1497   }
1498 }
1499
1500 /* n current name, a current area, e current extension */
1501 /* result in name_of_file[] */
1502 /* sec 0519 */
1503 void pack_file_name_(str_number n, str_number a, str_number e)
1504 {
1505   integer k;
1506   ASCII_code c;
1507   pool_pointer j;
1508
1509   k = 0;
1510
1511   for (j = str_start[a]; j <= str_start[a + 1] - 1; j++)
1512   {
1513     c = str_pool[j];
1514     incr(k);
1515
1516     if (k <= file_name_size)
1517       name_of_file[k] = xchr[c];
1518   }
1519
1520   for (j = str_start[n]; j <= str_start[n + 1] - 1; j++)
1521   {
1522     c = str_pool[j];
1523     incr(k);
1524
1525     if (k <= file_name_size)
1526       name_of_file[k] = xchr[c];
1527   }
1528
1529   for (j = str_start[e]; j <= str_start[e + 1] - 1; j++)
1530   {
1531     c = str_pool[j];
1532     incr(k);
1533
1534     if (k <= file_name_size)
1535       name_of_file[k] = xchr[c];
1536   }
1537
1538   if (k < file_name_size)
1539     name_length = k;
1540   else
1541     name_length = file_name_size - 1;
1542
1543 /*  pad it out with spaces ... what for ? in case we modify and forget  ? */
1544   for (k = name_length + 1; k <= file_name_size; k++)
1545     name_of_file[k] = ' ';
1546
1547   name_of_file[file_name_size] = '\0';    /* paranoia 94/Mar/24 */
1548
1549   {
1550     name_of_file [name_length+1] = '\0';
1551
1552     if (trace_flag)
1553     {
1554       sprintf(log_line, " pack_file_name `%s' (%d) ", name_of_file + 1, name_length); /* debugging */
1555       show_line(log_line, 0);
1556     }
1557
1558     name_of_file [name_length + 1] = ' ';
1559   }
1560 }
1561 /* Called only from two places tex9.c for format name - specified and default */
1562 /* for specified format name args are 0, a, b name in buffer[a] --- buffer[b] */
1563 /* for default args are format_default_length-4, 1, 0 */
1564 /* sec 0523 */
1565 void pack_buffered_name_(small_number n, integer a, integer b)
1566 {
1567   integer k;
1568   ASCII_code c;
1569   integer j;
1570
1571   if (n + b - a + 5 > file_name_size)
1572     b = a + file_name_size - n - 5;
1573
1574   k = 0;
1575
1576 /*  This loop kicks in when we want the default format name */
1577   for (j = 1; j <= n; j++)
1578   {
1579     c = xord[TEX_format_default[j]];
1580     incr(k);
1581
1582     if (k <= file_name_size)
1583       name_of_file[k] = xchr[c];
1584   }
1585 /*  This loop kicks in when we want a specififed format name */
1586   for (j = a; j <= b; j++)
1587   {
1588     c = buffer[j];
1589     incr(k);
1590
1591     if (k <= file_name_size)
1592       name_of_file[k] = xchr[c];
1593   }
1594
1595 /*  This adds the extension from the default format name */
1596   for (j = format_default_length - 3; j <= format_default_length; j++)
1597   {
1598     c = xord[TEX_format_default[j]];
1599     incr(k);
1600
1601     if (k <= file_name_size)
1602       name_of_file[k] = xchr[c];
1603   }
1604
1605   if (k < file_name_size)
1606     name_length = k;
1607   else
1608     name_length = file_name_size - 1;
1609
1610  /*  pad it out with spaces ... what for ? */
1611   for (k = name_length + 1; k <= file_name_size; k++)
1612     name_of_file[k]= ' ';
1613
1614   name_of_file[file_name_size] = '\0';    /* paranoia 94/Mar/24 */
1615 }
1616 /* sec 0525 */
1617 str_number make_name_string (void)
1618 {
1619   integer k;
1620
1621 #ifdef ALLOCATESTRING
1622   if (pool_ptr + name_length > current_pool_size)
1623     str_pool = realloc_str_pool(increment_pool_size + name_length);
1624
1625   if (str_ptr == current_max_strings)
1626     str_start = realloc_str_start(increment_max_strings);
1627
1628   if ((pool_ptr + name_length > current_pool_size) || (str_ptr == current_max_strings) || (cur_length > 0))
1629 #else
1630   if ((pool_ptr + name_length > pool_size) || (str_ptr == max_strings) || (cur_length > 0))
1631 #endif
1632   {
1633     return '?';
1634   }
1635   else
1636   {
1637     for (k = 1; k <= name_length; k++)
1638       append_char(xord[name_of_file[k]]);
1639
1640     return make_string();
1641   }
1642 }
1643 /* sec 0525 */
1644 //str_number a_make_name_string_(alpha_file * f)
1645 str_number a_make_name_string_(void)
1646 {
1647   return make_name_string();
1648 }
1649 /* sec 0525 */
1650 //str_number b_make_name_string_(byte_file * f)
1651 str_number b_make_name_string_(void)
1652 {
1653   return make_name_string(); 
1654 }
1655 /* sec 0525 */
1656 //str_number w_make_name_string_(word_file * f)
1657 str_number w_make_name_string_(void)
1658 {
1659   return make_name_string();
1660 }
1661
1662 /* Used by start_input to scan file name on command line */
1663 /* Also in tex8.c new_font_, open_or_close_in, and do_extension */
1664 /* sec 0526 */
1665 void scan_file_name (void)
1666 {
1667   name_in_progress = true;
1668   begin_name();
1669
1670   do
1671     {
1672       get_x_token(); 
1673     }
1674   while (!(cur_cmd != spacer));
1675
1676   quoted_file_name = false;
1677
1678   if (allow_quoted_names)
1679   {
1680     if (cur_chr == '"')
1681     {
1682       quoted_file_name = 1;
1683       get_x_token();
1684     }
1685   }
1686
1687   while (true)
1688   {
1689     if ((cur_cmd > other_char) || (cur_chr > 255)) 
1690     {
1691       back_input();
1692       goto lab30; 
1693     } 
1694
1695     if (!more_name(cur_chr))    /* up to next white space */
1696       goto lab30;
1697
1698     get_x_token();
1699   }
1700
1701 lab30:
1702   end_name();
1703   name_in_progress = false;
1704 }
1705 /* argument is string .fmt, .log, or .dvi */
1706 /* sec 0529 */
1707 void pack_job_name_(str_number s)
1708 {
1709   cur_area = 335;       /* "" */
1710   cur_ext  = s;
1711   cur_name = job_name;
1712   pack_file_name(cur_name, cur_area, cur_ext);
1713 }
1714
1715 /**********************************************************************/
1716 /* sec 0530 */
1717 /* s - what can't be found, e - default */
1718 void prompt_file_name_(char * s, str_number e) 
1719 {
1720   integer k;
1721
1722   if (interaction == scroll_mode);
1723
1724   if (!strcmp("input file name", s))
1725     print_err("I can't find file `");
1726   else
1727     print_err("I can't write on file `");
1728
1729   print_file_name(cur_name, cur_area, cur_ext);
1730   print_string("'.");
1731
1732   if (e == 785)    /* .tex */
1733     show_context();
1734
1735   print_nl("Please type another ");
1736   print_string(s); 
1737
1738   if (interaction < 2)
1739   {
1740     fatal_error("*** (job aborted, file error in nonstop mode)");
1741     return;     // abort_flag set
1742   }
1743
1744   if (!knuth_flag)
1745 #ifdef _WINDOWS
1746     show_line(" (or ^z to exit)", 0);
1747 #else
1748     show_line(" (or Ctrl-Z to exit)", 0);
1749 #endif
1750   prompt_input(": ");
1751
1752 /*  should we deal with tilde and space in file name here ??? */
1753   {
1754     begin_name();
1755     k = first;
1756
1757     while ((buffer[k] == ' ') && (k < last))
1758       incr(k);
1759 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1760     quoted_file_name = 0;         /* 98/March/15 */
1761
1762     if (allow_quoted_names && k < last) /* check whether quoted name */
1763     {
1764       if (buffer[k]== '"')
1765       {
1766         quoted_file_name = 1;
1767         incr(k);
1768       }
1769     }
1770
1771     while (true)
1772     {
1773       if (k == last)
1774         goto lab30;
1775 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1776 /*  convert tilde '~' to pseudo tilde */
1777       if (pseudo_tilde != 0 && buffer[k]== '~')
1778         buffer[k] = pseudo_tilde;
1779 /*  convert space ' ' to pseudo space */
1780       if (pseudo_space != 0 && buffer[k]== ' ')
1781         buffer[k] = pseudo_space;
1782 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1783       if (!more_name(buffer[k]))
1784         goto lab30;
1785
1786       incr(k);
1787     }
1788 lab30:
1789     end_name();
1790   }
1791
1792   if (cur_ext == 335)    /* "" */
1793     cur_ext = e;      /* use default extension */
1794
1795   pack_file_name(cur_name, cur_area, cur_ext);
1796 }
1797 /* sec 0534 */
1798 void open_log_file (void)
1799 {
1800   char old_setting;
1801   integer k;
1802   integer l;
1803   char * months;
1804
1805   old_setting = selector;
1806
1807   if (job_name == 0)
1808     job_name = 790;
1809
1810   pack_job_name(".log");
1811
1812   while (!a_open_out(log_file))
1813   {
1814     selector = term_only;
1815     prompt_file_name("transcript file name", ".log");
1816   }
1817
1818   texmf_log_name = a_make_name_string(log_file);
1819   selector = log_only;
1820   log_opened = true;
1821
1822   {
1823     if (want_version)
1824     {
1825       stamp_it(log_line);
1826       strcat(log_line, "\n");
1827       (void) fputs(log_line, log_file);
1828       stampcopy(log_line);
1829       strcat(log_line, "\n");
1830       (void) fputs(log_line, log_file);
1831     }
1832     
1833     fprintf(log_file, "%s (%s %s)", tex_version, application, yandyversion);
1834
1835     if (format_ident > 0)
1836       slow_print(format_ident);
1837
1838     print_string("  ");
1839
1840     if (civilize_flag)
1841       print_int(year);
1842     else
1843       print_int(day);
1844
1845     print_char(' ');
1846     months = " JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
1847
1848     for (k = 3 * month - 2; k <= 3 * month; k++)
1849       (void) putc(months[k],  log_file);
1850
1851     print_char(' ');
1852
1853     if (civilize_flag)
1854       print_int(day);
1855     else
1856       print_int(year);
1857
1858     print_char(' ');
1859     print_two(tex_time / 60);
1860     print_char(':');
1861     print_two(tex_time % 60);
1862   }
1863
1864   input_stack[input_ptr] = cur_input;
1865   print_nl("**");
1866   l = input_stack[0].limit_field;
1867
1868   if (buffer[l] == end_line_char)
1869     decr(l);
1870
1871   for (k = 1; k <= l; k++)
1872     print(buffer[k]);
1873
1874   print_ln(); 
1875
1876   if (show_fmt_flag)
1877   {
1878     if (format_file != NULL)
1879     {
1880       fprintf(log_file, "(%s)\n", format_file);
1881       free(format_file);
1882       format_file = NULL;
1883     }
1884   }
1885
1886   selector = old_setting + 2;
1887 }
1888
1889 // Attempt to deal with foo.bar.tex given as foo.bar on command line
1890 // Makes copy of job_name with extension
1891
1892 void more_name_copy(ASCII_code c)
1893 {
1894 #ifdef ALLOCATESTRING
1895   if (pool_ptr + 1 > current_pool_size)
1896     str_pool = realloc_str_pool (increment_pool_size);
1897
1898   if (pool_ptr + 1 > current_pool_size)
1899   {
1900     overflow("pool size", current_pool_size - init_pool_ptr);
1901     return;
1902   }
1903 #else
1904   if (pool_ptr + 1 > pool_size)
1905   {
1906     overflow("pool size", pool_size - init_pool_ptr);
1907     return;
1908   }
1909 #endif
1910
1911   str_pool[pool_ptr] = c; 
1912   incr(pool_ptr);
1913 }
1914
1915 int end_name_copy(void)
1916 {
1917 #ifdef ALLOCATESTRING
1918   if (str_ptr + 1 > current_max_strings)
1919     str_start = realloc_str_start(increment_max_strings + 1);
1920
1921   if (str_ptr + 1 > current_max_strings)
1922   {
1923     overflow("number of strings", current_max_strings - init_str_ptr);
1924     return 0;
1925   }
1926 #else
1927   if (str_ptr + 1 > max_strings)
1928   {
1929     overflow("number of strings", max_strings - init_str_ptr);
1930     return 0;
1931   }
1932 #endif
1933
1934   return make_string();
1935 }
1936
1937 void job_name_append (void)
1938
1939   int k, n;
1940
1941   k = str_start[job_name];
1942   n = str_start[job_name + 1];
1943
1944   while (k < n)
1945     more_name_copy(str_pool[k++]);
1946
1947   k = str_start[cur_ext];
1948   n = str_start[cur_ext + 1];
1949
1950   while (k < n)
1951     more_name_copy(str_pool[k++]);
1952
1953   job_name = end_name_copy();
1954 }
1955
1956 /* sec 0537 */
1957 void start_input(void)
1958 {
1959   scan_file_name();
1960   pack_file_name(cur_name, cur_area, cur_ext); 
1961
1962   while (true)
1963   {
1964     begin_file_reading();
1965     
1966     if (a_open_in(cur_file, TEXINPUTPATH))
1967       goto lab30;
1968
1969     end_file_reading();
1970     prompt_file_name("input file name", ".tex");
1971   }
1972
1973 lab30: 
1974   cur_input.name_field = a_make_name_string(cur_file);
1975
1976   if (job_name == 0)
1977   {
1978     job_name = cur_name;
1979     open_log_file();
1980   }
1981
1982   if (term_offset + length(cur_input.name_field) > max_print_line - 2)
1983     print_ln();
1984   else if ((term_offset > 0) || (file_offset > 0))
1985     print_char(' ');
1986
1987   print_char('(');
1988   incr(open_parens);
1989
1990   if (open_parens > max_open_parens)
1991     max_open_parens = open_parens;
1992
1993   slow_print(cur_input.name_field);
1994
1995 #ifndef _WINDOWS
1996   fflush(stdout);
1997 #endif
1998
1999   state = new_line;
2000
2001   {
2002     line = 1;
2003
2004     if (input_ln(cur_file, false));
2005
2006     firm_up_the_line();
2007
2008     if (end_line_char_inactive())
2009       decr(limit);
2010     else
2011       buffer[limit] = end_line_char;
2012
2013     first = limit + 1;
2014     loc = start;
2015   }
2016 }
2017 /* sec 0560 */
2018 internal_font_number read_font_info_(halfword u, str_number nom, str_number aire, scaled s)
2019 {
2020   font_index k;
2021   boolean file_opened;
2022   halfword lf, lh, nw, nh, nd, ni, nl, nk, ne, np;
2023   int bc, ec;
2024   internal_font_number f;
2025   internal_font_number g;
2026   eight_bits a, b, c, d;
2027   four_quarters qw;
2028   scaled sw;
2029   integer bch_label;
2030   short bchar;
2031   scaled z;
2032   integer alpha;
2033   char beta;
2034
2035   g = 0;
2036   file_opened = false;
2037   pack_file_name(nom, aire, 805); /* .tfm */
2038
2039   if (!b_open_in(tfm_file))
2040   {
2041     goto lab11;
2042   } 
2043
2044   file_opened = true; 
2045
2046   {
2047     read_sixteen(lf);
2048     tfm_temp = getc(tfm_file);
2049     read_sixteen(lh);
2050     tfm_temp = getc(tfm_file);
2051     read_sixteen(bc);
2052     tfm_temp = getc(tfm_file);
2053     read_sixteen(ec);
2054
2055     if ((bc > ec + 1) || (ec > 255))
2056       goto lab11;
2057
2058     if (bc > 255)
2059     {
2060       bc = 1;
2061       ec = 0;
2062     }
2063
2064     tfm_temp = getc(tfm_file);
2065     read_sixteen(nw);
2066     tfm_temp = getc(tfm_file);
2067     read_sixteen(nh);
2068     tfm_temp = getc(tfm_file);
2069     read_sixteen(nd);
2070     tfm_temp = getc(tfm_file);
2071     read_sixteen(ni);
2072     tfm_temp = getc(tfm_file);
2073     read_sixteen(nl);
2074     tfm_temp = getc(tfm_file);
2075     read_sixteen(nk);
2076     tfm_temp = getc(tfm_file);
2077     read_sixteen(ne);
2078     tfm_temp = getc(tfm_file);
2079     read_sixteen(np);
2080
2081     if (lf != 6 + lh + (ec - bc + 1) + nw + nh + nd + ni + nl + nk + ne + np)
2082       goto lab11;
2083
2084     if ((nw == 0) || (nh == 0) || (nd == 0) || (ni == 0))
2085       goto lab11;
2086   }
2087
2088   lf = lf - 6 - lh;
2089
2090   if (np < 7)
2091     lf = lf + 7 - np;
2092
2093 #ifdef ALLOCATEFONT
2094   if ((fmem_ptr + lf > current_font_mem_size))
2095     font_info = realloc_font_info (increment_font_mem_size + lf);
2096
2097   if ((font_ptr == font_max) || (fmem_ptr + lf > current_font_mem_size))
2098 #else
2099   if ((font_ptr == font_max) || (fmem_ptr + lf > font_mem_size))
2100 #endif
2101   {
2102     if (trace_flag)
2103     {
2104       sprintf(log_line, "font_ptr %d font_max %d fmem_ptr %d lf %d font_mem_size %d\n",
2105           font_ptr, font_max, fmem_ptr, lf, font_mem_size);
2106       show_line(log_line, 0);
2107     }
2108
2109     print_err("Font ");
2110     sprint_cs(u);
2111     print_char('=');
2112     print_file_name(nom, aire, 335); /* "" */
2113
2114     if (s >= 0)
2115     {
2116       print_string(" at ");
2117       print_scaled(s);
2118       print_string("pt");
2119     }
2120     else if (s != -1000)
2121     {
2122       print_string(" scaled ");
2123       print_int(- (integer) s);
2124     }
2125
2126     print_string(" not loaded: Not enough room left");
2127     help4("I'm afraid I won't be able to make use of this font,",
2128         "because my memory for character-size data is too small.",
2129         "If you're really stuck, ask a wizard to enlarge me.",
2130         "Or maybe try `I\\font<same font id>=<name of loaded font>'.");
2131     error();
2132     goto lab30;
2133   }
2134
2135   f = font_ptr + 1;
2136   char_base[f] = fmem_ptr - bc;
2137   width_base[f] = char_base[f] + ec + 1;
2138   height_base[f] = width_base[f] + nw;
2139   depth_base[f] = height_base[f] + nh;
2140   italic_base[f] = depth_base[f] + nd;
2141   lig_kern_base[f] = italic_base[f] + ni;
2142   kern_base[f] = lig_kern_base[f] + nl - 256 * (128);
2143   exten_base[f] = kern_base[f] + 256 * (128) + nk;
2144   param_base[f] = exten_base[f] + ne;
2145
2146   {
2147     if (lh < 2)
2148       goto lab11;
2149     
2150     store_four_quarters(font_check[f]);
2151     tfm_temp = getc(tfm_file);
2152     read_sixteen(z);
2153     tfm_temp = getc(tfm_file);
2154     z = z * 256 + tfm_temp;
2155     tfm_temp = getc(tfm_file);
2156     z =(z * 16) + (tfm_temp / 16);
2157
2158     if (z < unity)
2159       goto lab11; 
2160
2161     while (lh > 2)
2162     {
2163       tfm_temp = getc(tfm_file);
2164       tfm_temp = getc(tfm_file);
2165       tfm_temp = getc(tfm_file);
2166       tfm_temp = getc(tfm_file);
2167       decr(lh);
2168     }
2169
2170     font_dsize[f] = z;
2171
2172     if (s != -1000)
2173       if (s >= 0)
2174         z = s;
2175       else
2176         z = xn_over_d(z, - (integer) s, 1000);
2177
2178     font_size[f] = z;
2179   }
2180
2181   for (k = fmem_ptr; k <= width_base[f] - 1; k++)
2182   {
2183     store_four_quarters(font_info[k].qqqq);
2184
2185     if ((a >= nw) || (b / 16 >= nh) || (b % 16 >= nd) || (c / 4 >= ni))
2186       goto lab11;
2187
2188     switch (c % 4)
2189     {
2190       case lig_tag:
2191         if (d >= nl)
2192           goto lab11;
2193         break;
2194
2195       case ext_tag:
2196         if (d >= ne)
2197           goto lab11;
2198         break;
2199
2200       case list_tag:
2201         {
2202           {
2203             if ((d < bc) || (d > ec))
2204               goto lab11;
2205           }
2206
2207           while (d < k + bc - fmem_ptr)
2208           {
2209             qw = char_info(f, d);
2210  
2211             if (char_tag(qw) != list_tag)
2212               goto lab45;
2213
2214             d = rem_byte(qw);
2215           }
2216
2217           if (d == k + bc - fmem_ptr)
2218             goto lab11;
2219 lab45:; 
2220         }
2221         break;
2222
2223       default:
2224         break;
2225     }
2226   }
2227
2228   {
2229     {
2230       alpha = 16;
2231
2232       while (z >= 8388608L)   /* 2^23 */
2233       {
2234         z = z / 2;
2235         alpha = alpha + alpha;
2236       }
2237
2238       beta = (char) (256 / alpha);
2239       alpha = alpha * z;
2240     }
2241
2242     for (k = width_base[f]; k <= lig_kern_base[f] - 1; k++)
2243     {
2244       tfm_temp = getc(tfm_file);
2245       a = tfm_temp;
2246       tfm_temp = getc(tfm_file);
2247       b = tfm_temp;
2248       tfm_temp = getc(tfm_file);
2249       c = tfm_temp;
2250       tfm_temp = getc(tfm_file);
2251       d = tfm_temp;
2252       sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2253
2254       if (a == 0)
2255         font_info[k].cint = sw;
2256       else if (a == 255)
2257         font_info[k].cint = sw - alpha;
2258       else
2259         goto lab11;
2260     }
2261
2262     if (font_info[width_base[f]].cint != 0)
2263       goto lab11;
2264
2265     if (font_info[height_base[f]].cint != 0)
2266       goto lab11;
2267
2268     if (font_info[depth_base[f]].cint != 0)
2269       goto lab11;
2270
2271     if (font_info[italic_base[f]].cint != 0)
2272       goto lab11;
2273   }
2274
2275   bch_label = 32767;     /* '77777 */
2276   bchar = 256;
2277
2278   if (nl > 0)
2279   {
2280     for (k = lig_kern_base[f]; k <= kern_base[f] + 256 * (128) - 1; k++)
2281     {
2282       store_four_quarters(font_info[k].qqqq);
2283
2284       if (a > 128)
2285       {
2286         if (256 * c + d >= nl)
2287           goto lab11;       /* error in TFM, abort */
2288
2289         if (a == 255)
2290           if (k == lig_kern_base[f])
2291             bchar = b;
2292       }
2293       else
2294       {
2295         if (b != bchar)
2296         {
2297           {
2298             if ((b < bc) || (b > ec))  /* check-existence(b) */
2299               goto lab11;         /* error in TFM, abort */
2300           }
2301
2302           qw = font_info[char_base[f] + b].qqqq;
2303
2304           if (!(qw.b0 > 0))
2305             goto lab11;         /* error in TFM, abort */
2306         }
2307
2308         if (c < 128)
2309         {
2310           {
2311             if ((d < bc) || (d > ec))  /* check-existence(d) */
2312               goto lab11;         /* error in TFM, abort */
2313           }
2314
2315           qw = font_info[char_base[f] + d].qqqq;
2316
2317           if (!(qw.b0 > 0))
2318             goto lab11;         /* error in TFM, abort */
2319         }
2320         else if (256 * (c - 128) + d >= nk)
2321           goto lab11;           /* error in TFM, abort */
2322
2323         if (a < 128)
2324           if (k - lig_kern_base[f] + a + 1 >= nl)
2325             goto lab11;         /* error in TFM, abort */
2326       }
2327     }
2328
2329     if (a == 255)
2330       bch_label = 256 * c + d;
2331   }
2332
2333   for (k = kern_base[f] + 256 * (128); k <= exten_base[f] - 1; k++)
2334   {
2335     tfm_temp = getc(tfm_file);
2336     a = tfm_temp;
2337     tfm_temp = getc(tfm_file);
2338     b = tfm_temp;
2339     tfm_temp = getc(tfm_file);
2340     c = tfm_temp;
2341     tfm_temp = getc(tfm_file);
2342     d = tfm_temp;
2343     sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2344
2345     if (a == 0)
2346       font_info[k].cint = sw;
2347     else if (a == 255)
2348       font_info[k].cint = sw - alpha;
2349     else goto lab11;
2350   }
2351
2352   /*  read extensible character recipes */
2353   for (k = exten_base[f]; k <= param_base[f] - 1; k++)
2354   {
2355     store_four_quarters(font_info[k].qqqq);
2356
2357     if (a != 0)
2358     {
2359       {
2360         if ((a < bc) || (a > ec))
2361           goto lab11;
2362       }
2363
2364       qw = font_info[char_base[f] + a].qqqq;
2365
2366       if (!(qw.b0 > 0))
2367         goto lab11;
2368     }
2369
2370     if (b != 0)
2371     {
2372       {
2373         if ((b < bc) || (b > ec))
2374           goto lab11;
2375       }
2376
2377       qw = font_info[char_base[f] + b].qqqq;
2378
2379       if (!(qw.b0 > 0))
2380         goto lab11;
2381     }
2382
2383     if (c != 0)
2384     {
2385       {
2386         if ((c < bc) || (c > ec))
2387           goto lab11;
2388       }
2389
2390       qw = font_info[char_base[f] + c].qqqq;
2391
2392       if (!(qw.b0 > 0))
2393         goto lab11;
2394     }
2395
2396     {
2397       {
2398         if ((d < bc) || (d > ec))
2399           goto lab11;
2400       }
2401
2402       qw = font_info[char_base[f] + d].qqqq;
2403
2404       if (!(qw.b0 > 0))
2405         goto lab11;
2406     }
2407   }
2408
2409   {
2410     for (k = 1; k <= np; k++)
2411       if (k == 1)
2412       {
2413         tfm_temp = getc(tfm_file);
2414         sw = tfm_temp;
2415
2416         if (sw > 127)
2417           sw = sw - 256;
2418
2419         tfm_temp = getc(tfm_file);
2420         sw = sw * 256 + tfm_temp;
2421         tfm_temp = getc(tfm_file);
2422         sw = sw * 256 + tfm_temp;
2423         tfm_temp = getc(tfm_file);
2424         font_info[param_base[f]].cint = (sw * 16) + (tfm_temp / 16);
2425       }
2426       else
2427       {
2428         tfm_temp = getc(tfm_file);
2429         a = tfm_temp;
2430         tfm_temp = getc(tfm_file);
2431         b = tfm_temp;
2432         tfm_temp = getc(tfm_file);
2433         c = tfm_temp;
2434         tfm_temp = getc(tfm_file);
2435         d = tfm_temp;
2436         sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2437
2438         if (a == 0)
2439           font_info[param_base[f] + k - 1].cint = sw;
2440         else if (a == 255)
2441           font_info[param_base[f] + k - 1].cint = sw - alpha;
2442         else goto lab11;
2443       }
2444
2445     if (feof(tfm_file))
2446       goto lab11;
2447
2448     for (k = np + 1; k <= 7; k++)
2449       font_info[param_base[f] + k - 1].cint = 0;
2450   }
2451
2452   if (np >= 7)
2453     font_params[f] = np;
2454   else
2455     font_params[f] = 7;
2456
2457   hyphen_char[f] = default_hyphen_char;
2458   skew_char[f] = default_skew_char;
2459
2460   if (bch_label < nl)
2461     bchar_label[f] = bch_label + lig_kern_base[f];
2462   else
2463     bchar_label[f] = non_address;
2464
2465   font_bchar[f] = bchar;
2466   font_false_bchar[f] = bchar;
2467
2468   if (bchar <= ec)
2469     if (bchar >= bc)
2470     {
2471       qw = font_info[char_base[f] + bchar].qqqq;
2472
2473       if ((qw.b0 > 0))
2474         font_false_bchar[f] = 256;
2475     }
2476
2477   font_name[f] = nom;
2478   font_area[f] = aire;
2479   font_bc[f] = bc;
2480   font_ec[f] = ec;
2481   font_glue[f] = 0;
2482   char_base[f] = char_base[f];
2483   width_base[f] = width_base[f];
2484   lig_kern_base[f] = lig_kern_base[f];
2485   kern_base[f] = kern_base[f];
2486   exten_base[f] = exten_base[f];
2487   decr(param_base[f]);
2488   fmem_ptr = fmem_ptr + lf;
2489   font_ptr = f;
2490   g = f;
2491   goto lab30;
2492
2493 lab11:
2494   print_err("Font ");
2495   sprint_cs(u); 
2496   print_char('=');
2497   print_file_name(nom, aire, 335);
2498
2499   if (s >= 0)
2500   {
2501     print_string(" at ");
2502     print_scaled(s);
2503     print_string("pt");
2504   }
2505   else if (s != -1000)
2506   {
2507     print_string("scaled");
2508     print_int(- (integer) s);
2509   } 
2510
2511   if (file_opened)
2512     print_string(" not loadable: Bad metric (TFM) file");
2513   else
2514     print_string(" not loadable: Metric (TFM) file not found");
2515
2516   help5("I wasn't able to read the size data for this font,",
2517       "so I will ignore the font specification.",
2518       "[Wizards can fix TFM files using TFtoPL/PLtoTF.]",
2519       "You might try inserting a different font spec;",
2520       "e.g., type `I\\font<same font id>=<substitute font name>'.");
2521   error();
2522
2523 lab30:
2524   if (file_opened)
2525     b_close(tfm_file);
2526
2527   return g;
2528 }