OSDN Git Service

string clean.
[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   if (quoted_file_name == 0 && c == ' ')
1452     return false;
1453   else if (quoted_file_name != 0 && c == '"')
1454   {
1455     quoted_file_name = 0; /* catch next space character */
1456     return true;    /* accept ending quote, but throw away */
1457   }
1458   else
1459   {
1460 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1461 /*  convert pseudo tilde back to '~' 95/Sep/26 */ /* moved here 97/June/5 */
1462 /*  if (pseudo_tilde != 0 && c == pseudo_tilde) c = '~'; */
1463 /*  convert pseudo space back to ' ' 97/June/5 */ /* moved here 97/June/5 */
1464 /*  if (pseudo_space != 0 && c == pseudo_space) c = ' '; */
1465 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */      
1466     str_room(1);
1467     append_char(c);
1468 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1469 //  if ((c == 47))   /* / */
1470 //  for DOS/Windows
1471     if ((c == '/' || c == '\\' || c == ':')) /* 94/Mar/1 */
1472 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1473     {
1474       area_delimiter = cur_length;
1475       ext_delimiter = 0;
1476     } 
1477     else if (c == '.')
1478       ext_delimiter = cur_length;
1479     return true;
1480   }
1481 }
1482 /******************************** 2000 August 15th start ***********************/
1483
1484 // The following code is to save string space used by TeX for filenames
1485 // Not really critical in a system that has dynamic memory allocation
1486 // And may slow it down slightly - although this linear search only
1487 // occurs when opening a file, which is somewhat slow inany case...
1488
1489 // see if string from str_pool[start] to str_pool[end]
1490 // occurs elsewhere in string pool - returns string number
1491 // returns -1 if not found in string pool 2000 Aug 15
1492
1493 int find_string (int start, int end)
1494 {
1495   int k, nlen = end - start;
1496   char *s;
1497
1498 //  int trace_flag = 1;     // debugging only
1499
1500   if (trace_flag)
1501   {
1502     sprintf(log_line, "\nLOOKING for string (str_ptr %d nlen %d) ", str_ptr, end-start);
1503     s = log_line + strlen(log_line);
1504     strncpy(s, (const char *) str_pool + start, nlen);
1505     strcpy(s+nlen, "");
1506     show_line(log_line, 0);
1507   }
1508
1509 //  avoid problems with(cur_name == flushablestring)by going only up to str_ptr-1
1510 //  code in new_font (tex8.c) will take care of reuse of font name already
1511   for (k = 0; k < str_ptr - 1; k++)
1512   {
1513     if (length(k) != nlen) continue;
1514     if (strncmp((const char *) str_pool + start, (const char *) str_pool + str_start[k], nlen) == 0)
1515     {
1516       if (trace_flag)
1517       {
1518         sprintf(log_line, "\nFOUND the string %d (%d) ", k, str_start[k+1]-str_start[k]);
1519         s = log_line + strlen(log_line);
1520         strncpy(s, (const char *)str_pool + start, nlen);
1521         strcpy(s+nlen, "\n");
1522         show_line(log_line, 0);
1523       }
1524       return k;     // return number of matching string
1525     }
1526   }
1527
1528   if (trace_flag)
1529   {
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
1537   return -1;          // no match found
1538 }
1539
1540 // snip out the string from str_pool[start] to str_pool[end]
1541 // and move everything above it down 2000 Aug 15
1542
1543 void remove_string (int start, int end)
1544 {
1545   int nlen = pool_ptr - end;  // how many bytes to move down
1546   char *s;
1547   
1548 //  int trace_flag=1;   // debugging only
1549 //  if (end < start) show_line("\nEND < START", 1);
1550 //  if (pool_ptr < end) show_line("\nPOOLPTR < END", 1);
1551
1552   if (trace_flag)
1553   {
1554     int n = end-start;
1555     sprintf(log_line, "\nSTRIPPING OUT %d %d ", n, nlen);
1556     s = log_line + strlen(log_line);
1557     strncpy(s, (const char *)str_pool + start, n);
1558     strcpy(s+n, "\n");
1559     show_line(log_line, 0);
1560   }
1561
1562   if (nlen > 0)
1563     memcpy(str_pool+start, str_pool+end, nlen);
1564
1565   pool_ptr = start + nlen;    // poolprt - (end-start);
1566 }
1567
1568 void show_string (int k)
1569 {   // debugging code
1570   int nlen = length(k);
1571   char *s;
1572   
1573   sprintf(log_line, "\nSTRING %5d (%3d) %5d--%5d ",
1574       k, nlen, str_start[k], str_start[k+1]);
1575   s = log_line + strlen(log_line);      
1576   strncpy(s, (const char *)str_pool + str_start[k], nlen);
1577   strcpy(s + nlen, "");
1578   show_line(log_line, 0);
1579 }
1580
1581 // debugging code
1582 void show_all_strings (void)
1583 {
1584   int k;
1585
1586   for (k = 0; k < str_ptr; k++)
1587     show_string(k);
1588 }
1589
1590 // int notfirst=0;    // debugging only
1591
1592 /********************************** 2000 August 15 end ****************************/
1593 /* sec 0517 */
1594 void end_name (void) 
1595 {
1596 #ifdef ALLOCATESTRING
1597   if (str_ptr + 3 > current_max_strings)
1598     str_start = realloc_str_start(increment_max_strings + 3);
1599
1600   if (str_ptr + 3 > current_max_strings)
1601   {
1602     overflow("number of strings", current_max_strings - init_str_ptr);  /* 97/Mar/7 */
1603     return;     // abort_flag set
1604   }
1605 #else
1606   if (str_ptr + 3 > max_strings)
1607   {
1608     overflow("number of strings", max_strings - init_str_ptr); /* number of strings */
1609     return;     // abort_flag set
1610   }
1611 #endif
1612
1613 //  if (notfirst++ == 0) show_all_strings();  // debugging only
1614   
1615   if (area_delimiter == 0)   // no area delimiter ':' '/' or '\' found
1616     cur_area = 335;     // "" default area 
1617   else
1618   {
1619     if (save_strings_flag && (cur_area = find_string(str_start[str_ptr], str_start[str_ptr] + area_delimiter)) > 0)
1620     {
1621       remove_string(str_start[str_ptr], str_start[str_ptr] + area_delimiter);
1622       area_delimiter = 0; // area_delimiter - area_delimiter;
1623
1624       if (ext_delimiter != 0)
1625         ext_delimiter = ext_delimiter - area_delimiter;
1626
1627 //      str_start[str_ptr + 1]= str_start[str_ptr]+ area_delimiter; // test only
1628 //      incr(str_ptr);    // test only
1629     }
1630     else         // carve out string for "cur_area"
1631     {
1632       cur_area = str_ptr; 
1633       str_start[str_ptr + 1] = str_start[str_ptr] + area_delimiter; 
1634       incr(str_ptr);
1635     }
1636   }
1637
1638   if (ext_delimiter == 0) // no extension delimiter '.' found
1639   {
1640     cur_ext = 335;        // "" default extension 
1641
1642     if (save_strings_flag && (cur_name = find_string(str_start[str_ptr], pool_ptr)) > 0)
1643     {
1644       remove_string(str_start[str_ptr], pool_ptr);
1645 //    (void) make_string();  // test only
1646     }
1647     else            // Make string from str_start[str_ptr]to pool_ptr
1648       cur_name = make_string();
1649   } 
1650   else            // did find an extension
1651   {
1652     if (save_strings_flag &&
1653       (cur_name = find_string(str_start[str_ptr], str_start[str_ptr] + ext_delimiter - area_delimiter-1)) > 0)
1654     {
1655       remove_string(str_start[str_ptr], str_start[str_ptr] + ext_delimiter - area_delimiter - 1);
1656 //    str_start[str_ptr + 1]= str_start[str_ptr]+ ext_delimiter - area_delimiter - 1;   // test only
1657 //    incr(str_ptr);    // test only
1658     }
1659     else             // carve out string for "cur_name"
1660     {
1661       cur_name = str_ptr;
1662       str_start[str_ptr + 1]= str_start[str_ptr]+ ext_delimiter - area_delimiter - 1;
1663       incr(str_ptr);
1664     }
1665
1666     if (save_strings_flag && (cur_ext = find_string(str_start[str_ptr], pool_ptr)) > 0)
1667     {
1668       remove_string(str_start[str_ptr], pool_ptr);
1669 //    (void) make_string();  // test only
1670     }
1671     else            // Make string from str_start[str_ptr]to pool_ptr
1672       cur_ext = make_string();
1673   }
1674 }
1675
1676 /* n current name, a current area, e current extension */
1677 /* result in name_of_file[] */
1678 /* sec 0519 */
1679 void pack_file_name_(str_number n, str_number a, str_number e)
1680 {
1681   integer k;
1682   ASCII_code c;
1683   pool_pointer j;
1684   k = 0;
1685
1686   for (j = str_start[a]; j <= str_start[a + 1] - 1; j++)
1687   {
1688     c = str_pool[j];
1689     incr(k);
1690     if (k <= PATHMAX)
1691       name_of_file[k] = xchr[c];
1692   }
1693   for (j = str_start[n]; j <= str_start[n + 1] - 1; j++)
1694   {
1695     c = str_pool[j];
1696     incr(k);
1697     if (k <= PATHMAX)
1698       name_of_file[k] = xchr[c];
1699   }
1700   for (j = str_start[e]; j <= str_start[e + 1] - 1; j++)
1701   {
1702     c = str_pool[j];
1703     incr(k);
1704     if (k <= PATHMAX)
1705       name_of_file[k] = xchr[c];
1706   }
1707
1708   if (k < PATHMAX)
1709     name_length = k;
1710   else
1711     name_length = PATHMAX - 1;
1712 /*  pad it out with spaces ... what for ? in case we modify and forget  ? */
1713   for (k = name_length + 1; k <= PATHMAX; k++) name_of_file[k]= ' ';
1714   name_of_file[PATHMAX]= '\0';    /* paranoia 94/Mar/24 */
1715   {
1716     name_of_file [name_length+1] = '\0';
1717     if (trace_flag)
1718     {
1719       sprintf(log_line, " pack_file_name `%s' (%d) ", name_of_file + 1, name_length); /* debugging */
1720       show_line(log_line, 0);
1721     }
1722     name_of_file [name_length + 1] = ' ';
1723   }
1724 }
1725 /* Called only from two places tex9.c for format name - specified and default */
1726 /* for specified format name args are 0, a, b name in buffer[a] --- buffer[b] */
1727 /* for default args are format_default_length-4, 1, 0 */
1728 /* sec 0523 */
1729 void pack_buffered_name_(small_number n, integer a, integer b)
1730 {
1731   integer k;
1732   ASCII_code c;
1733   integer j;
1734   if (n + b - a + 5 > PATHMAX)
1735     b = a + PATHMAX - n - 5;
1736   k = 0;
1737 /*  This loop kicks in when we want the default format name */
1738   for (j = 1; j <= n; j++)
1739   {
1740     c = xord[TEX_format_default[j]];
1741     incr(k);
1742     if (k <= PATHMAX)
1743       name_of_file[k] = xchr[c];
1744   }
1745 /*  This loop kicks in when we want a specififed format name */
1746   for (j = a; j <= b; j++)
1747   {
1748     c = buffer[j];
1749     incr(k);
1750     if (k <= PATHMAX)
1751       name_of_file[k] = xchr[c];
1752   }
1753 /*  This adds the extension from the default format name */
1754   for (j = format_default_length - 3; j <= format_default_length; j++)
1755   {
1756     c = xord[TEX_format_default[j]];
1757     incr(k);
1758     if (k <= PATHMAX)
1759       name_of_file[k] = xchr[c];
1760   }
1761   if (k < PATHMAX)
1762     name_length = k;
1763   else
1764     name_length = PATHMAX - 1;
1765 /*  pad it out with spaces ... what for ? */
1766   for (k = name_length + 1; k <= PATHMAX; k++)
1767     name_of_file[k]= ' ';
1768   name_of_file[PATHMAX]= '\0';    /* paranoia 94/Mar/24 */
1769 }
1770 /* sec 0525 */
1771 str_number make_name_string (void)
1772 {
1773   integer k;
1774
1775 #ifdef ALLOCATESTRING
1776   if (pool_ptr + name_length > current_pool_size)
1777     str_pool = realloc_str_pool(increment_pool_size + name_length);
1778
1779   if (str_ptr == current_max_strings)
1780     str_start = realloc_str_start(increment_max_strings);
1781
1782   if ((pool_ptr + name_length > current_pool_size) || (str_ptr == current_max_strings) || (cur_length > 0))
1783 #else
1784   if ((pool_ptr + name_length > pool_size) || (str_ptr == max_strings) || (cur_length > 0))
1785 #endif
1786   {
1787     return '?';
1788   }
1789   else
1790   {
1791     for (k = 1; k <= name_length; k++)
1792       append_char(xord[name_of_file[k]]);
1793
1794     return make_string();
1795   }
1796 }
1797 /* sec 0525 */
1798 str_number a_make_name_string_(alpha_file * f)
1799 {
1800   return make_name_string();
1801 }
1802 /* sec 0525 */
1803 str_number b_make_name_string_(byte_file * f)
1804 {
1805   return make_name_string(); 
1806 }
1807 /* sec 0525 */
1808 str_number w_make_name_string_(word_file * f)
1809 {
1810   return make_name_string();
1811 }
1812
1813 /* Used by start_input to scan file name on command line */
1814 /* Also in tex8.c new_font_, open_or_close_in, and do_extension */
1815 /* sec 0526 */
1816 void scan_file_name (void)
1817 {
1818   name_in_progress = true;
1819   begin_name();
1820
1821   do
1822     {
1823       get_x_token(); 
1824     }
1825   while (!(cur_cmd != spacer));
1826
1827   quoted_file_name = 0;         /* 98/March/15 */
1828
1829   if (allow_quoted_names) /* check whether quoted name */
1830   {
1831     if (cur_chr == '"')
1832     {
1833       quoted_file_name = 1;
1834       get_x_token();
1835     }
1836   }
1837
1838   while (true)
1839   {
1840     if ((cur_cmd > other_char) || (cur_chr > 255)) 
1841     {
1842       back_input(); /* not a character put it back and leave */
1843       goto lab30; 
1844     } 
1845 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1846 /*  convert tilde '~' to pseudo tilde */
1847 /*  if (pseudo_tilde != 0 && cur_chr == '~') cur_chr = pseudo_tilde; */
1848 /*  convert space ' ' to pseudo space */
1849 /*  if (pseudo_space != 0 && cur_chr == ' ') cur_chr = pseudo_space; */
1850 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1851     if (!more_name(cur_chr))    /* up to next white space */
1852       goto lab30;
1853
1854     get_x_token();
1855   }
1856 lab30:
1857   end_name();
1858   name_in_progress = false;
1859 }
1860 /* argument is string .fmt, .log, or .dvi */
1861 /* sec 0529 */
1862 void pack_job_name_(str_number s)
1863 {
1864   cur_area = 335;       /* "" */
1865   cur_ext  = s;
1866   cur_name = job_name;
1867   pack_file_name(cur_name, cur_area, cur_ext);
1868 }
1869
1870 /**********************************************************************/
1871 /* show TEXINPUTS=... or format specific  */
1872 /* only show this if name was not fully qualified ? */
1873 void show_tex_inputs (void)
1874 {
1875   char *s, *t, *v;
1876
1877   s = "TEXINPUTS";        /* default */
1878
1879   if (format_specific)
1880   {
1881     s = format_name;                /* try specific */
1882
1883     if (grabenv(s) == NULL)
1884       s = "TEXINPUTS";  /* no format specific */
1885   }
1886
1887   if (grabenv(s) == NULL)
1888     s = "TEXINPUT";     /* 94/May/19 */
1889
1890   print_nl("  ");
1891   print_char(' ');
1892   print_char('(');
1893   t = s;
1894
1895   while (*t > '\0')
1896     print_char(*t++);
1897
1898   print_char('=');
1899   v = grabenv(s);
1900
1901   if (v != NULL)
1902   {
1903     t = v;
1904     while (*t > '\0')
1905       print_char(*t++);
1906   }
1907   print_char(')');
1908 }
1909
1910 /**********************************************************************/
1911 /* sec 0530 */
1912 /*  s - what can't be found, e - default */
1913 void prompt_file_name_(char * s, str_number e) 
1914 {
1915   integer k;
1916
1917   if (interaction == scroll_mode);
1918
1919   if (!strcmp("input file name", s))
1920     print_err("I can't find file `");
1921   else
1922     print_err("I can't write on file `");
1923
1924   print_file_name(cur_name, cur_area, cur_ext);
1925   print_string("'.");
1926
1927   if (!strcmp("input file name", s))
1928   {
1929     if (cur_area == 335) /* "" only if path not specified */
1930     {
1931       if (show_texinput_flag)
1932         show_tex_inputs();
1933     }
1934   }
1935
1936   if (e == 785)    /* .tex */
1937     show_context();
1938
1939   print_nl("Please type another ");
1940   print_string(s); 
1941
1942   if (interaction < 2)
1943   {
1944     fatal_error("*** (job aborted, file error in nonstop mode)");
1945     return;     // abort_flag set
1946   }
1947
1948   if (!knuth_flag)
1949 #ifdef _WINDOWS
1950     show_line(" (or ^z to exit)", 0);
1951 #else
1952     show_line(" (or Ctrl-Z to exit)", 0);
1953 #endif
1954   {
1955     print_string(": ");
1956     term_input(": ", 0);
1957   }
1958 /*  should we deal with tilde and space in file name here ??? */
1959   {
1960     begin_name();
1961     k = first;
1962
1963     while ((buffer[k] == ' ') && (k < last))
1964       incr(k);
1965 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1966     quoted_file_name = 0;         /* 98/March/15 */
1967
1968     if (allow_quoted_names && k < last) /* check whether quoted name */
1969     {
1970       if (buffer[k]== '"')
1971       {
1972         quoted_file_name = 1;
1973         incr(k);
1974       }
1975     }
1976
1977     while (true) {
1978       if (k == last)
1979         goto lab30;
1980 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1981 /*  convert tilde '~' to pseudo tilde */
1982       if (pseudo_tilde != 0 && buffer[k]== '~')
1983         buffer[k] = pseudo_tilde;
1984 /*  convert space ' ' to pseudo space */
1985       if (pseudo_space != 0 && buffer[k]== ' ')
1986         buffer[k] = pseudo_space;
1987 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1988       if (!more_name(buffer[k]))
1989         goto lab30;
1990       incr(k);
1991     }
1992 lab30:
1993     end_name();
1994   }
1995
1996   if (cur_ext == 335)    /* "" */
1997     cur_ext = e;      /* use default extension */
1998
1999   pack_file_name(cur_name, cur_area, cur_ext);
2000 }
2001 /* sec 0534 */
2002 void open_log_file (void)
2003 {
2004   char old_setting;
2005   integer k;
2006   integer l;
2007   ccharpointer months;
2008
2009   old_setting = selector;
2010
2011   if (job_name == 0)
2012     job_name = 790;   /* default:  texput */
2013
2014   pack_job_name(".log");
2015
2016   while (!a_open_out(log_file))
2017   {
2018     selector = term_only;
2019     prompt_file_name("transcript file name", ".log");
2020   }
2021
2022   texmf_log_name = a_make_name_string(log_file);
2023   selector = log_only;
2024   log_opened = true;
2025   {
2026 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2027 //  for our version DOS/Windows
2028   if (want_version)
2029   {
2030     stamp_it(log_line);         // ??? use log_line ???
2031     strcat(log_line, "\n");
2032     (void) fputs(log_line, log_file);
2033     stampcopy(log_line);
2034     strcat(log_line, "\n");
2035     (void) fputs(log_line, log_file);
2036   }
2037 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2038 /*  also change following in itex.c - bkph */
2039   (void) fputs(tex_version, log_file); 
2040   (void) fprintf(log_file, " (%s %s)", application, yandyversion);
2041
2042   if (format_ident > 0)
2043     slow_print(format_ident);     /* bkph */
2044
2045   print_string("  ");
2046 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2047   if (civilize_flag)
2048     print_int(year);
2049   else
2050     print_int(day);
2051 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2052     print_char(' ');
2053     months = " JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
2054
2055     for (k = 3 * month - 2; k <= 3 * month; k++)
2056       (void) putc(months[k],  log_file);
2057
2058     print_char(' ');
2059 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2060     if (civilize_flag)
2061       print_int(day);
2062     else
2063       print_int(year);
2064 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2065     print_char(' ');
2066     print_two(tex_time / 60);  /* hour */
2067     print_char(':');
2068     print_two(tex_time % 60);  /* minute */
2069   }
2070
2071   input_stack[input_ptr] = cur_input;
2072   print_nl("**");
2073   l = input_stack[0].limit_field;
2074
2075   if (buffer[l] == end_line_char)
2076     decr(l);
2077
2078   for (k = 1; k <= l; k++)
2079     print(buffer[k]);
2080
2081   print_ln(); 
2082 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2083 /* a good place to show the fmt file name or pool file name ? 94/June/21 */
2084   if (show_fmt_flag)
2085   {
2086     if (string_file != NULL)
2087     {
2088       fprintf(log_file, "(%s)\n", string_file);
2089       free(string_file);  /* this was allocated by strdup in openinou */
2090       string_file = NULL;   /* for safety */
2091     }
2092
2093     if (format_file != NULL)
2094     {
2095       fprintf(log_file, "(%s)\n", format_file);
2096       free(format_file);  /* this was allocated by strdup in openinou */
2097       format_file = NULL;   /* for safety */
2098     }
2099   }
2100 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2101   selector = old_setting + 2;
2102 }
2103
2104 /**************************** start of insertion 98/Feb/7 **************/
2105
2106 // Attempt to deal with foo.bar.tex given as foo.bar on command line
2107 // Makes copy of job_name with extension
2108
2109 void morenamecopy(ASCII_code c)
2110 {
2111 #ifdef ALLOCATESTRING
2112   if (pool_ptr + 1 > current_pool_size)
2113     str_pool = realloc_str_pool (increment_pool_size);
2114
2115   if (pool_ptr + 1 > current_pool_size) /* in case it failed 94/Jan/24 */
2116   {
2117     overflow("pool size", current_pool_size - init_pool_ptr); /* 97/Mar/7 */
2118     return;     // abort_flag set
2119   }
2120 #else
2121   if (pool_ptr + 1 > pool_size)
2122   {
2123     overflow("pool size", pool_size - init_pool_ptr); /* pool size */
2124     return;     // abort_flag set
2125   }
2126 #endif
2127   str_pool[pool_ptr] = c; 
2128   incr(pool_ptr);
2129 }
2130
2131 int endnamecopy(void)
2132 {
2133 #ifdef ALLOCATESTRING
2134     if (str_ptr + 1 > current_max_strings)
2135       str_start = realloc_str_start(increment_max_strings + 1);
2136
2137     if (str_ptr + 1 > current_max_strings) /* in case it failed 94/Jan/24 */
2138     {
2139       overflow("number of strings", current_max_strings - init_str_ptr);  /* 97/Mar/7 */
2140       return 0;     // abort_flag set
2141     }
2142 #else
2143     if (str_ptr + 1 > max_strings)
2144     {
2145       overflow("number of strings", max_strings - init_str_ptr); /* number of strings */
2146       return 0;     // abort_flag set
2147     }
2148 #endif
2149     return make_string();
2150 }
2151
2152 /* add extension to job_name */
2153 void jobnameappend (void)
2154
2155   int k, n;
2156 /*  copy job_name */
2157   k = str_start[job_name];
2158   n = str_start[job_name + 1];
2159
2160   while (k < n)
2161     morenamecopy(str_pool[k++]);
2162 /*  copy `extension' */
2163   k = str_start[cur_ext];
2164   n = str_start[cur_ext + 1];
2165
2166   while (k < n)
2167     morenamecopy(str_pool[k++]);
2168
2169   job_name = endnamecopy();
2170 }
2171
2172 /**************************** end of insertion 98/Feb/7 **************/
2173 /* sec 0537 */
2174 void start_input (void)
2175 {
2176   bool addedextension = false;
2177   scan_file_name();
2178   pack_file_name(cur_name, cur_area, cur_ext); 
2179
2180   while (true) {        /* loop until we get a valid file name */
2181     addedextension = false;
2182     begin_file_reading(); 
2183 /* *** *** *** *** *** following is new in 3.14159 *** *** *** *** *** *** */
2184 /*  if current extension is *not* empty, try to open using name as is */
2185 /*  string 335 is "" the empty string */
2186     if ((cur_ext != 335) && a_open_in(input_file[cur_input.index_field], TEXINPUTPATH))
2187       goto lab30;
2188 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2189 /*  we get here if extension is "", or file with extension failed to open */
2190 /*  if current extension is not `tex,' and `tex' is not irrelevant, try it */
2191 /*  string 785 is .tex */
2192 /*    (! extensionirrelevantp(name_of_file, "tex"))){ */
2193     if ((cur_ext != 785) && (name_length + 5 < PATHMAX) &&
2194         (! extensionirrelevantp(name_of_file, name_length, "tex")))
2195     {
2196       name_of_file[name_length + 1] = '.';
2197       name_of_file[name_length + 2] = 't';
2198       name_of_file[name_length + 3] = 'e';
2199       name_of_file[name_length + 4] = 'x';
2200       name_of_file[name_length + 5] = ' ';  /* 96/Jan/20 ??? */
2201       name_length = name_length + 4;
2202
2203       addedextension = true;
2204 /* *** *** *** ***  following new in 3.14159 *** *** *** *** *** *** *** */
2205       if (a_open_in(input_file[cur_input.index_field], TEXINPUTPATH))
2206         goto lab30;
2207
2208       name_length = name_length - 4;      /* strip extension again */
2209       name_of_file[name_length + 1] = ' ';  /* ' ' */
2210       addedextension = false;
2211 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2212     }
2213 /* *** *** *** *** major changes here in 3.14159 *** *** *** *** *** *** */
2214 /*  string 335 is "" the empty string */
2215     if ((cur_ext == 335) && a_open_in(input_file[cur_input.index_field], TEXINPUTPATH))
2216       goto lab30;
2217
2218     if (maketextex() && a_open_in(input_file[cur_input.index_field], TEXINPUTPATH))
2219       goto lab30;
2220 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2221     end_file_reading();
2222     prompt_file_name("input file name", ".tex");
2223   }   /* end of while(true)trying to get valid file name */
2224
2225 /* maybe set  pseudo_tilde = 0  at this point ? 95/Sep/26 */
2226 lab30: 
2227   cur_input.name_field = a_make_name_string(input_file[cur_input.index_field]);
2228
2229   if (job_name == 0)       /* only the first time */
2230   {
2231     job_name = cur_name;        /* here we set the job_name */
2232 /*  did file name have an `extension' already and we added ".tex" ? */
2233     if (cur_ext != 335 && addedextension)     /* 98/Feb/7 */
2234       jobnameappend();   /* append `extension' to job_name */
2235     open_log_file();
2236   }
2237   if (term_offset + length(cur_input.name_field) > max_print_line - 2) /* was 3 ? */
2238     print_ln();
2239   else if ((term_offset > 0) || (file_offset > 0))
2240     print_char(' ');
2241   print_char('(');
2242 //  print_char(64);       // debugging only marker
2243   incr(open_parens);
2244   if (open_parens > max_open_parens)
2245     max_open_parens = open_parens;    /* 1999/Jan/17 */
2246   slow_print(cur_input.name_field);
2247 //  print_char(64);       // debugging only marker
2248 #ifndef _WINDOWS
2249   fflush(stdout);
2250 #endif
2251   cur_input.state_field = new_line;
2252   {
2253     line = 1;
2254     if (input_ln(input_file[cur_input.index_field], false));
2255     firm_up_the_line();
2256     if ((end_line_char < 0) || (end_line_char > 255))
2257       decr(cur_input.limit_field);
2258     else
2259       buffer[cur_input.limit_field] = end_line_char;
2260     first = cur_input.limit_field + 1;
2261     cur_input.loc_field = cur_input.start_field;
2262   }
2263 }
2264
2265 /**********************************************************************/
2266 /* show TEXFONTS=... or format specific  */
2267 /* only show this if name was not fully qualified ? */
2268 void show_tex_fonts (void)
2269 {     /* 98/Jan/28 */
2270   char *s, *t, *v, *u;
2271   int n;
2272   s = "TEXFONTS";
2273   if (encoding_specific) {
2274     u = encoding_name;                /* try specific */
2275     if ((t = grabenv(u)) != NULL) {
2276       if (strchr(t, ':') != NULL &&
2277         sscanf(t, "%d", &n) == 0) {
2278         s = u;        /* look here instead of TEXFONTS=... */
2279       }
2280     }
2281   }
2282   print_nl("  ");
2283   print_char(' ');
2284   print_char('(');
2285   t = s;
2286   while (*t > '\0') print_char(*t++);
2287   print_char('=');
2288   v = grabenv(s);
2289   if (v != NULL) {
2290     t = v;
2291     while (*t > '\0') print_char(*t++);
2292   }
2293   print_char(')');
2294 }
2295
2296 /**********************************************************************/
2297
2298 /* called only from tex8.c */
2299 /* sec 0560 */
2300 internal_font_number read_font_info_(halfword u, str_number nom, str_number aire, scaled s)
2301 {
2302   register internal_font_number Result;
2303   font_index k;
2304   bool fileopened;
2305 /*  halfword lf, lh, bc, ec, nw, nh, nd, ni, nl, nk, ne, np;  */
2306   halfword lf, lh, nw, nh, nd, ni, nl, nk, ne, np;
2307 /*  halfword bc, ec; */
2308   int bc, ec;             /* 95/Jan/7 */
2309   internal_font_number f;
2310   internal_font_number g;
2311   eight_bits a, b, c, d;
2312   ffourquarters qw;
2313   scaled sw;
2314   integer bchlabel;
2315   short bchar;
2316   scaled z;
2317   integer alpha;
2318   char beta;
2319
2320   g = 0;
2321   fileopened = false;
2322   pack_file_name(nom, aire, 805); /* .tfm */
2323
2324   if (!b_open_in(tfm_file)) /* new in C version d */
2325   {
2326     if (maketextfm ())
2327     {
2328       if (!b_open_in(tfm_file))
2329         goto lab11;
2330     }
2331     else goto lab11;
2332   } 
2333 /*   was just: goto lab11; */
2334   fileopened = true; 
2335   {
2336 /*  tfm_temp = getc(tfm_file);  */ /* done already in open_input, but why? */
2337     {
2338       lf = tfm_temp;
2339       if (lf > 127)
2340         goto lab11;
2341       tfm_temp = getc(tfm_file);
2342       lf = lf * 256 + tfm_temp;
2343     }
2344     tfm_temp = getc(tfm_file);
2345     {
2346       lh = tfm_temp;
2347       if (lh > 127)
2348         goto lab11;
2349       tfm_temp = getc(tfm_file);
2350       lh = lh * 256 + tfm_temp;
2351     }
2352     tfm_temp = getc(tfm_file);
2353     {
2354       bc = tfm_temp;
2355       if (bc > 127)
2356         goto lab11;
2357       tfm_temp = getc(tfm_file);
2358       bc = bc * 256 + tfm_temp;
2359     }
2360     tfm_temp = getc(tfm_file);
2361     {
2362       ec = tfm_temp;
2363       if (ec > 127)
2364         goto lab11;
2365       tfm_temp = getc(tfm_file);
2366       ec = ec * 256 + tfm_temp;
2367     }
2368     if ((bc > ec + 1)||(ec > 255))
2369       goto lab11;
2370     if (bc > 255)
2371     {
2372       bc = 1;
2373       ec = 0;
2374     }
2375     tfm_temp = getc(tfm_file);
2376     {
2377       nw = tfm_temp;
2378       if (nw > 127)
2379         goto lab11;
2380       tfm_temp = getc(tfm_file);
2381       nw = nw * 256 + tfm_temp;
2382     }
2383     tfm_temp = getc(tfm_file);
2384     {
2385       nh = tfm_temp;
2386       if (nh > 127)
2387         goto lab11;
2388       tfm_temp = getc(tfm_file);
2389       nh = nh * 256 + tfm_temp;
2390     }
2391     tfm_temp = getc(tfm_file);
2392     {
2393       nd = tfm_temp;
2394       if (nd > 127)
2395         goto lab11;
2396       tfm_temp = getc(tfm_file);
2397       nd = nd * 256 + tfm_temp;
2398     }
2399     tfm_temp = getc(tfm_file);
2400     {
2401       ni = tfm_temp;
2402       if (ni > 127)
2403         goto lab11;
2404       tfm_temp = getc(tfm_file);
2405       ni = ni * 256 + tfm_temp;
2406     }
2407     tfm_temp = getc(tfm_file);
2408     {
2409       nl = tfm_temp;
2410       if (nl > 127)
2411         goto lab11;
2412       tfm_temp = getc(tfm_file);
2413       nl = nl * 256 + tfm_temp;
2414     }
2415     tfm_temp = getc(tfm_file);
2416     {
2417       nk = tfm_temp;
2418       if (nk > 127)
2419         goto lab11;
2420       tfm_temp = getc(tfm_file);
2421       nk = nk * 256 + tfm_temp;
2422     }
2423     tfm_temp = getc(tfm_file);
2424     {
2425       ne = tfm_temp;
2426       if (ne > 127)
2427         goto lab11;
2428       tfm_temp = getc(tfm_file);
2429       ne = ne * 256 + tfm_temp;
2430     }
2431     tfm_temp = getc(tfm_file);
2432     {
2433       np = tfm_temp;
2434       if (np > 127)
2435         goto lab11;
2436       tfm_temp = getc(tfm_file);
2437       np = np * 256 + tfm_temp;
2438     }
2439     if (lf != 6 + lh + (ec - bc + 1) + nw + nh + nd + ni + nl + nk + ne + np)
2440       goto lab11;
2441
2442     if ((nw == 0) || (nh == 0) || (nd == 0) || (ni == 0))
2443       goto lab11;
2444   }
2445
2446   lf = lf - 6 - lh;
2447
2448   if (np < 7)
2449     lf = lf + 7 - np;
2450 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2451 #ifdef ALLOCATEFONT
2452   if ((fmem_ptr + lf > current_font_mem_size))   /* 93/Nov/28 */
2453     font_info = realloc_font_info (increment_font_mem_size + lf);
2454
2455   if ((font_ptr == font_max) || (fmem_ptr + lf > current_font_mem_size))
2456 #else
2457   if ((font_ptr == font_max) || (fmem_ptr + lf > font_mem_size))
2458 #endif
2459   {
2460     if (trace_flag)
2461     {
2462       sprintf(log_line, "font_ptr %d font_max %d fmem_ptr %d lf %d font_mem_size %d\n",
2463           font_ptr, font_max, fmem_ptr, lf, font_mem_size); /* debugging */
2464       show_line(log_line, 0);
2465     }
2466
2467     print_err("Font ");
2468     sprint_cs(u);
2469     print_char('=');
2470     print_file_name(nom, aire, 335); /* "" */
2471
2472     if (s >= 0)
2473     {
2474       print_string(" at ");
2475       print_scaled(s);
2476       print_string("pt");
2477     }
2478     else if (s != -1000)
2479     {
2480       print_string(" scaled ");
2481       print_int(- (integer) s);
2482     }
2483
2484     print_string(" not loaded: Not enough room left");
2485     help4("I'm afraid I won't be able to make use of this font,",
2486         "because my memory for character-size data is too small.",
2487         "If you're really stuck, ask a wizard to enlarge me.",
2488         "Or maybe try `I\\font<same font id>=<name of loaded font>'.");
2489     error();
2490     goto lab30;
2491   }
2492
2493   f = font_ptr + 1;
2494   char_base[f] = fmem_ptr - bc;
2495   width_base[f] = char_base[f] + ec + 1;
2496   height_base[f] = width_base[f] + nw;
2497   depth_base[f] = height_base[f] + nh;
2498   italic_base[f] = depth_base[f] + nd;
2499   lig_kern_base[f] = italic_base[f] + ni;
2500   kern_base[f] = lig_kern_base[f] + nl - 256 * (128);
2501   exten_base[f] = kern_base[f] + 256 *(128) + nk;
2502   param_base[f] = exten_base[f] + ne;
2503
2504   {
2505     if (lh < 2)
2506       goto lab11;
2507 /*  build the font checksum now */
2508     {
2509       tfm_temp = getc(tfm_file);
2510       a = tfm_temp;
2511       qw.b0 = a;
2512       tfm_temp = getc(tfm_file);
2513       b = tfm_temp;
2514       qw.b1 = b;
2515       tfm_temp = getc(tfm_file);
2516       c = tfm_temp;
2517       qw.b2 = c;
2518       tfm_temp = getc(tfm_file);
2519       d = tfm_temp;
2520       qw.b3 = d;
2521       font_check[f] = qw;
2522     }
2523
2524     tfm_temp = getc(tfm_file);
2525     {
2526       z = tfm_temp;
2527       if (z > 127)
2528         goto lab11;
2529       tfm_temp = getc(tfm_file);
2530       z = z * 256 + tfm_temp;
2531     }
2532
2533     tfm_temp = getc(tfm_file);
2534     z = z * 256 + tfm_temp;
2535     tfm_temp = getc(tfm_file);
2536     z =(z * 16) + (tfm_temp / 16);
2537
2538     if (z < 65536L)
2539       goto lab11; 
2540
2541     while (lh > 2)
2542     {
2543       tfm_temp = getc(tfm_file);
2544       tfm_temp = getc(tfm_file);
2545       tfm_temp = getc(tfm_file);
2546       tfm_temp = getc(tfm_file);
2547       decr(lh);
2548     }
2549
2550     font_dsize[f] = z;
2551
2552     if (s != -1000)
2553       if (s >= 0)
2554         z = s;
2555       else
2556         z = xn_over_d(z, - (integer) s, 1000);
2557     font_size[f] = z;
2558   }
2559
2560   for (k = fmem_ptr; k <= width_base[f] - 1; k++)
2561   {
2562     {
2563       tfm_temp = getc(tfm_file);
2564       a = tfm_temp;
2565       qw.b0 = a;
2566       tfm_temp = getc(tfm_file);
2567       b = tfm_temp;
2568       qw.b1 = b;
2569       tfm_temp = getc(tfm_file);
2570       c = tfm_temp;
2571       qw.b2 = c;
2572       tfm_temp = getc(tfm_file);
2573       d = tfm_temp;
2574       qw.b3 = d;
2575       font_info[k].qqqq = qw;
2576     }
2577
2578     if ((a >= nw) || (b / 16 >= nh) || (b % 16 >= nd) || (c / 4 >= ni))
2579       goto lab11;
2580
2581     switch (c % 4)
2582     {
2583       case 1 :
2584         if (d >= nl)
2585           goto lab11;
2586         break;
2587       case 3 :
2588         if (d >= ne)
2589           goto lab11;
2590         break;
2591       case 2 :
2592         {
2593           {
2594             if ((d < bc)||(d > ec))
2595               goto lab11;
2596           }
2597           while (d < k + bc - fmem_ptr) {
2598             qw = font_info[char_base[f]+ d].qqqq;
2599             if (((qw.b2)% 4)!= 2)
2600               goto lab45;
2601             d = qw.b3;
2602           }
2603           if (d == k + bc - fmem_ptr)
2604             goto lab11;
2605 lab45:; 
2606         }
2607         break;
2608       default:
2609         break;
2610     }
2611   }
2612   {
2613     {
2614       alpha = 16;
2615       while (z >= 8388608L) {   /* 2^23 */
2616         z = z / 2;
2617         alpha = alpha + alpha;
2618       }
2619       beta = (char) (256 / alpha);
2620       alpha = alpha * z;
2621     }
2622
2623     for (k = width_base[f]; k <= lig_kern_base[f] - 1; k++)
2624     {
2625       tfm_temp = getc(tfm_file);
2626       a = tfm_temp;
2627       tfm_temp = getc(tfm_file);
2628       b = tfm_temp;
2629       tfm_temp = getc(tfm_file);
2630       c = tfm_temp;
2631       tfm_temp = getc(tfm_file);
2632       d = tfm_temp;
2633       sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2634       if (a == 0)
2635         font_info[k].cint = sw;
2636       else if (a == 255)
2637         font_info[k].cint = sw - alpha;
2638       else
2639         goto lab11;
2640     }
2641     if (font_info[width_base[f]].cint != 0)
2642       goto lab11;
2643     if (font_info[height_base[f]].cint != 0)
2644       goto lab11;
2645     if (font_info[depth_base[f]].cint != 0)
2646       goto lab11;
2647     if (font_info[italic_base[f]].cint != 0)
2648       goto lab11;
2649   }
2650 /*  read ligature/kern program */
2651   bchlabel = 32767;     /* '77777 */
2652   bchar = 256;
2653
2654   if (nl > 0)
2655   {
2656     for (k = lig_kern_base[f]; k <= kern_base[f] + 256 * (128)- 1; k++)
2657     {
2658       {
2659         tfm_temp = getc(tfm_file);
2660         a = tfm_temp;
2661         qw.b0 = a;
2662         tfm_temp = getc(tfm_file);
2663         b = tfm_temp;
2664         qw.b1 = b;
2665         tfm_temp = getc(tfm_file);
2666         c = tfm_temp;
2667         qw.b2 = c;
2668         tfm_temp = getc(tfm_file);
2669         d = tfm_temp;
2670         qw.b3 = d;
2671         font_info[k].qqqq = qw; /* store_four_quarters(font_info[k].qqqq */
2672       }
2673       if (a > 128)
2674       {
2675         if (256 * c + d >= nl)
2676           goto lab11;       /* error in TFM, abort */
2677         if (a == 255)
2678           if (k == lig_kern_base[f])
2679             bchar = b;
2680       }
2681       else
2682       {
2683         if (b != bchar)
2684         {
2685           {
2686             if ((b < bc) || (b > ec))  /* check-existence(b) */
2687               goto lab11;         /* error in TFM, abort */
2688           }
2689           qw = font_info[char_base[f] + b].qqqq;
2690           if (!(qw.b0 > 0))
2691             goto lab11;         /* error in TFM, abort */
2692         }
2693         if (c < 128)
2694         {
2695           {
2696             if ((d < bc) || (d > ec))  /* check-existence(d) */
2697               goto lab11;         /* error in TFM, abort */
2698           }
2699           qw = font_info[char_base[f] + d].qqqq;
2700           if (!(qw.b0 > 0))
2701             goto lab11;         /* error in TFM, abort */
2702         }
2703         else if (256 * (c - 128) + d >= nk)
2704           goto lab11;           /* error in TFM, abort */
2705         if (a < 128)
2706           if (k - lig_kern_base[f] + a + 1 >= nl)
2707             goto lab11;         /* error in TFM, abort */
2708       }
2709     }
2710     if (a == 255)
2711       bchlabel = 256 * c + d;
2712   }
2713
2714   for (k = kern_base[f] + 256 * (128); k <= exten_base[f] - 1; k++)
2715   {
2716     tfm_temp = getc(tfm_file);
2717     a = tfm_temp;
2718     tfm_temp = getc(tfm_file);
2719     b = tfm_temp;
2720     tfm_temp = getc(tfm_file);
2721     c = tfm_temp;
2722     tfm_temp = getc(tfm_file);
2723     d = tfm_temp;
2724     sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2725     if (a == 0)
2726       font_info[k].cint = sw;
2727     else if (a == 255)
2728       font_info[k].cint = sw - alpha;
2729     else goto lab11;
2730   }
2731 /*  read extensible character recipes */
2732 /*  for k:=exten_base[f] to param_base[f]-1 do */
2733   for (k = exten_base[f]; k <= param_base[f] - 1; k++)
2734   {
2735     {
2736       tfm_temp = getc(tfm_file);
2737       a = tfm_temp;
2738       qw.b0 = a;
2739       tfm_temp = getc(tfm_file);
2740       b = tfm_temp;
2741       qw.b1 = b;
2742       tfm_temp = getc(tfm_file);
2743       c = tfm_temp;
2744       qw.b2 = c;
2745       tfm_temp = getc(tfm_file);
2746       d = tfm_temp;
2747       qw.b3 = d;
2748 /*    store_four_quarters(font_info[k].qqqq); */
2749       font_info[k].qqqq = qw;
2750     }
2751     if (a != 0)
2752     {
2753       {
2754         if ((a < bc) || (a > ec))
2755           goto lab11;
2756       }
2757       qw = font_info[char_base[f] + a].qqqq;
2758       if (!(qw.b0 > 0))
2759         goto lab11;
2760     }
2761     if (b != 0)
2762     {
2763       {
2764         if ((b < bc) || (b > ec))
2765           goto lab11;
2766       }
2767       qw = font_info[char_base[f] + b].qqqq;
2768       if (!(qw.b0 > 0))
2769         goto lab11;
2770     }
2771     if (c != 0)
2772     {
2773       {
2774         if ((c < bc) || (c > ec))
2775           goto lab11;
2776       }
2777       qw = font_info[char_base[f] + c].qqqq;
2778       if (!(qw.b0 > 0))
2779         goto lab11;
2780     }
2781     {
2782       {
2783         if ((d < bc) || (d > ec))
2784           goto lab11;
2785       }
2786       qw = font_info[char_base[f] + d].qqqq;
2787       if (!(qw.b0 > 0))
2788         goto lab11;
2789     }
2790   }
2791   {
2792     for (k = 1; k <= np; k++)
2793       if (k == 1)
2794       {
2795         tfm_temp = getc(tfm_file);
2796         sw = tfm_temp;
2797         if (sw > 127)
2798           sw = sw - 256;
2799         tfm_temp = getc(tfm_file);
2800         sw = sw * 256 + tfm_temp;
2801         tfm_temp = getc(tfm_file);
2802         sw = sw * 256 + tfm_temp;
2803         tfm_temp = getc(tfm_file);
2804         font_info[param_base[f]].cint = (sw * 16) + (tfm_temp / 16);
2805       }
2806       else
2807       {
2808         tfm_temp = getc(tfm_file);
2809         a = tfm_temp;
2810         tfm_temp = getc(tfm_file);
2811         b = tfm_temp;
2812         tfm_temp = getc(tfm_file);
2813         c = tfm_temp;
2814         tfm_temp = getc(tfm_file);
2815         d = tfm_temp;
2816         sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2817         if (a == 0)
2818           font_info[param_base[f] + k - 1].cint = sw;
2819         else if (a == 255)
2820           font_info[param_base[f] + k - 1].cint = sw - alpha;
2821         else goto lab11;
2822       }
2823 /*  use test_eof() here instead ? */
2824     if (feof(tfm_file))
2825       goto lab11;
2826     for (k = np + 1; k <= 7; k++)
2827       font_info[param_base[f] + k - 1].cint = 0;
2828   }
2829 /* @<Make final adjustments...@>= l.11174 */
2830   if (np >= 7)
2831     font_params[f] = np;
2832   else
2833     font_params[f] = 7;
2834   hyphen_char[f] = default_hyphen_char;
2835   skew_char[f] = default_skew_char;
2836   if (bchlabel < nl)
2837     bchar_label[f] = bchlabel + lig_kern_base[f];
2838   else
2839     bchar_label[f]= non_address; /* i.e. 0 --- 96/Jan/15 */
2840   font_bchar[f] = bchar;
2841   font_false_bchar[f] = bchar;
2842   if (bchar <= ec)
2843     if (bchar >= bc)
2844     {
2845       qw = font_info[char_base[f] + bchar].qqqq;
2846       if ((qw.b0 > 0))
2847         font_false_bchar[f] = 256;
2848     }
2849   font_name[f] = nom;
2850   font_area[f] = aire;
2851   font_bc[f] = bc;
2852   font_ec[f] = ec;
2853   font_glue[f] = 0;  /* font_glue[f]:=null; l.11184 */
2854   char_base[f] = char_base[f];
2855   width_base[f] = width_base[f];
2856   lig_kern_base[f] = lig_kern_base[f];
2857   kern_base[f] = kern_base[f];
2858   exten_base[f] = exten_base[f];
2859   decr(param_base[f]);
2860   fmem_ptr = fmem_ptr + lf;
2861   font_ptr = f;
2862   g = f;
2863   goto lab30;
2864 lab11:
2865   print_err("Font ");
2866   sprint_cs(u); 
2867   print_char('=');
2868   print_file_name(nom, aire, 335);  /* "" */
2869   if (s >= 0)
2870   {
2871     print_string(" at ");
2872     print_scaled(s);
2873     print_string("pt");
2874   }
2875   else if (s != -1000)
2876   {
2877     print_string("scaled");
2878     print_int(- (integer) s);
2879   } 
2880
2881   if (fileopened)
2882     print_string(" not loadable: Bad metric (TFM) file");
2883   else
2884     print_string(" not loadable: Metric (TFM) file not found");
2885
2886   if (aire == 335) /* "" only if path not specified */
2887   {
2888     if (show_texinput_flag) show_tex_fonts();   /* 98/Jan/31 */
2889   }
2890
2891   help5("I wasn't able to read the size data for this font,",
2892       "so I will ignore the font specification.",
2893       "[Wizards can fix TFM files using TFtoPL/PLtoTF.]",
2894       "You might try inserting a different font spec;",
2895       "e.g., type `I\\font<same font id>=<substitute font name>'.");
2896   error();
2897 lab30:
2898   if (fileopened)
2899     b_close(tfm_file);
2900
2901   Result = g;
2902   return Result;
2903 }