OSDN Git Service

memcpy and memmove.
[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   register str_number Result;
1788   Result = make_name_string();
1789   return Result;
1790 }   /* f unreferenced ? bkph */
1791 /* sec 0525 */
1792 str_number b_make_name_string_(byte_file * f)
1793 {
1794   register str_number Result;
1795   Result = make_name_string();
1796   return Result; 
1797 }   /* f unreferenced ? bkph */
1798 /* sec 0525 */
1799 str_number w_make_name_string_(word_file * f)
1800 {
1801   register str_number Result;
1802   Result = make_name_string();
1803   return Result;
1804 }   /* f unreferenced ? bkph */
1805
1806 /* Used by start_input to scan file name on command line */
1807 /* Also in tex8.c new_font_, open_or_close_in, and do_extension */
1808 /* sec 0526 */
1809 void scan_file_name (void)
1810 {
1811   name_in_progress = true;
1812   begin_name();
1813
1814   do
1815     {
1816       get_x_token(); 
1817     }
1818   while (!(cur_cmd != spacer));
1819
1820   quoted_file_name = 0;         /* 98/March/15 */
1821
1822   if (allow_quoted_names) /* check whether quoted name */
1823   {
1824     if (cur_chr == '"')
1825     {
1826       quoted_file_name = 1;
1827       get_x_token();
1828     }
1829   }
1830
1831   while (true)
1832   {
1833     if ((cur_cmd > other_char) || (cur_chr > 255)) 
1834     {
1835       back_input(); /* not a character put it back and leave */
1836       goto lab30; 
1837     } 
1838 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1839 /*  convert tilde '~' to pseudo tilde */
1840 /*  if (pseudo_tilde != 0 && cur_chr == '~') cur_chr = pseudo_tilde; */
1841 /*  convert space ' ' to pseudo space */
1842 /*  if (pseudo_space != 0 && cur_chr == ' ') cur_chr = pseudo_space; */
1843 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1844     if (!more_name(cur_chr))    /* up to next white space */
1845       goto lab30;
1846
1847     get_x_token();
1848   }
1849 lab30:
1850   end_name();
1851   name_in_progress = false;
1852 }
1853 /* argument is string .fmt, .log, or .dvi */
1854 /* sec 0529 */
1855 void pack_job_name_(str_number s)
1856 {
1857   cur_area = 335;       /* "" */
1858   cur_ext = s;
1859   cur_name = job_name;
1860   pack_file_name(cur_name, cur_area, cur_ext);
1861 }
1862
1863 /**********************************************************************/
1864 /* show TEXINPUTS=... or format specific  */
1865 /* only show this if name was not fully qualified ? */
1866 void show_tex_inputs (void)
1867 {
1868   char *s, *t, *v;
1869
1870   s = "TEXINPUTS";        /* default */
1871
1872   if (format_specific)
1873   {
1874     s = format_name;                /* try specific */
1875     if (grabenv(s) == NULL) s = "TEXINPUTS";  /* no format specific */
1876   }
1877
1878   if (grabenv(s) == NULL) s = "TEXINPUT";     /* 94/May/19 */
1879
1880   print_nl("  ");
1881   print_char(' ');
1882   print_char('(');
1883   t = s;
1884
1885   while (*t > '\0')
1886     print_char(*t++);
1887
1888   print_char('=');
1889   v = grabenv(s);
1890
1891   if (v != NULL)
1892   {
1893     t = v;
1894     while (*t > '\0')
1895       print_char(*t++);
1896   }
1897   print_char(')');
1898 }
1899
1900 /**********************************************************************/
1901 /* sec 0530 */
1902 void prompt_file_name_(str_number s, str_number e)/*  s - what can't be found, e - default */ 
1903 {
1904   integer k;
1905
1906   if (interaction == scroll_mode);
1907
1908   if (s == 781)
1909     print_err("I can't find file `");
1910   else
1911     print_err("I can't write on file `");
1912
1913   print_file_name(cur_name, cur_area, cur_ext);
1914   print_string("'.");
1915
1916   if (s == 781) /* input file name */
1917   {
1918     if (cur_area == 335) /* "" only if path not specified */
1919     {
1920       if (show_texinput_flag)
1921         show_tex_inputs();
1922     }
1923   }
1924
1925   if (e == 785)    /* .tex */
1926     show_context();
1927
1928   print_nl("Please type another ");
1929   print(s);
1930
1931   if (interaction < 2)
1932   {
1933     fatal_error("*** (job aborted, file error in nonstop mode)");
1934     return;     // abort_flag set
1935   }
1936
1937   if (!knuth_flag)
1938 #ifdef _WINDOWS
1939     show_line(" (or ^z to exit)", 0);
1940 #else
1941     show_line(" (or Ctrl-Z to exit)", 0);
1942 #endif
1943   {
1944     print_string(": ");
1945     term_input(": ", 0);
1946   }
1947 /*  should we deal with tilde and space in file name here ??? */
1948   {
1949     begin_name();
1950     k = first;
1951 /*  step over leading spaces ... */
1952     while ((buffer[k]== 32) && (k < last))
1953       incr(k);
1954 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1955     quoted_file_name = 0;         /* 98/March/15 */
1956
1957     if (allow_quoted_names && k < last) /* check whether quoted name */
1958     {
1959       if (buffer[k]== '"')
1960       {
1961         quoted_file_name = 1;
1962         incr(k);
1963       }
1964     }
1965
1966     while (true) {
1967       if (k == last)
1968         goto lab30;
1969 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1970 /*  convert tilde '~' to pseudo tilde */
1971       if (pseudo_tilde != 0 && buffer[k]== '~')
1972         buffer[k]= pseudo_tilde;
1973 /*  convert space ' ' to pseudo space */
1974       if (pseudo_space != 0 && buffer[k]== ' ')
1975         buffer[k]= pseudo_space;
1976 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1977       if (!more_name(buffer[k]))
1978         goto lab30;
1979       incr(k);
1980     }
1981 lab30:
1982     end_name();
1983   }
1984   if (cur_ext == 335)    /* "" */
1985     cur_ext = e;      /* use default extension */
1986   pack_file_name(cur_name, cur_area, cur_ext);
1987 }
1988 /* sec 0534 */
1989 void open_log_file (void)
1990 {
1991   char old_setting;
1992   integer k;
1993   integer l;
1994   ccharpointer months;
1995
1996   old_setting = selector;
1997
1998   if (job_name == 0)
1999     job_name = 790;   /* default:  texput */
2000
2001   pack_job_name(791); /* .log */
2002
2003   while (!a_open_out(log_file))
2004   {
2005     selector = term_only;
2006     prompt_file_name(793, 791); /* transcript file name  texput */
2007   }
2008   texmf_log_name = a_make_name_string(log_file);
2009   selector = log_only;
2010   log_opened = true;
2011   {
2012 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2013 //  for our version DOS/Windows
2014   if (want_version) {
2015 //    showversion (log_file);       /* in local.c - bkph */
2016 //    showversion (stdout);
2017     stamp_it(log_line);         // ??? use log_line ???
2018     strcat(log_line, "\n");
2019     (void) fputs(log_line, log_file);
2020 //    show_line(buffer, 0);        // ??? show on screen as well
2021 //    print_ln(); 
2022     stampcopy(log_line);
2023     strcat(log_line, "\n");
2024 //    show_line(buffer, 0);        // ??? show on screen as well
2025     (void) fputs(log_line, log_file);
2026 //    print_ln(); 
2027   }
2028 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2029 /*  also change following in itex.c - bkph */
2030   (void) fputs(tex_version,  log_file); 
2031   (void) fprintf(log_file, " (%s %s)", application, yandyversion);
2032   if (format_ident > 0)
2033     slow_print(format_ident);     /* bkph */
2034   print_string("  ");
2035 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2036   if (civilize_flag)
2037     print_int(year);
2038   else
2039     print_int(day);
2040 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2041     print_char(' ');
2042     months = " JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
2043     for (k = 3 * month - 2; k <= 3 * month; k++)
2044       (void) putc(months[k],  log_file);
2045     print_char(' ');
2046 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2047   if (civilize_flag)
2048     print_int(day);
2049   else
2050     print_int(year);
2051 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2052     print_char(' ');
2053     print_two(tex_time / 60);  /* hour */
2054     print_char(':');
2055     print_two(tex_time % 60);  /* minute */
2056   }
2057   input_stack[input_ptr] = cur_input;
2058   print_nl("**");
2059   l = input_stack[0].limit_field;
2060   if (buffer[l] == end_line_char)
2061     decr(l);
2062   for (k = 1; k <= l; k++)
2063     print(buffer[k]);
2064   print_ln(); 
2065 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2066 /* a good place to show the fmt file name or pool file name ? 94/June/21 */
2067   if (show_fmt_flag)
2068   {
2069     if (string_file != NULL)
2070     {
2071       fprintf(log_file, "(%s)\n", string_file);
2072       free(string_file);  /* this was allocated by strdup in openinou */
2073       string_file = NULL;   /* for safety */
2074     }
2075     if (format_file != NULL)
2076     {
2077       fprintf(log_file, "(%s)\n", format_file);
2078       free(format_file);  /* this was allocated by strdup in openinou */
2079       format_file = NULL;   /* for safety */
2080     }
2081   }
2082 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2083   selector = old_setting + 2;
2084 }
2085
2086 /**************************** start of insertion 98/Feb/7 **************/
2087
2088 // Attempt to deal with foo.bar.tex given as foo.bar on command line
2089 // Makes copy of job_name with extension
2090
2091 void morenamecopy(ASCII_code c)
2092 {
2093 #ifdef ALLOCATESTRING
2094   if (pool_ptr + 1 > current_pool_size)
2095     str_pool = realloc_str_pool (increment_pool_size);
2096   if (pool_ptr + 1 > current_pool_size)   { /* in case it failed 94/Jan/24 */
2097     overflow("pool size", current_pool_size - init_pool_ptr); /* 97/Mar/7 */
2098     return;     // abort_flag set
2099   }
2100 #else
2101   if (pool_ptr + 1 > pool_size){
2102     overflow("pool size", pool_size - init_pool_ptr); /* pool size */
2103     return;     // abort_flag set
2104   }
2105 #endif
2106   str_pool[pool_ptr]= c; 
2107   incr(pool_ptr); 
2108
2109
2110 int endnamecopy(void)
2111 {
2112 #ifdef ALLOCATESTRING
2113     if (str_ptr + 1 > current_max_strings)
2114       str_start = realloc_str_start(increment_max_strings + 1);
2115     if (str_ptr + 1 > current_max_strings) { /* in case it failed 94/Jan/24 */
2116       overflow("number of strings", current_max_strings - init_str_ptr);  /* 97/Mar/7 */
2117       return 0;     // abort_flag set
2118     }
2119 #else
2120     if (str_ptr + 1 > max_strings){
2121       overflow("number of strings", max_strings - init_str_ptr); /* number of strings */
2122       return 0;     // abort_flag set
2123     }
2124 #endif
2125     return make_string();
2126
2127
2128 void jobnameappend (void)
2129 { /* add extension to job_name */
2130   int k, n;
2131 /*  copy job_name */
2132   k = str_start[job_name];
2133   n = str_start[job_name + 1];
2134   while (k < n) morenamecopy(str_pool[k++]);
2135 /*  copy `extension' */
2136   k = str_start[cur_ext];
2137   n = str_start[cur_ext + 1];
2138   while (k < n) morenamecopy(str_pool[k++]);
2139   job_name = endnamecopy();
2140 }
2141
2142 /**************************** end of insertion 98/Feb/7 **************/
2143 /* sec 0537 */
2144 void start_input (void)
2145 {
2146   bool addedextension = false;
2147   scan_file_name();
2148   pack_file_name(cur_name, cur_area, cur_ext); 
2149
2150   while (true) {        /* loop until we get a valid file name */
2151     addedextension = false;
2152     begin_file_reading(); 
2153 /* *** *** *** *** *** following is new in 3.14159 *** *** *** *** *** *** */
2154 /*  if current extension is *not* empty, try to open using name as is */
2155 /*  string 335 is "" the empty string */
2156     if ((cur_ext != 335) && a_open_in(input_file[cur_input.index_field], TEXINPUTPATH))
2157       goto lab30;
2158 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2159 /*  we get here if extension is "", or file with extension failed to open */
2160 /*  if current extension is not `tex,' and `tex' is not irrelevant, try it */
2161 /*  string 785 is .tex */
2162 /*    (! extensionirrelevantp(name_of_file, "tex"))){ */
2163     if ((cur_ext != 785) && (name_length + 5 < PATHMAX) &&
2164         (! extensionirrelevantp(name_of_file, name_length, "tex")))
2165     {
2166       name_of_file[name_length + 1] = '.';
2167       name_of_file[name_length + 2] = 't';
2168       name_of_file[name_length + 3] = 'e';
2169       name_of_file[name_length + 4] = 'x';
2170       name_of_file[name_length + 5] = ' ';  /* 96/Jan/20 ??? */
2171       name_length = name_length + 4;
2172
2173       addedextension = true;
2174 /* *** *** *** ***  following new in 3.14159 *** *** *** *** *** *** *** */
2175       if (a_open_in(input_file[cur_input.index_field], TEXINPUTPATH))
2176         goto lab30;
2177       name_length = name_length - 4;      /* strip extension again */
2178       name_of_file[name_length + 1] = ' ';  /* ' ' */
2179       addedextension = false;
2180 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2181     }
2182 /* *** *** *** *** major changes here in 3.14159 *** *** *** *** *** *** */
2183 /*  string 335 is "" the empty string */
2184     if ((cur_ext == 335) && a_open_in(input_file[cur_input.index_field], TEXINPUTPATH))
2185       goto lab30;
2186     if (maketextex() && a_open_in(input_file[cur_input.index_field], TEXINPUTPATH))
2187       goto lab30;
2188 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2189     end_file_reading();
2190     prompt_file_name(781, 785); /* input file name  .tex */
2191   }   /* end of while(true)trying to get valid file name */
2192
2193 /* maybe set  pseudo_tilde = 0  at this point ? 95/Sep/26 */
2194 lab30: 
2195   cur_input.name_field = a_make_name_string(input_file[cur_input.index_field]);
2196
2197   if (job_name == 0)       /* only the first time */
2198   {
2199     job_name = cur_name;        /* here we set the job_name */
2200 /*  did file name have an `extension' already and we added ".tex" ? */
2201     if (cur_ext != 335 && addedextension)     /* 98/Feb/7 */
2202       jobnameappend();   /* append `extension' to job_name */
2203     open_log_file();
2204   }
2205   if (term_offset + length(cur_input.name_field) > max_print_line - 2) /* was 3 ? */
2206     print_ln();
2207   else if ((term_offset > 0) || (file_offset > 0))
2208     print_char(' ');
2209   print_char('(');
2210 //  print_char(64);       // debugging only marker
2211   incr(open_parens);
2212   if (open_parens > max_open_parens)
2213     max_open_parens = open_parens;    /* 1999/Jan/17 */
2214   slow_print(cur_input.name_field);
2215 //  print_char(64);       // debugging only marker
2216 #ifndef _WINDOWS
2217   fflush(stdout);
2218 #endif
2219   cur_input.state_field = new_line;
2220   {
2221     line = 1;
2222     if (input_ln(input_file[cur_input.index_field], false));
2223     firm_up_the_line();
2224     if ((end_line_char < 0) || (end_line_char > 255))
2225       decr(cur_input.limit_field);
2226     else
2227       buffer[cur_input.limit_field] = end_line_char;
2228     first = cur_input.limit_field + 1;
2229     cur_input.loc_field = cur_input.start_field;
2230   }
2231 }
2232
2233 /**********************************************************************/
2234 /* show TEXFONTS=... or format specific  */
2235 /* only show this if name was not fully qualified ? */
2236 void show_tex_fonts (void)
2237 {     /* 98/Jan/28 */
2238   char *s, *t, *v, *u;
2239   int n;
2240   s = "TEXFONTS";
2241   if (encoding_specific) {
2242     u = encoding_name;                /* try specific */
2243     if ((t = grabenv(u)) != NULL) {
2244       if (strchr(t, ':') != NULL &&
2245         sscanf(t, "%d", &n) == 0) {
2246         s = u;        /* look here instead of TEXFONTS=... */
2247       }
2248     }
2249   }
2250   print_nl("  ");
2251   print_char(' ');
2252   print_char('(');
2253   t = s;
2254   while (*t > '\0') print_char(*t++);
2255   print_char('=');
2256   v = grabenv(s);
2257   if (v != NULL) {
2258     t = v;
2259     while (*t > '\0') print_char(*t++);
2260   }
2261   print_char(')');
2262 }
2263
2264 /**********************************************************************/
2265
2266 /* called only from tex8.c */
2267 /* sec 0560 */
2268 internal_font_number read_font_info_(halfword u, str_number nom, str_number aire, scaled s)
2269 {
2270   register internal_font_number Result;
2271   font_index k;
2272   bool fileopened;
2273 /*  halfword lf, lh, bc, ec, nw, nh, nd, ni, nl, nk, ne, np;  */
2274   halfword lf, lh, nw, nh, nd, ni, nl, nk, ne, np;
2275 /*  halfword bc, ec; */
2276   int bc, ec;             /* 95/Jan/7 */
2277   internal_font_number f;
2278   internal_font_number g;
2279   eight_bits a, b, c, d;
2280   ffourquarters qw;
2281   scaled sw;
2282   integer bchlabel;
2283   short bchar;
2284   scaled z;
2285   integer alpha;
2286   char beta;
2287
2288   g = 0;
2289   fileopened = false;
2290   pack_file_name(nom, aire, 805); /* .tfm */
2291   if (!b_open_in(tfm_file)) /* new in C version d */
2292   {
2293     if (maketextfm ())
2294     {
2295       if (!b_open_in(tfm_file))
2296         goto lab11;
2297     }
2298     else goto lab11;
2299   } 
2300 /*   was just: goto lab11; */
2301   fileopened = true; 
2302   {
2303 /*  tfm_temp = getc(tfm_file);  */ /* done already in open_input, but why? */
2304     {
2305       lf = tfm_temp;
2306       if (lf > 127)
2307         goto lab11;
2308       tfm_temp = getc(tfm_file);
2309       lf = lf * 256 + tfm_temp;
2310     }
2311     tfm_temp = getc(tfm_file);
2312     {
2313       lh = tfm_temp;
2314       if (lh > 127)
2315         goto lab11;
2316       tfm_temp = getc(tfm_file);
2317       lh = lh * 256 + tfm_temp;
2318     }
2319     tfm_temp = getc(tfm_file);
2320     {
2321       bc = tfm_temp;
2322       if (bc > 127)
2323         goto lab11;
2324       tfm_temp = getc(tfm_file);
2325       bc = bc * 256 + tfm_temp;
2326     }
2327     tfm_temp = getc(tfm_file);
2328     {
2329       ec = tfm_temp;
2330       if (ec > 127)
2331         goto lab11;
2332       tfm_temp = getc(tfm_file);
2333       ec = ec * 256 + tfm_temp;
2334     }
2335     if ((bc > ec + 1)||(ec > 255))
2336       goto lab11;
2337     if (bc > 255)
2338     {
2339       bc = 1;
2340       ec = 0;
2341     }
2342     tfm_temp = getc(tfm_file);
2343     {
2344       nw = tfm_temp;
2345       if (nw > 127)
2346         goto lab11;
2347       tfm_temp = getc(tfm_file);
2348       nw = nw * 256 + tfm_temp;
2349     }
2350     tfm_temp = getc(tfm_file);
2351     {
2352       nh = tfm_temp;
2353       if (nh > 127)
2354         goto lab11;
2355       tfm_temp = getc(tfm_file);
2356       nh = nh * 256 + tfm_temp;
2357     }
2358     tfm_temp = getc(tfm_file);
2359     {
2360       nd = tfm_temp;
2361       if (nd > 127)
2362         goto lab11;
2363       tfm_temp = getc(tfm_file);
2364       nd = nd * 256 + tfm_temp;
2365     }
2366     tfm_temp = getc(tfm_file);
2367     {
2368       ni = tfm_temp;
2369       if (ni > 127)
2370         goto lab11;
2371       tfm_temp = getc(tfm_file);
2372       ni = ni * 256 + tfm_temp;
2373     }
2374     tfm_temp = getc(tfm_file);
2375     {
2376       nl = tfm_temp;
2377       if (nl > 127)
2378         goto lab11;
2379       tfm_temp = getc(tfm_file);
2380       nl = nl * 256 + tfm_temp;
2381     }
2382     tfm_temp = getc(tfm_file);
2383     {
2384       nk = tfm_temp;
2385       if (nk > 127)
2386         goto lab11;
2387       tfm_temp = getc(tfm_file);
2388       nk = nk * 256 + tfm_temp;
2389     }
2390     tfm_temp = getc(tfm_file);
2391     {
2392       ne = tfm_temp;
2393       if (ne > 127)
2394         goto lab11;
2395       tfm_temp = getc(tfm_file);
2396       ne = ne * 256 + tfm_temp;
2397     }
2398     tfm_temp = getc(tfm_file);
2399     {
2400       np = tfm_temp;
2401       if (np > 127)
2402         goto lab11;
2403       tfm_temp = getc(tfm_file);
2404       np = np * 256 + tfm_temp;
2405     }
2406     if (lf != 6 + lh + (ec - bc + 1) + nw + nh + nd + ni + nl + nk + ne + np)
2407       goto lab11;
2408     if ((nw == 0) || (nh == 0) || (nd == 0) || (ni == 0))
2409       goto lab11;
2410   }
2411   lf = lf - 6 - lh;
2412   if (np < 7)
2413     lf = lf + 7 - np;
2414 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2415 #ifdef ALLOCATEFONT
2416   if ((fmem_ptr + lf > current_font_mem_size))   /* 93/Nov/28 */
2417     font_info = realloc_font_info (increment_font_mem_size + lf);
2418   if ((font_ptr == font_max) || (fmem_ptr + lf > current_font_mem_size))
2419 #else
2420 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2421   if ((font_ptr == font_max) || (fmem_ptr + lf > font_mem_size))
2422 #endif
2423   {
2424 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2425     if (trace_flag)
2426     {
2427       sprintf(log_line, "font_ptr %d font_max %d fmem_ptr %d lf %d font_mem_size %d\n",
2428           font_ptr, font_max, fmem_ptr, lf, font_mem_size); /* debugging */
2429       show_line(log_line, 0);
2430     }
2431 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2432     print_err("Font ");
2433     sprint_cs(u);
2434     print_char('=');
2435     print_file_name(nom, aire, 335); /* "" */
2436     if (s >= 0)
2437     {
2438       print_string(" at ");
2439       print_scaled(s);
2440       print_string("pt");
2441     }
2442     else if (s != -1000)
2443     {
2444       print_string(" scaled ");
2445       print_int(- (integer) s);
2446     }
2447     print_string(" not loaded: Not enough room left");
2448     help4("I'm afraid I won't be able to make use of this font,",
2449         "because my memory for character-size data is too small.",
2450         "If you're really stuck, ask a wizard to enlarge me.",
2451         "Or maybe try `I\\font<same font id>=<name of loaded font>'.");
2452     error();
2453     goto lab30;
2454   }
2455   f = font_ptr + 1;
2456   char_base[f] = fmem_ptr - bc;
2457   width_base[f] = char_base[f] + ec + 1;
2458   height_base[f] = width_base[f] + nw;
2459   depth_base[f] = height_base[f] + nh;
2460   italic_base[f] = depth_base[f] + nd;
2461   lig_kern_base[f] = italic_base[f] + ni;
2462   kern_base[f] = lig_kern_base[f] + nl - 256 * (128);
2463   exten_base[f] = kern_base[f] + 256 *(128) + nk;
2464   param_base[f] = exten_base[f] + ne;
2465   {
2466     if (lh < 2)
2467       goto lab11;
2468 /*  build the font checksum now */
2469     {
2470       tfm_temp = getc(tfm_file);
2471       a = tfm_temp;
2472       qw.b0 = a;
2473       tfm_temp = getc(tfm_file);
2474       b = tfm_temp;
2475       qw.b1 = b;
2476       tfm_temp = getc(tfm_file);
2477       c = tfm_temp;
2478       qw.b2 = c;
2479       tfm_temp = getc(tfm_file);
2480       d = tfm_temp;
2481       qw.b3 = d;
2482       font_check[f] = qw;
2483     }
2484     tfm_temp = getc(tfm_file);
2485     {
2486       z = tfm_temp;
2487       if (z > 127)
2488         goto lab11;
2489       tfm_temp = getc(tfm_file);
2490       z = z * 256 + tfm_temp;
2491     }
2492     tfm_temp = getc(tfm_file);
2493     z = z * 256 + tfm_temp;
2494     tfm_temp = getc(tfm_file);
2495     z =(z * 16) + (tfm_temp / 16);
2496     if (z < 65536L)
2497       goto lab11; 
2498     while (lh > 2) {
2499       tfm_temp = getc(tfm_file);
2500       tfm_temp = getc(tfm_file);
2501       tfm_temp = getc(tfm_file);
2502       tfm_temp = getc(tfm_file);
2503       decr(lh);
2504     }
2505     font_dsize[f] = z;
2506     if (s != -1000)
2507       if (s >= 0)
2508         z = s;
2509       else
2510         z = xn_over_d(z, - (integer) s, 1000);
2511     font_size[f] = z;
2512   }
2513
2514   for (k = fmem_ptr; k <= width_base[f] - 1; k++)
2515   {
2516     {
2517       tfm_temp = getc(tfm_file);
2518       a = tfm_temp;
2519       qw.b0 = a;
2520       tfm_temp = getc(tfm_file);
2521       b = tfm_temp;
2522       qw.b1 = b;
2523       tfm_temp = getc(tfm_file);
2524       c = tfm_temp;
2525       qw.b2 = c;
2526       tfm_temp = getc(tfm_file);
2527       d = tfm_temp;
2528       qw.b3 = d;
2529       font_info[k].qqqq = qw;
2530     }
2531     if ((a >= nw) || (b / 16 >= nh) || (b % 16 >= nd) || (c / 4 >= ni))
2532       goto lab11;
2533     switch (c % 4)
2534     {
2535       case 1 :
2536         if (d >= nl)
2537           goto lab11;
2538         break;
2539       case 3 :
2540         if (d >= ne)
2541           goto lab11;
2542         break;
2543       case 2 :
2544         {
2545           {
2546             if ((d < bc)||(d > ec))
2547               goto lab11;
2548           }
2549           while (d < k + bc - fmem_ptr) {
2550             qw = font_info[char_base[f]+ d].qqqq;
2551             if (((qw.b2)% 4)!= 2)
2552               goto lab45;
2553             d = qw.b3;
2554           }
2555           if (d == k + bc - fmem_ptr)
2556             goto lab11;
2557 lab45:; 
2558         }
2559         break;
2560       default:
2561         break;
2562     }
2563   }
2564   {
2565     {
2566       alpha = 16;
2567       while (z >= 8388608L) {   /* 2^23 */
2568         z = z / 2;
2569         alpha = alpha + alpha;
2570       }
2571       beta = (char) (256 / alpha);
2572       alpha = alpha * z;
2573     }
2574
2575     for (k = width_base[f]; k <= lig_kern_base[f] - 1; k++)
2576     {
2577       tfm_temp = getc(tfm_file);
2578       a = tfm_temp;
2579       tfm_temp = getc(tfm_file);
2580       b = tfm_temp;
2581       tfm_temp = getc(tfm_file);
2582       c = tfm_temp;
2583       tfm_temp = getc(tfm_file);
2584       d = tfm_temp;
2585       sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2586       if (a == 0)
2587         font_info[k].cint = sw;
2588       else if (a == 255)
2589         font_info[k].cint = sw - alpha;
2590       else
2591         goto lab11;
2592     }
2593     if (font_info[width_base[f]].cint != 0)
2594       goto lab11;
2595     if (font_info[height_base[f]].cint != 0)
2596       goto lab11;
2597     if (font_info[depth_base[f]].cint != 0)
2598       goto lab11;
2599     if (font_info[italic_base[f]].cint != 0)
2600       goto lab11;
2601   }
2602 /*  read ligature/kern program */
2603   bchlabel = 32767;     /* '77777 */
2604   bchar = 256;
2605   if (nl > 0)
2606   {
2607     for (k = lig_kern_base[f]; k <= kern_base[f] + 256 * (128)- 1; k++)
2608     {
2609       {
2610         tfm_temp = getc(tfm_file);
2611         a = tfm_temp;
2612         qw.b0 = a;
2613         tfm_temp = getc(tfm_file);
2614         b = tfm_temp;
2615         qw.b1 = b;
2616         tfm_temp = getc(tfm_file);
2617         c = tfm_temp;
2618         qw.b2 = c;
2619         tfm_temp = getc(tfm_file);
2620         d = tfm_temp;
2621         qw.b3 = d;
2622         font_info[k].qqqq = qw; /* store_four_quarters(font_info[k].qqqq */
2623       }
2624       if (a > 128)
2625       {
2626         if (256 * c + d >= nl)
2627           goto lab11;       /* error in TFM, abort */
2628         if (a == 255)
2629           if (k == lig_kern_base[f])
2630             bchar = b;
2631       }
2632       else
2633       {
2634         if (b != bchar)
2635         {
2636           {
2637             if ((b < bc) || (b > ec))  /* check-existence(b) */
2638               goto lab11;         /* error in TFM, abort */
2639           }
2640           qw = font_info[char_base[f] + b].qqqq;
2641           if (!(qw.b0 > 0))
2642             goto lab11;         /* error in TFM, abort */
2643         }
2644         if (c < 128)
2645         {
2646           {
2647             if ((d < bc) || (d > ec))  /* check-existence(d) */
2648               goto lab11;         /* error in TFM, abort */
2649           }
2650           qw = font_info[char_base[f] + d].qqqq;
2651           if (!(qw.b0 > 0))
2652             goto lab11;         /* error in TFM, abort */
2653         }
2654         else if (256 * (c - 128) + d >= nk)
2655           goto lab11;           /* error in TFM, abort */
2656         if (a < 128)
2657           if (k - lig_kern_base[f] + a + 1 >= nl)
2658             goto lab11;         /* error in TFM, abort */
2659       }
2660     }
2661     if (a == 255)
2662       bchlabel = 256 * c + d;
2663   }
2664
2665   for (k = kern_base[f] + 256 * (128); k <= exten_base[f] - 1; k++)
2666   {
2667     tfm_temp = getc(tfm_file);
2668     a = tfm_temp;
2669     tfm_temp = getc(tfm_file);
2670     b = tfm_temp;
2671     tfm_temp = getc(tfm_file);
2672     c = tfm_temp;
2673     tfm_temp = getc(tfm_file);
2674     d = tfm_temp;
2675     sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2676     if (a == 0)
2677       font_info[k].cint = sw;
2678     else if (a == 255)
2679       font_info[k].cint = sw - alpha;
2680     else goto lab11;
2681   }
2682 /*  read extensible character recipes */
2683 /*  for k:=exten_base[f] to param_base[f]-1 do */
2684   for (k = exten_base[f]; k <= param_base[f] - 1; k++)
2685   {
2686     {
2687       tfm_temp = getc(tfm_file);
2688       a = tfm_temp;
2689       qw.b0 = a;
2690       tfm_temp = getc(tfm_file);
2691       b = tfm_temp;
2692       qw.b1 = b;
2693       tfm_temp = getc(tfm_file);
2694       c = tfm_temp;
2695       qw.b2 = c;
2696       tfm_temp = getc(tfm_file);
2697       d = tfm_temp;
2698       qw.b3 = d;
2699 /*    store_four_quarters(font_info[k].qqqq); */
2700       font_info[k].qqqq = qw;
2701     }
2702     if (a != 0)
2703     {
2704       {
2705         if ((a < bc) || (a > ec))
2706           goto lab11;
2707       }
2708       qw = font_info[char_base[f] + a].qqqq;
2709       if (!(qw.b0 > 0))
2710         goto lab11;
2711     }
2712     if (b != 0)
2713     {
2714       {
2715         if ((b < bc) || (b > ec))
2716           goto lab11;
2717       }
2718       qw = font_info[char_base[f] + b].qqqq;
2719       if (!(qw.b0 > 0))
2720         goto lab11;
2721     }
2722     if (c != 0)
2723     {
2724       {
2725         if ((c < bc) || (c > ec))
2726           goto lab11;
2727       }
2728       qw = font_info[char_base[f] + c].qqqq;
2729       if (!(qw.b0 > 0))
2730         goto lab11;
2731     }
2732     {
2733       {
2734         if ((d < bc) || (d > ec))
2735           goto lab11;
2736       }
2737       qw = font_info[char_base[f] + d].qqqq;
2738       if (!(qw.b0 > 0))
2739         goto lab11;
2740     }
2741   }
2742   {
2743     for (k = 1; k <= np; k++)
2744       if (k == 1)
2745       {
2746         tfm_temp = getc(tfm_file);
2747         sw = tfm_temp;
2748         if (sw > 127)
2749           sw = sw - 256;
2750         tfm_temp = getc(tfm_file);
2751         sw = sw * 256 + tfm_temp;
2752         tfm_temp = getc(tfm_file);
2753         sw = sw * 256 + tfm_temp;
2754         tfm_temp = getc(tfm_file);
2755         font_info[param_base[f]].cint = (sw * 16) + (tfm_temp / 16);
2756       }
2757       else
2758       {
2759         tfm_temp = getc(tfm_file);
2760         a = tfm_temp;
2761         tfm_temp = getc(tfm_file);
2762         b = tfm_temp;
2763         tfm_temp = getc(tfm_file);
2764         c = tfm_temp;
2765         tfm_temp = getc(tfm_file);
2766         d = tfm_temp;
2767         sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2768         if (a == 0)
2769           font_info[param_base[f] + k - 1].cint = sw;
2770         else if (a == 255)
2771           font_info[param_base[f] + k - 1].cint = sw - alpha;
2772         else goto lab11;
2773       }
2774 /*  use test_eof() here instead ? */
2775     if (feof(tfm_file))
2776       goto lab11;
2777     for (k = np + 1; k <= 7; k++)
2778       font_info[param_base[f] + k - 1].cint = 0;
2779   }
2780 /* @<Make final adjustments...@>= l.11174 */
2781   if (np >= 7)
2782     font_params[f] = np;
2783   else
2784     font_params[f] = 7;
2785   hyphen_char[f] = default_hyphen_char;
2786   skew_char[f] = default_skew_char;
2787   if (bchlabel < nl)
2788     bchar_label[f] = bchlabel + lig_kern_base[f];
2789   else
2790     bchar_label[f]= non_address; /* i.e. 0 --- 96/Jan/15 */
2791   font_bchar[f] = bchar;
2792   font_false_bchar[f] = bchar;
2793   if (bchar <= ec)
2794     if (bchar >= bc)
2795     {
2796       qw = font_info[char_base[f] + bchar].qqqq;
2797       if ((qw.b0 > 0))
2798         font_false_bchar[f] = 256;
2799     }
2800   font_name[f] = nom;
2801   font_area[f] = aire;
2802   font_bc[f] = bc;
2803   font_ec[f] = ec;
2804   font_glue[f] = 0;  /* font_glue[f]:=null; l.11184 */
2805   char_base[f] = char_base[f];
2806   width_base[f] = width_base[f];
2807   lig_kern_base[f] = lig_kern_base[f];
2808   kern_base[f] = kern_base[f];
2809   exten_base[f] = exten_base[f];
2810   decr(param_base[f]);
2811   fmem_ptr = fmem_ptr + lf;
2812   font_ptr = f;
2813   g = f;
2814   goto lab30;
2815 lab11:
2816   print_err("Font ");
2817   sprint_cs(u); 
2818   print_char('=');
2819   print_file_name(nom, aire, 335);  /* "" */
2820   if (s >= 0)
2821   {
2822     print_string(" at ");
2823     print_scaled(s);
2824     print_string("pt");
2825   }
2826   else if (s != -1000)
2827   {
2828     print_string("scaled");
2829     print_int(- (integer) s);
2830   } 
2831   if (fileopened)
2832     print_string(" not loadable: Bad metric (TFM) file");
2833   else
2834     print_string(" not loadable: Metric (TFM) file not found");
2835   if (aire == 335)
2836   {    /* "" only if path not specified */
2837     if (show_texinput_flag) show_tex_fonts();   /* 98/Jan/31 */
2838   }
2839   help5("I wasn't able to read the size data for this font,",
2840       "so I will ignore the font specification.",
2841       "[Wizards can fix TFM files using TFtoPL/PLtoTF.]",
2842       "You might try inserting a different font spec;",
2843       "e.g., type `I\\font<same font id>=<substitute font name>'.");
2844   error();
2845 lab30:
2846   if (fileopened)
2847     b_close(tfm_file);
2848   Result = g;
2849   return Result;
2850 }