OSDN Git Service

3e76e0280eceb49d5ac5be8e044ebac3331db459
[putex/putex.git] / src / texsourc / tex8.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 #pragma warning(disable:4996)
12 #pragma warning(disable:4131) // old style declarator
13 #pragma warning(disable:4135) // conversion between different integral types 
14 #pragma warning(disable:4127) // conditional expression is constant
15
16 #include <setjmp.h>
17
18 #define EXTERN extern
19
20 #include "texd.h"
21
22 #pragma warning(disable:4244)       /* 96/Jan/10 */
23
24 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
25
26 /* math_fraction etc used to be in tex7.c */
27 /* sec 1181 */
28 void math_fraction (void)
29 {
30   small_number c;
31
32   c = cur_chr;
33
34   if (incompleat_noad != 0)
35   {
36     if (c >= delimited_code)
37     {
38       scan_delimiter(garbage, false);
39       scan_delimiter(garbage, false);
40     }
41
42     if (c % delimited_code == 0)
43       scan_dimen(false, false, false);
44
45     print_err("Ambiguous; you need another { and }");
46     help3("I'm ignoring this fraction specification, since I don't",
47       "know whether a construction like `x \\over y \\over z'",
48       "means `{x \\over y} \\over z' or `x \\over {y \\over z}'.");
49     error();
50   }
51   else
52   {
53     incompleat_noad = get_node(fraction_noad_size);
54     type(incompleat_noad) = fraction_noad;
55     subtype(incompleat_noad) = normal;
56     math_type(numerator(incompleat_noad)) = sub_mlist;
57     info(numerator(incompleat_noad)) = link(head);
58     mem[denominator(incompleat_noad)].hh = empty_field;
59     mem[left_delimiter(incompleat_noad)].qqqq = null_delimiter;
60     mem[right_delimiter(incompleat_noad)].qqqq = null_delimiter;
61     link(head) = 0;
62     tail = head;
63
64     if (c >= delimited_code)
65     {
66       scan_delimiter(left_delimiter(incompleat_noad), false);
67       scan_delimiter(right_delimiter(incompleat_noad), false);
68     }
69
70     switch(c % delimited_code)
71     {
72       case above_code:
73         scan_dimen(false, false, false);
74         thickness(incompleat_noad) = cur_val;
75         break;
76
77       case over_code:
78         thickness(incompleat_noad) = default_code;
79         break;
80
81       case atop_code:
82         thickness(incompleat_noad) = 0;
83         break;
84     }
85   }
86 }
87 /* sec 1191 */
88 void math_left_right (void)
89 {
90   small_number t;
91   halfword p;
92
93   t = cur_chr;
94
95   if ((t == right_noad) && (cur_group != math_left_group))
96   {
97     if (cur_group == math_shift_group)
98     {
99       scan_delimiter(garbage, false);
100       print_err("Extra ");
101       print_esc("right");
102       help1("I'm ignoring a \\right that had no matching \\left.");
103       error();
104     }
105     else
106     {
107       off_save();
108     }
109   }
110   else
111   {
112     p = new_noad();
113     type(p) = t;
114     scan_delimiter(delimiter(p), false);
115
116     if (t == left_noad)
117     {
118       push_math(math_left_group);
119       link(tail) = p;
120       tail = p;
121     }
122     else
123     {
124       p = fin_mlist(p);
125       unsave();
126       tail_append(new_noad());
127       type(tail) = inner_noad;
128       math_type(nucleus(tail)) = sub_mlist;
129       info(nucleus(tail)) = p;
130     }
131   }
132 }
133 /* sec 1194 */
134 void after_math (void)
135 {
136   bool l;
137   bool danger;
138   integer m;
139   halfword p;
140   halfword a;
141   halfword b;
142   scaled w;
143   scaled z;
144   scaled e;
145   scaled q;
146   scaled d;
147   scaled s;
148   small_number g1, g2;
149   halfword r;
150   halfword t;
151
152   danger = false;
153   
154   if ((font_params[fam_fnt(2 + text_size)] < total_mathsy_params) ||
155     (font_params[fam_fnt(2 + script_size)] < total_mathsy_params) ||
156     (font_params[fam_fnt(2 + script_script_size)] < total_mathsy_params))
157   {
158     print_err("Math formula deleted: Insufficient symbol fonts");
159     help3("Sorry, but I can't typeset math unless \\textfont 2",
160         "and \\scriptfont 2 and \\scriptscriptfont 2 have all",
161         "the \\fontdimen values needed in math symbol fonts.");
162     error();
163     flush_math();
164     danger = true;
165   }
166   else if ((font_params[fam_fnt(3 + text_size)] < total_mathex_params) ||
167     (font_params[fam_fnt(3 + script_size)] < total_mathex_params) ||
168     (font_params[fam_fnt(3 + script_script_size)] < total_mathex_params))
169   {
170     print_err("Math formula deleted: Insufficient extension fonts");
171     help3("Sorry, but I can't typeset math unless \\textfont 3",
172         "and \\scriptfont 3 and \\scriptscriptfont 3 have all",
173         "the \\fontdimen values needed in math extension fonts.");
174     error();
175     flush_math();
176     danger = true;
177   }
178
179   m = mode;
180   l = false;
181   p = fin_mlist(0);
182
183   if (mode == - (integer) m)
184   {
185     {
186       get_x_token();
187
188       if (cur_cmd != math_shift)
189       {
190         print_err("Display math should end with $$");
191         help2("The `$' that I just saw supposedly matches a previous `$$'.",
192             "So I shall assume that you typed `$$' both times.");
193         back_error();
194       }
195     }
196
197     cur_mlist = p;
198     cur_style = text_style;
199     mlist_penalties = false;
200     mlist_to_hlist();
201     a = hpack(link(temp_head), 0, 1);
202     unsave();
203     decr(save_ptr);
204
205     if (saved(0) == 1)
206       l = true;
207
208     danger = false;
209
210     if ((font_params[fam_fnt(2 + text_size)] < total_mathsy_params) ||
211       (font_params[fam_fnt(2 + script_size)] < total_mathsy_params) ||
212       (font_params[fam_fnt(2 + script_script_size)] < total_mathsy_params))
213     {
214       print_err("Math formula deleted: Insufficient symbol fonts");
215       help3("Sorry, but I can't typeset math unless \\textfont 2",
216           "and \\scriptfont 2 and \\scriptscriptfont 2 have all",
217           "the \\fontdimen values needed in math symbol fonts.");
218       error();
219       flush_math();
220       danger = true;
221     }
222     else if ((font_params[fam_fnt(3 + text_size)] < total_mathex_params) ||
223       (font_params[fam_fnt(3 + script_size)] < total_mathex_params) ||
224       (font_params[fam_fnt(3 + script_script_size)] < total_mathex_params))
225     {
226       print_err("Math formula deleted: Insufficient extension fonts");
227       help3("Sorry, but I can't typeset math unless \\textfont 3",
228         "and \\scriptfont 3 and \\scriptscriptfont 3 have all",
229         "the \\fontdimen values needed in math extension fonts.");
230       error();
231       flush_math();
232       danger = true;
233     }
234
235     m = mode;
236     p = fin_mlist(0);
237   }
238   else
239     a = 0;
240
241   if (m < 0)
242   {
243     tail_append(new_math(math_surround, 0));
244     cur_mlist = p;
245     cur_style = text_style;
246     mlist_penalties = (mode > 0);
247     mlist_to_hlist();
248     link(tail) = link(temp_head);
249
250     while(link(tail) != 0)
251       tail = link(tail);
252
253     tail_append(new_math(math_surround, 1));
254     space_factor = 1000;
255     unsave();
256   }
257   else
258   {
259     if (a == 0)
260     {
261       get_x_token();
262
263       if (cur_cmd != math_shift)
264       {
265         print_err("Display math should end with $$");
266         help2("The `$' that I just saw supposedly matches a previous `$$'.",
267             "So I shall assume that you typed `$$' both times.");
268         back_error();
269       }
270     }
271
272     cur_mlist = p;
273     cur_style = display_style;
274     mlist_penalties = false;
275     mlist_to_hlist();
276     p = link(temp_head);
277     adjust_tail = adjust_head;
278     b = hpack(p, 0, 1);
279     p = list_ptr(b);
280     t = adjust_tail;
281     adjust_tail = 0;
282     w = width(b);
283     z = display_width;
284     s = display_indent;
285
286     if ((a == 0) || danger)
287     {
288       e = 0;
289       q = 0;
290     }
291     else
292     {
293       e = width(a);
294       q = e + math_quad(text_size);
295     }
296
297     if (w + q > z)
298     {
299       if ((e != 0) && ((w - total_shrink[normal] + q <= z) || (total_shrink[fil] != 0) || (total_shrink[fill] != 0) || (total_shrink[filll] != 0)))
300       {
301         free_node(b, box_node_size);
302         b = hpack(p, z - q, 0);
303       }
304       else
305       {
306         e = 0;
307
308         if (w > z)
309         {
310           free_node(b, box_node_size);
311           b = hpack(p, z, 0);
312         }
313       }
314       w = width(b);
315     }
316
317     d = half(z - w);
318
319     if ((e > 0) && (d < 2 * e))
320     {
321       d = half(z - w - e);
322
323       if (p != 0)
324         if (!(p >= hi_mem_min))
325           if (type(p) == glue_node)
326             d = 0;
327     }
328
329     tail_append(new_penalty(pre_display_penalty));
330
331     if ((d + s <= pre_display_size) || l)
332     {
333       g1 = above_display_skip_code;
334       g2 = below_display_skip_code;
335     }
336     else
337     {
338       g1 = above_display_short_skip_code;
339       g2 = below_display_short_skip_code;
340     }
341     if (l && (e == 0))
342     {
343       shift_amount(a) = s;
344       append_to_vlist(a);
345       tail_append(new_penalty(10000));
346     }
347     else
348     {
349       tail_append(new_param_glue(g1));
350     }
351
352     if (e != 0)
353     {
354       r = new_kern(z - w - e - d);
355
356       if (l)
357       {
358         link(a) = r;
359         link(r) = b;
360         b = a;
361         d = 0;
362       }
363       else
364       {
365         link(b) = r;
366         link(r) = a;
367       }
368       b = hpack(b, 0, 1);
369     }
370
371     shift_amount(b) = s + d;
372     append_to_vlist(b);
373
374     if ((a != 0) && (e == 0) && !l)
375     {
376       tail_append(new_penalty(10000));
377       shift_amount(a) = s + z - width(a);
378       append_to_vlist(a);
379       g2 = 0;
380     }
381
382     if (t != adjust_head)
383     {
384       link(tail) = link(adjust_head);
385       tail = t;
386     }
387
388     tail_append(new_penalty(post_display_penalty));
389
390     if (g2 > 0)
391     {
392       tail_append(new_param_glue(g2));
393     }
394
395     resume_after_display();
396   }
397 }
398 /* sec 1200 */
399 void resume_after_display (void)
400 {
401   if (cur_group != math_shift_group)
402   {
403     confusion("display");
404     return;       // abort_flag set
405   }
406
407   unsave();
408   prev_graf = prev_graf + 3;
409   push_nest();
410   mode = hmode;
411   space_factor = 1000;
412   set_cur_lang();
413   clang = cur_lang;
414   prev_graf =(norm_min(left_hyphen_min) * 64 + norm_min(right_hyphen_min)) * 65536L + cur_lang;
415
416   {
417     get_x_token();
418
419     if (cur_cmd != spacer)
420       back_input();
421   }
422
423   if (nest_ptr == 1)
424   {
425     build_page();
426   }
427 }
428 /* sec 1215 */
429 void get_r_token (void)
430 {
431 lab20:
432   do
433     {
434       get_token();
435     }
436     while (!(cur_tok != space_token));
437
438   if ((cur_cs == 0) || (cur_cs > frozen_control_sequence))
439   {
440     print_err("Missing control sequence inserted");
441     help5("Please don't say `\\def cs{...}', say `\\def\\cs{...}'.",
442       "I've inserted an inaccessible control sequence so that your",
443       "definition will be completed without mixing me up too badly.",
444       "You can recover graciously from this error, if you're",
445       "careful; see exercise 27.2 in The TeXbook.");
446
447     if (cur_cs == 0)
448       back_input();
449
450     cur_tok = cs_token_flag + frozen_protection;
451     ins_error();
452     goto lab20;
453   }
454 }
455 /* sec 1229 */
456 void trap_zero_glue (void)
457 {
458   if ((width(cur_val) == 0) && (stretch(cur_val) == 0) && (shrink(cur_val) == 0))
459   {
460     add_glue_ref(zero_glue);
461     delete_glue_ref(cur_val);
462     cur_val = 0;
463   }
464 }
465 /* sec 1236 */
466 void do_register_command_ (small_number a)
467 {
468   halfword l, q, r, s;
469   char p;
470
471   q = cur_cmd;
472
473   {
474     if (q != tex_register)
475     {
476       get_x_token();
477
478       if ((cur_cmd >= assign_int) && (cur_cmd <= assign_mu_glue))
479       {
480         l = cur_chr;
481         p = cur_cmd - assign_int;
482         goto lab40;
483       }
484
485       if (cur_cmd != tex_register)
486       {
487         print_err("You can't use `");
488         print_cmd_chr(cur_cmd, cur_chr);
489         print_string("' after ");
490         print_cmd_chr(q, 0);
491         help1("I'm forgetting what you said and not changing anything.");
492         error();
493         return;
494       }
495     }
496
497     p = cur_chr;
498     scan_eight_bit_int();
499
500     switch(p)
501     {
502       case int_val:
503         l = cur_val + count_base;
504         break;
505
506       case dimen_val:
507         l = cur_val + scaled_base;
508         break;
509
510       case glue_val:
511         l = cur_val + skip_base;
512         break;
513
514       case mu_val:
515         l = cur_val + mu_skip_base;
516         break;
517     }
518   }
519 lab40:;
520
521   if (q == tex_register)
522     scan_optional_equals();
523   else
524     if (scan_keyword("by"));
525
526   arith_error = false;
527
528   if (q < multiply)
529     if (p < glue_val)
530     {
531       if (p == int_val)
532         scan_int();
533       else
534         scan_dimen(false, false, false);
535
536       if (q == advance)
537         cur_val = cur_val + eqtb[l].cint;
538     }
539     else
540     {
541       scan_glue(p);
542
543       if (q == advance)
544       {
545         q = new_spec(cur_val);
546         r = equiv(l);
547         delete_glue_ref(cur_val);
548         width(q) = width(q) + width(r);
549
550         if (stretch(q) == 0)
551           stretch_order(q) = normal;
552
553         if (stretch_order(q) == stretch_order(r))
554           stretch(q) = stretch(q) + stretch(r);
555         else if ((stretch_order(q) < stretch_order(r)) && (stretch(r) != 0))
556         {
557           stretch(q) = stretch(r);
558           stretch_order(q) = stretch_order(r);
559         }
560
561         if (shrink(q) == 0)
562           shrink_order(q) = normal;
563
564         if (shrink_order(q) == shrink_order(r))
565           shrink(q) = shrink(q) + shrink(r);
566         else if ((shrink_order(q) < shrink_order(r)) && (shrink(r) != 0))
567         {
568           shrink(q) = shrink(r);
569           shrink_order(q) = shrink_order(r);
570         }
571         cur_val = q;
572       }
573     }
574   else
575   {
576     scan_int();
577
578     if (p < glue_val)
579       if (q == multiply)
580         if (p == int_val)
581           cur_val = mult_and_add(eqtb[l].cint, cur_val, 0, 2147483647L); /*  2^31 - 1 */
582         else
583           cur_val = mult_and_add(eqtb[l].cint, cur_val, 0, 1073741823L); /*  2^30 - 1 */
584       else
585         cur_val = x_over_n(eqtb[l].cint, cur_val);
586     else
587     {
588       s = equiv(l);
589       r = new_spec(s);
590
591       if (q == multiply)
592       {
593         width(r) = mult_and_add(width(s), cur_val, 0, 1073741823L);  /* 2^30 - 1 */
594         stretch(r) = mult_and_add(stretch(s), cur_val, 0, 1073741823L);  /* 2^30 - 1 */
595         shrink(r) = mult_and_add(shrink(s), cur_val, 0, 1073741823L);  /* 2^30 - 1 */
596       }
597       else
598       {
599         width(r) = x_over_n(width(s), cur_val);
600         stretch(r) = x_over_n(stretch(s), cur_val);
601         shrink(r) = x_over_n(shrink(s), cur_val);
602       }
603       cur_val = r;
604     }
605   }
606
607   if (arith_error)
608   {
609     print_err("Arithmetic overflow");
610     help2("I can't carry out that multiplication or division,",
611         "since the result is out of range.");
612
613     if (p >= glue_val)
614       delete_glue_ref(cur_val);
615
616     error();
617     return;
618   }
619
620   if (p < glue_val)
621   {
622     if ((a >= 4))
623       geq_word_define(l, cur_val);
624     else
625       eq_word_define(l, cur_val);
626   }
627   else
628   {
629     trap_zero_glue();
630
631     if ((a >= 4))
632       geq_define(l, glue_ref, cur_val);
633     else
634       eq_define(l, glue_ref, cur_val);
635   }
636 }
637 /* called only from itex.c */
638 /* sec 1243 */
639 void alter_aux (void)
640 {
641   halfword c;
642
643   if (cur_chr != abs(mode))
644   {
645     report_illegal_case();
646   }
647   else
648   {
649     c = cur_chr;
650     scan_optional_equals();
651
652     if (c == vmode)
653     {
654       scan_dimen(false, false, false);
655       prev_depth = cur_val;
656     }
657     else
658     {
659       scan_int();
660
661       if ((cur_val <= 0) || (cur_val > 32767))
662       {
663         print_err("Bad space factor");
664         help1("I allow only values in the range 1..32767 here.");
665         int_error(cur_val);
666       }
667       else
668         space_factor = cur_val;
669     }
670   }
671 }
672 /* sec 1244 */
673 void alter_prev_graf (void)
674 {
675   integer p;
676
677   nest[nest_ptr] = cur_list;
678   p = nest_ptr;
679
680   while(abs(nest[p].mode_field) != vmode)
681     decr(p);
682
683   scan_optional_equals();
684   scan_int();
685
686   if (cur_val < 0)
687   {
688     print_err("Bad ");
689     print_esc("prevgraf");
690     help1("I allow only nonnegative values here.");
691     int_error(cur_val);
692   }
693   else
694   {
695     nest[p].pg_field = cur_val;
696     cur_list = nest[nest_ptr];
697   }
698 }
699 /* sec 1245 */
700 void alter_page_so_far (void)
701 {
702   char c;
703
704   c = cur_chr;
705   scan_optional_equals();
706   scan_dimen(false, false, false);
707   page_so_far[c] = cur_val;
708 }
709 /* sec 1246 */
710 void alter_integer (void)
711 {
712   char c;
713
714   c = cur_chr;
715   scan_optional_equals();
716   scan_int();
717
718   if (c == 0)
719     dead_cycles = cur_val;
720   else
721     insert_penalties = cur_val;
722 }
723 /* sec 1247 */
724 void alter_box_dimen (void)
725 {
726   small_number c;
727   eight_bits b;
728
729   c = cur_chr;
730   scan_eight_bit_int();
731   b = cur_val;
732   scan_optional_equals();
733   scan_dimen(false, false, false);
734
735   if (box(b) != 0)
736     mem[box(b) + c].cint = cur_val;
737 }
738 /* sec 1257 */
739 void new_font_(small_number a)
740 {
741   halfword u;
742   scaled s;
743   internal_font_number f;
744   str_number t;
745   char old_setting;
746   str_number flushable_string;
747
748   if (job_name == 0)
749     open_log_file();
750
751   get_r_token();
752   u = cur_cs;
753
754   if (u >= hash_base)
755     t = text(u);
756   else if (u >= single_base)
757     if (u == null_cs)
758       t = 1213;     /* FONT */
759     else
760       t = u - single_base;
761   else
762   {
763     old_setting = selector;
764     selector = 21;
765     print_string("FONT");
766     print(u - active_base);
767     selector = old_setting;
768     str_room(1);
769     t = make_string();
770   }
771
772   if ((a >= 4))
773     geq_define(u, set_font, 0);
774   else
775     eq_define(u, set_font, 0);
776
777   scan_optional_equals();
778   scan_file_name();
779
780   name_in_progress = true;
781
782   if (scan_keyword("at"))
783   {
784     scan_dimen(false, false, false);
785     s = cur_val; 
786
787     if ((s <= 0) || (s >= 134217728L)) /* 2^27 */
788     {
789       print_err("Improper `at' size (");
790       print_scaled(s);
791       print_string("pt), replaced by 10pt");
792       help2("I can only handle fonts at positive sizes that are",
793         "less than 2048pt, so I've changed what you said to 10pt.");
794       error();
795       s = 10 * 65536L;    /* 10pt */
796     }
797   }
798   else if (scan_keyword("scaled"))
799   {
800     scan_int();
801     s = - (integer) cur_val;
802
803     if ((cur_val <= 0) || (cur_val > 32768L))
804     {
805       print_err("Illegal magnification has been changed to 1000");
806       help1("The magnification ratio must be between 1 and 32768.");
807       int_error(cur_val);
808       s = -1000;
809     }
810   }
811   else
812     s = -1000;
813
814   name_in_progress = false;
815
816   flushable_string = str_ptr - 1;
817
818   if (trace_flag) /* debugging stuff only 98/Oct/5 */
819   {
820     int i, k1, k2, l1, l2;
821     char *sch = log_line;
822     k1 = str_start[cur_area];
823     k2 = str_start[cur_name];
824     l1 = length(cur_area);
825     l2 = length(cur_name);
826     show_char('\n');
827     show_line("FONT ", 0);
828
829     for (i = 0; i < l1; i++)
830     {
831       *sch++ = str_pool[i + k1];
832     }
833
834     for (i = 0; i < l2; i++)
835     {
836       *sch++ = str_pool[i + k2];
837     }
838
839     *sch++ = ' ';
840     *sch++ = '\0';
841     show_line(log_line, 0);
842   }
843
844   for (f = font_base + 1; f < font_ptr; f++)
845   {
846     if (str_eq_str(font_name[f], cur_name) && str_eq_str(font_area[f], cur_area))
847     {
848       if (cur_name == flushable_string)
849       {
850         flush_string();
851         cur_name = font_name[f];
852       }
853
854       if (s > 0)
855       {
856         if (s == font_size[f])
857         {
858           if (ignore_frozen == 0 || f > frozenfontptr)
859           {
860             if (trace_flag)
861             {
862               sprintf(log_line, "SKIPPING %ld ", s);
863               show_line(log_line, 0);
864             }
865             goto lab50;
866           }
867         }
868       }
869       else if (font_size[f] == xn_over_d(font_dsize[f], - (integer) s, 1000))
870       {
871         if (ignore_frozen == 0 || f > frozenfontptr) /* 99/Mar/26 */
872         {
873           if (trace_flag)
874           {
875             sprintf(log_line, "SKIPPING %ld ", s);
876             show_line(log_line, 0);
877           }
878           goto lab50;
879         }
880       }
881     }
882   }
883
884   if (trace_flag)
885     show_line("READING ", 0);
886
887   f = read_font_info(u, cur_name, cur_area, s); 
888
889 lab50:
890   if (trace_flag)
891   {
892     sprintf(log_line, "NEW FONT %d ", f);
893     show_line(log_line, 0);
894   }
895
896   equiv(u) = f;
897   eqtb[font_id_base + f] = eqtb[u];
898
899 #ifdef SHORTHASH
900   if (t > 65535L)
901   {
902     sprintf(log_line, "ERROR: %s too large %d\n",  "hash_used", t);
903     show_line(log_line, 1);
904   }
905 #endif
906   font_id_text(f) = t;
907 }
908 /* sec 1265 */
909 void new_interaction (void)
910 {
911   print_ln();
912   interaction = cur_chr;
913
914   if (interaction == batch_mode)
915     selector = no_print;
916   else
917     selector = term_only;
918
919   if (log_opened)
920     selector = selector + 2;
921 }
922 /* sec 1270 */
923 void do_assignments (void)
924 {
925   while (true)
926   {
927     do
928       {
929         get_x_token();
930       }
931     while (!((cur_cmd != spacer) && (cur_cmd != relax)));
932
933     if (cur_cmd <= max_non_prefixed_command)
934       return;
935
936     set_box_allowed = false;
937     prefixed_command();
938     set_box_allowed = true;
939   }
940 }
941 /* sec 1275 */
942 void open_or_close_in (void)
943 {
944   char c;
945   char n;
946
947   c = cur_chr;
948   scan_four_bit_int();
949   n = cur_val;
950
951   if (read_open[n] != closed)
952   {
953     (void) a_close(read_file[n]);
954     read_open[n] = closed;
955   }
956
957   if (c != 0)
958   {
959     scan_optional_equals();
960     scan_file_name();
961     pack_file_name(cur_name, cur_area, cur_ext);
962
963 /* *** some changes in following in 3.14159 *** */
964 /*  if current extension is *not* empty, try to open using name as is */
965 /*  string 335 is "" the empty string */
966     if ((cur_ext != 335) && a_open_in(read_file[n], TEXINPUTPATH))
967       read_open[n] = 1;
968 /*  we get here if extension is "", or file with extension failed to open */
969 /*  if current extension is not `tex,' and `tex' is not irrelevant, try it */
970 /*  string 785 is  .tex */
971     else if ((cur_ext != 785) && (name_length + 5 < PATHMAX))
972       {
973         name_of_file[name_length + 1] = '.';
974         name_of_file[name_length + 2] = 't';
975         name_of_file[name_length + 3] = 'e';
976         name_of_file[name_length + 4] = 'x';
977         name_of_file[name_length + 5] = ' ';
978         name_length = name_length + 4;
979
980         if (a_open_in(read_file[n], TEXINPUTPATH))
981           read_open[n] = just_open;
982         else
983         {
984           name_length = name_length - 4;      /* remove ".tex" again */
985           name_of_file[name_length + 1] = ' ';
986
987           if ((cur_ext == 335) && a_open_in(read_file[n], TEXINPUTPATH))
988             read_open[n] = 1;
989         }
990       }
991   }
992 }
993 /* sec 1279 */
994 void issue_message (void)
995 {
996   char old_setting;
997   char c;
998   str_number s;
999
1000   c = cur_chr;
1001   link(garbage) = scan_toks(false, true);
1002   old_setting = selector;
1003   selector = new_string;
1004   token_show(def_ref);
1005   selector = old_setting;
1006   flush_list(def_ref);
1007   str_room(1);
1008   s = make_string();
1009
1010   if (c == 0)
1011   {
1012     if (term_offset + length(s) > max_print_line - 2)
1013       print_ln();
1014     else if ((term_offset > 0) || (file_offset > 0))
1015       print_char(' ');
1016
1017     slow_print(s);
1018
1019 #ifndef _WINDOWS
1020     fflush(stdout);
1021 #endif
1022   }
1023   else
1024   {
1025     print_err("");
1026     slow_print(s);
1027
1028     if (err_help != 0)
1029       use_err_help = true;
1030     else if (long_help_seen)
1031       help1("(That was another \\errmessage.)");
1032     else
1033     {
1034       if (interaction < error_stop_mode)
1035         long_help_seen = true;
1036
1037       help4("This error message was generated by an \\errmessage",
1038         "command, so I can't give any explicit help.",
1039         "Pretend that you're Hercule Poirot: Examine all clues,",
1040         "and deduce the truth by order and method.");
1041     }
1042
1043     error();
1044     use_err_help = false;
1045   }
1046
1047   flush_string();
1048 }
1049 /* sec 1288 */
1050 void shift_case (void)
1051 {
1052   halfword b;
1053   halfword p;
1054   halfword t;
1055   eight_bits c;
1056
1057   b = cur_chr;
1058   p = scan_toks(false, false);
1059   p = link(def_ref);
1060
1061   while (p != 0)
1062   {
1063     t = info(p); 
1064
1065     if (t < cs_token_flag + single_base)
1066     {
1067       c = t % 256;
1068
1069       if (equiv(b + c) != 0)
1070         info(p) = t - c + equiv(b + c);
1071     }
1072
1073     p = link(p);
1074   }
1075
1076   begin_token_list(link(def_ref), 3);
1077   free_avail(def_ref);
1078 }
1079 /* sec 1293 */
1080 void show_whatever (void)
1081 {
1082   halfword p;
1083
1084   switch(cur_chr)
1085   {
1086     case show_lists:
1087       {
1088         begin_diagnostic();
1089         show_activities();
1090       }
1091       break;
1092
1093     case show_box_code:
1094       {
1095         scan_eight_bit_int();
1096         begin_diagnostic();
1097         print_nl("> \\box");
1098         print_int(cur_val);
1099         print_char('=');
1100
1101         if (box(cur_val) == 0)
1102           print_string("void");
1103         else
1104           show_box(box(cur_val));
1105       }
1106       break;
1107
1108     case show_code:
1109       {
1110         get_token();
1111
1112         if (interaction == error_stop_mode)
1113           ;
1114
1115         print_nl("> ");
1116
1117         if (cur_cs != 0)
1118         {
1119           sprint_cs(cur_cs);
1120           print_char('=');
1121         }
1122
1123         print_meaning();
1124         goto lab50;
1125       }
1126       break;
1127
1128     default:
1129       {
1130         p = the_toks();
1131
1132         if (interaction == error_stop_mode)
1133           ;
1134
1135         print_nl("> ");
1136         token_show(temp_head);
1137         flush_list(link(temp_head));
1138         goto lab50;
1139       }
1140       break;
1141   }
1142
1143   end_diagnostic(true);
1144   print_err("OK");
1145
1146   if (selector == term_and_log)
1147     if (tracing_online <= 0)
1148     {
1149       selector = term_only;
1150       print_string(" (see the transcript file)");
1151       selector = term_and_log;
1152     }
1153
1154 lab50:
1155
1156   if (interaction < error_stop_mode)
1157   {
1158     help_ptr = 0;
1159     decr(error_count);
1160   }
1161   else if (tracing_online > 0)
1162   {
1163     help3("This isn't an error message; I'm just \\showing something.",
1164       "Type `I\\show...' to show more (e.g., \\show\\cs,",
1165       "\\showthe\\count10, \\showbox255, \\showlists).");
1166   }
1167   else
1168   {
1169     help5("This isn't an error message; I'm just \\showing something.",
1170       "Type `I\\show...' to show more (e.g., \\show\\cs,",
1171       "\\showthe\\count10, \\showbox255, \\showlists).",
1172       "And type `I\\tracingonline=1\\show...' to show boxes and",
1173       "lists on your terminal as well as in the transcript file.");
1174   }
1175   error();
1176 }
1177 /* sec 1349 */
1178 void new_whatsit_(small_number s, small_number w)
1179 {
1180   halfword p;
1181
1182   p = get_node(w);
1183   type(p) = whatsit_node;
1184   subtype(p) = s;
1185   link(tail) = p;
1186   tail = p;
1187 }
1188 /* sec 1350 */
1189 void new_write_whatsit_(small_number w)
1190 {
1191   new_whatsit(cur_chr, w);
1192
1193   if (w != write_node_size)
1194   {
1195     scan_four_bit_int();
1196   }
1197   else
1198   {
1199     scan_int();
1200
1201     if (cur_val < 0)
1202       cur_val = 17;
1203     else if (cur_val > 15)
1204       cur_val = 16;
1205   }
1206
1207   write_stream(tail) = cur_val;
1208 }
1209 /* sec 1348 */
1210 void do_extension (void)
1211 {
1212 /*  integer i, j, k;  */
1213   integer k;
1214 /*  halfword p, q, r;  */
1215   halfword p;
1216
1217   switch(cur_chr)
1218   {
1219     case open_node:
1220       {
1221         new_write_whatsit(open_node_size);
1222         scan_optional_equals();
1223         scan_file_name();
1224         open_name(tail) = cur_name;
1225         open_area(tail) = cur_area;
1226         open_ext(tail) = cur_ext;
1227       }
1228       break;
1229
1230     case write_node:
1231       {
1232         k = cur_cs;
1233         new_write_whatsit(write_node_size);
1234         cur_cs = k;
1235         p = scan_toks(false, false);
1236         write_tokens(tail) = def_ref;
1237       }
1238       break;
1239
1240     case close_node:
1241       {
1242         new_write_whatsit(write_node_size);
1243         write_tokens(tail) = 0;
1244       }
1245       break;
1246
1247     case special_node:
1248       {
1249         new_whatsit(special_node, write_node_size);
1250         write_stream(tail) = 0;
1251         p = scan_toks(false, true);
1252         write_tokens(tail) = def_ref;
1253       }
1254       break;
1255
1256     case immediate_code:
1257       {
1258         get_x_token();
1259
1260         if ((cur_cmd == extension) && (cur_chr <= close_node))
1261         {
1262           p = tail;
1263           do_extension();
1264           out_what(tail);
1265           flush_node_list(tail);
1266           tail = p;
1267           link(p) = 0;
1268         }
1269         else
1270           back_input();
1271       }
1272       break;
1273
1274     case set_language_code:
1275       if (abs(mode) != hmode)
1276       {
1277         report_illegal_case();
1278       }
1279       else
1280       {
1281         new_whatsit(language_node, small_node_size);
1282         scan_int();
1283
1284         if (cur_val <= 0)
1285           clang = 0;
1286         else if (cur_val > 255)
1287           clang = 0;
1288         else
1289           clang = cur_val;
1290
1291         what_lang(tail) = clang;
1292         what_lhm(tail) = norm_min(left_hyphen_min);
1293         what_rhm(tail) = norm_min(right_hyphen_min);
1294       }
1295       break;
1296
1297     default:
1298       {
1299         confusion("ext1");
1300         return;       // abort_flag set
1301       }
1302       break;
1303   }
1304 }
1305 /* sec 1376 */
1306 void fix_language (void)
1307 {
1308 /*  ASCII_code l;  */
1309   int l;                  /* 95/Jan/7 */
1310
1311   if (language <= 0)
1312     l = 0; 
1313   else if (language > 255)
1314     l = 0;
1315   else
1316     l = language;
1317
1318   if (l != clang)
1319   {
1320     new_whatsit(language_node, small_node_size);
1321     what_lang(tail) = l;
1322     clang = l;
1323     what_lhm(tail) = norm_min(left_hyphen_min);
1324     what_rhm(tail) = norm_min(right_hyphen_min);
1325   }
1326 }
1327 /* sec 1068 */
1328 void handle_right_brace (void)
1329 {
1330   halfword p, q;
1331   scaled d;
1332   integer f;
1333
1334   switch(cur_group)
1335   {
1336     case simple_group:
1337       unsave();
1338       break;
1339
1340     case bottom_level:
1341       {
1342         print_err("Too many }'s");
1343         help2("You've closed more groups than you opened.",
1344           "Such booboos are generally harmless, so keep going.");
1345         error();
1346       }
1347       break;
1348
1349     case semi_simple_group:
1350     case math_shift_group:
1351     case math_left_group:
1352       extra_right_brace();
1353       break;
1354
1355     case hbox_group:
1356       package(0);
1357       break;
1358
1359     case adjust_hbox_group:
1360       {
1361         adjust_tail = adjust_head;
1362         package(0);
1363       }
1364       break;
1365
1366     case vbox_group:
1367       {
1368         end_graf();
1369         package(0);
1370       }
1371       break;
1372
1373     case vtop_group:
1374       {
1375         end_graf();
1376         package(vtop_code);
1377       }
1378       break;
1379
1380     case insert_group:
1381       {
1382         end_graf();
1383         q = split_top_skip;
1384         add_glue_ref(q);
1385         d = split_max_depth;
1386         f = floating_penalty;
1387         unsave();
1388         decr(save_ptr);
1389         p = vpackage(link(head), 0, 1, 1073741823L);  /* 2^30 - 1 */
1390         pop_nest();
1391
1392         if (saved(0) < 255)
1393         {
1394           tail_append(get_node(ins_node_size));
1395           type(tail) = ins_node;
1396           subtype(tail) = saved(0);
1397           height(tail) = height(p) + depth(p);
1398           ins_ptr(tail) = list_ptr(p);
1399           split_top_ptr(tail) = q;
1400           depth(tail) = d;
1401           float_cost(tail) = f;
1402         }
1403         else
1404         {
1405           tail_append(get_node(small_node_size));
1406           type(tail) = adjust_node;
1407           subtype(tail) = 0;
1408           adjust_ptr(tail) = list_ptr(p);
1409           delete_glue_ref(q);
1410         }
1411         free_node(p, box_node_size);
1412
1413         if (nest_ptr == 0)
1414         {
1415           build_page();
1416         }
1417       }
1418       break;
1419     case output_group:
1420       {
1421         if ((cur_input.loc_field != 0) || ((token_type != output_text) && (token_type != backed_up)))
1422         {
1423           print_err("Unbalanced output routine");
1424           help2("Your sneaky output routine has problematic {'s and/or }'s.",
1425             "I can't handle that very well; good luck.");
1426           error();
1427
1428           do
1429             {
1430               get_token();
1431             }
1432           while (!(cur_input.loc_field == 0));
1433         }
1434
1435         end_token_list();
1436         end_graf();
1437         unsave();
1438         output_active = false;
1439         insert_penalties = 0;
1440
1441         if (box(255) != 0)
1442         {
1443           print_err("Output routine didn't use all of ");
1444           print_esc("box");
1445           print_int(255);
1446           help3("Your \\output commands should empty \\box255,",
1447             "e.g., by saying `\\shipout\\box255'.",
1448             "Proceed; I'll discard its present contents.");
1449           box_error(255);
1450         }
1451
1452         if (tail != head)
1453         {
1454           link(page_tail) = link(head);
1455           page_tail = tail;
1456         }
1457
1458         if (link(page_head) != 0)
1459         {
1460           if (link(contrib_head) == 0)
1461             nest[0].tail_field = page_tail;
1462
1463           link(page_tail) = link(contrib_head);
1464           link(contrib_head) = link(page_head);
1465           link(page_head) = 0;
1466           page_tail = page_head;
1467         }
1468         pop_nest();
1469         build_page();
1470       }
1471       break;
1472
1473     case disc_group:
1474       build_discretionary();
1475       break;
1476
1477     case align_group:
1478       {
1479         back_input();
1480         cur_tok = cs_token_flag + frozen_cr;
1481         print_err("Missing ");
1482         print_esc("cr");
1483         print_string("inserted");
1484         help1("I'm guessing that you meant to end an alignment here.");
1485         ins_error();
1486       }
1487       break;
1488
1489     case no_align_group:
1490       {
1491         end_graf();
1492         unsave();
1493         align_peek();
1494       }
1495       break;
1496
1497     case vcenter_group:
1498       {
1499         end_graf();
1500         unsave();
1501         save_ptr = save_ptr - 2;
1502         p = vpackage(link(head), saved(1), saved(0), 1073741823L);   /* 2^30 - 1 */
1503         pop_nest();
1504         tail_append(new_noad());
1505         type(tail) = vcenter_noad;
1506         math_type(nucleus(tail)) = sub_box;
1507         info(nucleus(tail)) = p;
1508       }
1509       break;
1510
1511     case math_choice_group:
1512       build_choices();
1513       break;
1514
1515     case math_group:
1516       {
1517         unsave();
1518         decr(save_ptr);
1519         math_type(saved(0)) = sub_mlist;
1520         p = fin_mlist(0);
1521         info(saved(0)) = p;
1522
1523         if (p != 0)
1524           if (link(p) == 0)
1525             if (type(p) == ord_noad)
1526             {
1527               if (math_type(subscr(p)) == 0)
1528                 if (math_type(supscr(p)) == 0)
1529                 {
1530                   mem[saved(0)].hh = mem[nucleus(p)].hh;
1531                   free_node(p, noad_size);
1532                 }
1533             }
1534             else if (type(p) == accent_noad)
1535               if (saved(0) == nucleus(tail))
1536                 if (type(tail) == ord_noad)
1537                 {
1538                   q = head;
1539
1540                   while(link(q) != tail)
1541                     q = link(q);
1542
1543                   link(q) = p;
1544                   free_node(tail, noad_size);
1545                   tail = p;
1546                 }
1547       }
1548       break;
1549     default:
1550       {
1551         confusion("rightbrace");
1552         return;       // abort_flag set
1553       }
1554       break;
1555   }
1556 }
1557 /* sec 1030 */
1558 void main_control (void) 
1559 {
1560   integer t;
1561   integer bSuppress; /* 199/Jan/5 */
1562
1563   if (every_job != 0)
1564     begin_token_list(every_job, every_job_text);
1565
1566 lab60:
1567   get_x_token();       /* big_switch */
1568
1569 lab21:
1570   if (interrupt != 0)
1571     if (OK_to_interrupt)
1572     {
1573       back_input();
1574       {
1575         if (interrupt != 0)
1576         {
1577           pause_for_instructions();
1578         }
1579       }
1580       goto lab60;
1581     }
1582
1583 #ifdef DEBUG
1584   if (panicking)
1585     check_mem(false);
1586 #endif
1587
1588   if (tracing_commands > 0)
1589     show_cur_cmd_chr();
1590
1591 /*  the big switch --- don't bother to test abort_flag ??? */
1592   switch(abs(mode) + cur_cmd)
1593   {
1594     case hmode + letter:
1595     case hmode + other_char:
1596     case hmode + char_given:
1597       goto lab70;
1598       break;
1599
1600     case hmode + char_num:
1601       {
1602         scan_char_num();
1603         cur_chr = cur_val;
1604         goto lab70;
1605       }
1606       break;
1607
1608     case hmode + no_boundary:
1609       {
1610         get_x_token();
1611
1612         if ((cur_cmd == letter) || (cur_cmd == other_char) ||
1613           (cur_cmd == char_given) || (cur_cmd == char_num))
1614           cancel_boundary = true;
1615         goto lab21;
1616       }
1617       break;
1618
1619     case hmode + spacer:
1620       if (space_factor == 1000)
1621         goto lab120;
1622       else
1623         app_space();
1624       break;
1625
1626     case hmode + ex_space:
1627     case mmode + ex_space:
1628       goto lab120;
1629       break;
1630
1631     case any_mode(relax):
1632     case vmode + spacer:
1633     case mmode + spacer:
1634     case mmode + no_boundary:
1635       ;
1636       break;
1637
1638     case any_mode(ignore_spaces):
1639       {
1640         do
1641           {
1642             get_x_token();
1643           }
1644         while(!(cur_cmd != spacer));
1645         goto lab21;
1646       }
1647       break;
1648
1649     case vmode + stop:
1650       if (its_all_over())
1651         return;
1652       break;
1653
1654     case vmode + vmove:
1655     case hmode + hmove:
1656     case mmode + hmove:
1657     case any_mode(last_item):
1658     case vmode + vadjust:
1659     case vmode + ital_corr:
1660     case non_math(eq_no):
1661     case any_mode(mac_param):
1662       report_illegal_case();
1663       break;
1664
1665     case non_math(sup_mark):
1666     case non_math(sub_mark):
1667     case non_math(math_char_num):
1668     case non_math(math_given):
1669     case non_math(math_comp):
1670     case non_math(delim_num):
1671     case non_math(left_right):
1672     case non_math(above):
1673     case non_math(radical):
1674     case non_math(math_style):
1675     case non_math(math_choice):
1676     case non_math(vcenter):
1677     case non_math(non_script):
1678     case non_math(mkern):
1679     case non_math(limit_switch):
1680     case non_math(mskip):
1681     case non_math(math_accent):
1682     case mmode + endv:
1683     case mmode + par_end:
1684     case mmode + stop:
1685     case mmode + vskip:
1686     case mmode + un_vbox:
1687     case mmode + valign:
1688     case mmode + hrule:
1689       insert_dollar_sign();
1690       break;
1691
1692     case vmode + hrule:
1693     case hmode + vrule:
1694     case mmode + vrule:
1695       {
1696         tail_append(scan_rule_spec());
1697
1698         if (abs(mode) == vmode)
1699           prev_depth = ignore_depth;
1700         else if (abs(mode) == hmode)
1701           space_factor = 1000;
1702       }
1703       break;
1704
1705     case vmode + vskip:
1706     case hmode + hskip:
1707     case mmode + hskip:
1708     case mmode + mskip:
1709       append_glue();
1710       break;
1711
1712     case any_mode(kern):
1713     case mmode + mkern:
1714       append_kern();
1715       break;
1716
1717     case non_math(left_brace):
1718       new_save_level(simple_group);
1719       break;
1720
1721     case any_mode(begin_group):
1722       new_save_level(semi_simple_group);
1723       break;
1724
1725     case any_mode(end_group):
1726       if (cur_group == semi_simple_group)
1727         unsave();
1728       else
1729         off_save();
1730       break;
1731
1732     case any_mode(right_brace):
1733       handle_right_brace();
1734       break;
1735
1736     case vmode + hmove:
1737     case hmode + vmove:
1738     case mmode + vmove:
1739       {
1740         t = cur_chr;
1741         scan_dimen(false, false, false);
1742
1743         if (t == 0)
1744           scan_box(cur_val);
1745         else
1746           scan_box(- (integer) cur_val);
1747       }
1748       break;
1749
1750     case any_mode(leader_ship):
1751       scan_box(leader_flag - a_leaders + cur_chr);
1752       break;
1753
1754     case any_mode(make_box):
1755       begin_box(0);
1756       break;
1757
1758     case vmode + start_par:
1759       new_graf(cur_chr > 0);
1760       break;
1761
1762     case vmode + letter:
1763     case vmode + other_char:
1764     case vmode + char_num:
1765     case vmode + char_given:
1766     case vmode + math_shift:
1767     case vmode + un_hbox:
1768     case vmode + vrule:
1769     case vmode + accent:
1770     case vmode + discretionary:
1771     case vmode + hskip:
1772     case vmode + valign:
1773     case vmode + ex_space:
1774     case vmode + no_boundary:
1775       {
1776         back_input();
1777         new_graf(true);
1778       }
1779       break;
1780
1781     case hmode + start_par:
1782     case mmode + start_par:
1783       indent_in_hmode();
1784       break;
1785
1786     case vmode + par_end:
1787       {
1788         normal_paragraph();
1789
1790         if (mode > 0)
1791           build_page();
1792       }
1793       break;
1794
1795     case hmode + par_end:
1796       {
1797         if (align_state < 0)
1798           off_save();
1799
1800         end_graf();
1801
1802         if (mode == 1)
1803           build_page();
1804       }
1805       break;
1806
1807     case hmode + stop:
1808     case hmode + vskip:
1809     case hmode + hrule:
1810     case hmode + un_vbox:
1811     case hmode + halign:
1812       head_for_vmode();
1813       break;
1814
1815     case any_mode(insert):
1816     case hmode + vadjust:
1817     case mmode + vadjust:
1818       begin_insert_or_adjust();
1819       break;
1820
1821     case any_mode(mark):
1822       make_mark();
1823       break;
1824
1825     case any_mode(break_penalty):
1826       append_penalty();
1827       break;
1828
1829     case any_mode(remove_item):
1830       delete_last();
1831       break;
1832
1833     case vmode + un_vbox:
1834     case hmode + un_hbox:
1835     case mmode + un_hbox:
1836       unpackage();
1837       break;
1838
1839     case hmode + ital_corr:
1840       append_italic_correction();
1841       break;
1842
1843     case mmode + ital_corr:
1844       tail_append(new_kern(0));
1845       break;
1846
1847     case hmode + discretionary:
1848     case mmode + discretionary:
1849       append_discretionary();
1850       break;
1851
1852     case hmode + accent:
1853       make_accent();
1854       break;
1855
1856     case any_mode(car_ret):
1857     case any_mode(tab_mark):
1858       align_error();
1859       break;
1860
1861     case any_mode(no_align):
1862       noalign_error();
1863       break;
1864
1865     case any_mode(omit):
1866       omit_error();
1867       break;
1868
1869     case vmode + halign:
1870     case hmode + valign:
1871       init_align();
1872       break;
1873
1874     case mmode + halign:
1875       if (privileged ())
1876         if (cur_group == math_shift_group)
1877           init_align();
1878         else
1879           off_save();
1880       break;
1881
1882     case vmode + endv:
1883     case hmode + endv:
1884       do_endv();
1885       break;
1886
1887     case any_mode(end_cs_name):
1888       cs_error();
1889       break;
1890
1891     case hmode + math_shift:
1892       init_math();
1893       break;
1894
1895     case mmode + eq_no:
1896       if (privileged ())
1897         if (cur_group == math_shift_group)
1898           start_eq_no();
1899         else
1900           off_save();
1901       break;
1902
1903     case mmode + left_brace:
1904       {
1905         tail_append(new_noad());
1906         back_input();
1907         scan_math(nucleus(tail));
1908       }
1909       break;
1910
1911     case mmode + letter:
1912     case mmode + other_char:
1913     case mmode + char_given:
1914       set_math_char(math_code(cur_chr));
1915       break;
1916
1917     case mmode + char_num:
1918       {
1919         scan_char_num();
1920         cur_chr = cur_val;
1921         set_math_char(math_code(cur_chr));
1922       }
1923       break;
1924
1925     case mmode + math_char_num:
1926       {
1927         scan_fifteen_bit_int();
1928         set_math_char(cur_val);
1929       }
1930       break;
1931
1932     case mmode + math_given:
1933       set_math_char(cur_chr);
1934       break;
1935
1936     case mmode + delim_num:
1937       {
1938         scan_twenty_seven_bit_int();
1939         set_math_char(cur_val / 4096);
1940       }
1941       break;
1942
1943     case mmode + math_comp:
1944       {
1945         tail_append(new_noad());
1946         type(tail) = cur_chr;
1947         scan_math(nucleus(tail));
1948       }
1949       break;
1950
1951     case mmode + limit_switch:
1952       math_limit_switch();
1953       break;
1954
1955     case mmode + radical:
1956       math_radical();
1957       break;
1958
1959     case mmode + accent:
1960     case mmode + math_accent:
1961       math_ac();
1962       break;
1963
1964     case mmode + vcenter:
1965       {
1966         scan_spec(vcenter_group, false);
1967         normal_paragraph();
1968         push_nest();
1969         mode = -1;
1970         prev_depth = ignore_depth;
1971
1972         if (every_vbox != 0)
1973           begin_token_list(every_vbox, every_vbox_text);
1974       }
1975       break;
1976
1977     case mmode + math_style:
1978       tail_append(new_style(cur_chr));
1979       break;
1980
1981     case mmode + non_script:
1982       {
1983         tail_append(new_glue(0));
1984         subtype(tail) = cond_math_glue;
1985       }
1986       break;
1987
1988     case mmode + math_choice:
1989       append_choices();
1990       break;
1991
1992     case mmode + sub_mark:
1993     case mmode + sup_mark:
1994       sub_sup();
1995       break;
1996
1997     case mmode + above:
1998       math_fraction();
1999       break;
2000
2001     case mmode + left_right:
2002       math_left_right();
2003       break;
2004
2005     case mmode + math_shift:
2006       if (cur_group == math_shift_group)
2007         after_math();
2008       else
2009         off_save();
2010       break;
2011
2012     case any_mode(toks_register):
2013     case any_mode(assign_toks):
2014     case any_mode(assign_int):
2015     case any_mode(assign_dimen):
2016     case any_mode(assign_glue):
2017     case any_mode(assign_mu_glue):
2018     case any_mode(assign_font_dimen):
2019     case any_mode(assign_font_int):
2020     case any_mode(set_aux):
2021     case any_mode(set_prev_graf):
2022     case any_mode(set_page_dimen):
2023     case any_mode(set_page_int):
2024     case any_mode(set_box_dimen):
2025     case any_mode(set_shape):
2026     case any_mode(def_code):
2027     case any_mode(def_family):
2028     case any_mode(set_font):
2029     case any_mode(def_font):
2030     case any_mode(tex_register):
2031     case any_mode(advance):
2032     case any_mode(multiply):
2033     case any_mode(divide):
2034     case any_mode(prefix):
2035     case any_mode(let):
2036     case any_mode(shorthand_def):
2037     case any_mode(read_to_cs):
2038     case any_mode(def):
2039     case any_mode(set_box):
2040     case any_mode(hyph_data):
2041     case any_mode(set_interaction):
2042       prefixed_command();
2043       break;
2044
2045     case any_mode(after_assignment):
2046       {
2047         get_token();
2048         after_token = cur_tok;
2049       }
2050       break;
2051
2052     case any_mode(after_group):
2053       {
2054         get_token();
2055         save_for_after(cur_tok);
2056       }
2057       break;
2058
2059     case any_mode(in_stream):
2060       open_or_close_in();
2061       break;
2062
2063     case any_mode(message):
2064       issue_message();
2065       break;
2066
2067     case any_mode(case_shift):
2068       shift_case();
2069       break;
2070
2071     case any_mode(xray):
2072       show_whatever();
2073       break;
2074
2075     case any_mode(extension):
2076       do_extension();
2077       break;
2078   } /* end of big switch */
2079   goto lab60; /*  main_loop */
2080
2081 lab70:
2082   adjust_space_factor();
2083   main_f = cur_font;
2084   bchar = font_bchar[main_f];
2085   false_bchar = font_false_bchar[main_f];
2086
2087   if (mode > 0)
2088     if (language != clang)
2089       fix_language();
2090   {
2091     lig_stack = avail;
2092
2093     if (lig_stack == 0)
2094       lig_stack = get_avail();
2095     else
2096     {
2097       avail = mem[lig_stack].hh.v.RH;
2098       mem[lig_stack].hh.v.RH = 0;
2099 #ifdef STAT
2100       incr(dyn_used);
2101 #endif /* STAT */
2102     }
2103   }
2104
2105   font(lig_stack) = main_f;
2106   cur_l = cur_chr;
2107   character(lig_stack) = cur_l;
2108   cur_q = tail;
2109
2110   if (cancel_boundary)
2111   {
2112     cancel_boundary = false;
2113     main_k = non_address;
2114   }
2115   else
2116     main_k = bchar_label[main_f];
2117
2118   if (main_k == non_address)
2119     goto lab92;
2120
2121   cur_r = cur_l;
2122   cur_l = non_char;
2123   goto lab111;
2124
2125 lab80: 
2126   wrapup(rt_hit);
2127
2128 /*  main_loop_move */
2129 lab90:
2130   if (lig_stack == 0)
2131     goto lab21;
2132
2133   cur_q = tail;
2134   cur_l = character(lig_stack);
2135
2136 lab91:
2137   if (!(lig_stack >= hi_mem_min))
2138     goto lab95;
2139
2140 lab92:
2141   if ((cur_chr < font_bc[main_f]) || (cur_chr > font_ec[main_f]))
2142   {
2143     char_warning(main_f, cur_chr);
2144     free_avail(lig_stack);
2145     goto lab60;
2146   }
2147
2148   main_i = char_info(main_f, cur_l);
2149
2150   if (!(main_i.b0 > 0))
2151   {
2152     char_warning(main_f, cur_chr);
2153     free_avail(lig_stack);
2154     goto lab60; 
2155   }
2156   {
2157     link(tail) = lig_stack;
2158     tail = lig_stack;
2159   }
2160
2161 /*  main_loop_lookahead */
2162 lab100:
2163   get_next();
2164
2165   if (cur_cmd == letter)
2166     goto lab101;
2167   if (cur_cmd == other_char)
2168     goto lab101;
2169   if (cur_cmd == char_given)
2170     goto lab101;
2171
2172   x_token();
2173
2174   if (cur_cmd == letter)
2175     goto lab101;
2176   if (cur_cmd == other_char)
2177     goto lab101;
2178   if (cur_cmd == char_given)
2179     goto lab101;
2180
2181   if (cur_cmd == char_num)
2182   {
2183     scan_char_num();
2184     cur_chr = cur_val;
2185     goto lab101;
2186   }
2187
2188   if (cur_cmd == no_boundary)
2189     bchar = non_char;
2190
2191   cur_r = bchar;
2192   lig_stack = 0;
2193   goto lab110;
2194
2195 lab101:
2196   adjust_space_factor();
2197
2198   {
2199     lig_stack = avail;
2200
2201     if (lig_stack == 0)
2202       lig_stack = get_avail();
2203     else
2204     {
2205       avail = mem[lig_stack].hh.v.RH;
2206       mem[lig_stack].hh.v.RH = 0;
2207 #ifdef STAT
2208       incr(dyn_used);
2209 #endif /* STAT */
2210     }
2211   }
2212
2213   font(lig_stack) = main_f;
2214   cur_r = cur_chr;
2215   character(lig_stack) = cur_r;
2216
2217   if (cur_r == false_bchar)
2218     cur_r = non_char;
2219
2220 // main_lig_loop:@<If there's a ligature/kern command relevant to |cur_l| and
2221 //  |cur_r|, adjust the text appropriately; exit to |main_loop_wrapup|@>;
2222 lab110:
2223
2224   if (char_tag(main_i) != lig_tag)
2225     goto lab80;
2226
2227   if (cur_r == non_char)
2228     goto lab80;
2229
2230   main_k = lig_kern_start(main_f, main_i);
2231   main_j = font_info[main_k].qqqq;
2232
2233   if (skip_byte(main_j) <= stop_flag)
2234     goto lab112;
2235
2236   main_k = lig_kern_restart(main_f, main_j);
2237
2238 /* main_lig_loop+1:main_j:=font_info[main_k].qqqq; */
2239 lab111:
2240   main_j = font_info[main_k].qqqq;
2241
2242 lab112:
2243 /* provide for suppression of f-ligatures 99/Jan/5 */
2244   bSuppress = 0;
2245
2246   if (suppress_f_ligs && next_char(main_j) == cur_r && op_byte(main_j) == no_tag)
2247   {
2248     if (cur_l == 'f')
2249       bSuppress = 1;
2250   }
2251
2252   if (next_char(main_j) == cur_r && bSuppress == 0)  /* 99/Jan/5 */
2253     if (skip_byte(main_j) <= stop_flag)
2254     {
2255       if (op_byte(main_j) >= kern_flag)
2256       {
2257         wrapup(rt_hit);
2258         tail_append(new_kern(char_kern(main_f, main_j)));
2259         goto lab90;
2260       }
2261
2262       if (cur_l == non_char)
2263         lft_hit = true;
2264       else if (lig_stack == 0)
2265         rt_hit = true;
2266
2267       {
2268         if (interrupt != 0)
2269         {
2270           pause_for_instructions();
2271         }
2272       }
2273
2274       switch (op_byte(main_j))
2275       {
2276         case 1:
2277         case 5:
2278           {
2279             cur_l = rem_byte(main_j);
2280             main_i = char_info(main_f, cur_l);
2281             ligature_present = true;
2282           }
2283           break;
2284         case 2:
2285         case 6:
2286           {
2287             cur_r = rem_byte(main_j);
2288
2289             if (lig_stack == 0)
2290             {
2291               lig_stack = new_lig_item(cur_r);
2292               bchar = non_char;
2293             }
2294             else if ((lig_stack >= hi_mem_min))
2295             {
2296               main_p = lig_stack;
2297               lig_stack = new_lig_item(cur_r);
2298               lig_ptr(lig_stack) = main_p;
2299             }
2300             else
2301               character(lig_stack) = cur_r;
2302           }
2303           break;
2304         case 3:
2305           {
2306             cur_r = rem_byte(main_j);
2307             main_p = lig_stack;
2308             lig_stack = new_lig_item(cur_r);
2309             link(lig_stack) = main_p;
2310           }
2311           break;
2312         case 7:
2313         case 11:
2314           {
2315             wrapup(false);
2316             cur_q = tail;
2317             cur_l = rem_byte(main_j);
2318             main_i = char_info(main_f, cur_l);
2319             ligature_present = true;
2320           }
2321           break;
2322         default:
2323           {
2324             cur_l = rem_byte(main_j);
2325             ligature_present = true;
2326  
2327             if (lig_stack == 0)
2328               goto lab80;
2329             else
2330               goto lab91;
2331           }
2332           break;
2333       }
2334
2335       if (op_byte(main_j) > 4)
2336         if (op_byte(main_j) != 7)
2337           goto lab80;
2338
2339       if (cur_l < non_char)
2340         goto lab110;
2341
2342       main_k = bchar_label[main_f];
2343       goto lab111;
2344     }
2345
2346     if (skip_byte(main_j) == 0)
2347       incr(main_k);
2348     else
2349     {
2350       if (skip_byte(main_j) >= stop_flag)
2351         goto lab80;
2352
2353       main_k = main_k + skip_byte(main_j) + 1;
2354     }
2355
2356     goto lab111;
2357
2358 /*  main_move_log */
2359 lab95:
2360   main_p = lig_ptr(lig_stack);
2361
2362   if (main_p != 0)     /* BUG FIX */
2363     tail_append(main_p);
2364
2365   temp_ptr = lig_stack;
2366   lig_stack = link(temp_ptr);
2367   free_node(temp_ptr, small_node_size);
2368   main_i = char_info(main_f, cur_l);
2369   ligature_present = true;
2370
2371   if (lig_stack == 0)
2372     if (main_p != 0)   /* BUG FIX */
2373       goto lab100;
2374     else
2375       cur_r = bchar;
2376   else
2377     cur_r = character(lig_stack);
2378
2379   goto lab110;
2380
2381 /*  append_normal_space */
2382 lab120:
2383   if (space_skip == 0)
2384   {
2385     {
2386       main_p = font_glue[cur_font];
2387
2388       if (main_p == 0)
2389       {
2390         main_p = new_spec(zero_glue);
2391         main_k = param_base[cur_font] + space_code;
2392         width(main_p) = font_info[main_k].cint;
2393         stretch(main_p) = font_info[main_k + 1].cint;
2394         shrink(main_p) = font_info[main_k + 2].cint;
2395         font_glue[cur_font] = main_p;
2396       }
2397     }
2398     temp_ptr = new_glue(main_p);
2399   }
2400   else
2401     temp_ptr = new_param_glue(space_skip_code);
2402
2403   link(tail) = temp_ptr;
2404   tail = temp_ptr;
2405   goto lab60;
2406 }
2407 /* give_err_help etc followed here in the old tex8.c */