OSDN Git Service

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