OSDN Git Service

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