OSDN Git Service

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