OSDN Git Service

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