OSDN Git Service

long options.
[putex/putex.git] / src / texsourc / tex7.c
1 #ifdef _WINDOWS
2   #define NOCOMM
3   #define NOSOUND
4   #define NODRIVERS
5   #define STRICT
6   #pragma warning(disable:4115) // kill rpcasync.h complaint
7   #include <windows.h>
8   #define MYLIBAPI __declspec(dllexport)
9 #endif
10
11 #pragma warning(disable:4131) // old style declarator
12 #pragma warning(disable:4135) // conversion between different integral types 
13 #pragma warning(disable:4127) // conditional expression is constant
14
15 #include <setjmp.h>
16
17 #define EXTERN extern
18
19 #include "texd.h"
20
21 #pragma warning(disable:4244)       /* 96/Jan/10 */
22
23 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
24 /* sec 0994 */
25 void build_page (void)
26 {
27   halfword p;
28   halfword q, r;
29   integer b, c;
30   integer pi;
31 /*  unsigned char n;  */
32   unsigned int n;             /* 95/Jan/7 */
33   scaled delta, h, w;
34
35   if ((link(contrib_head) == 0) || output_active)
36     return;
37
38   do
39     {
40 lab22:
41       p = link(contrib_head);
42
43       if (last_glue != max_halfword)
44         delete_glue_ref(last_glue);
45
46       last_penalty = 0;
47       last_kern = 0;
48
49       if (type(p) == glue_node)
50       {
51         last_glue = glue_ptr(p);
52         add_glue_ref(last_glue);
53       }
54       else
55       {
56         last_glue = max_halfword;
57
58         if (type(p) == penalty_node)
59           last_penalty = penalty(p);
60         else if (type(p) == kern_node)
61           last_kern = width(p);
62       }
63
64       switch (type(p))
65       {
66         case hlist_node:
67         case vlist_node:
68         case rule_node:
69           if (page_contents < box_there)
70           {
71             if (page_contents == 0)
72               freeze_page_specs(box_there);
73             else
74               page_contents = box_there;
75
76             q = new_skip_param(top_skip_code);
77
78             if (width(temp_ptr) > height(p))
79               width(temp_ptr) = width(temp_ptr) - height(p);
80             else
81               width(temp_ptr) = 0;
82
83             link(q) = p;
84             link(contrib_head) = q;
85             goto lab22;
86           }
87           else
88           {
89             page_total = page_total + page_depth + height(p);
90             page_depth = depth(p);
91             goto lab80;
92           }
93           break;
94
95         case whatsit_node:
96           goto lab80;
97           break;
98
99         case glue_node:
100           if (page_contents < box_there)
101             goto lab31;
102           else if (precedes_break(page_tail))
103             pi = 0;
104           else
105             goto lab90;
106           break;
107
108         case kern_node:
109           if (page_contents < box_there)
110             goto lab31;
111           else if (link(p) == 0)
112             return;
113           else if (type(link(p)) == glue_node)
114             pi = 0;
115           else
116             goto lab90;
117           break;
118
119         case penalty_node:
120           if (page_contents < box_there)
121             goto lab31;
122           else
123             pi = penalty(p);
124           break;
125
126         case mark_node:
127           goto lab80;
128           break;
129
130         case ins_node:
131           {
132             if (page_contents == 0)
133               freeze_page_specs(inserts_only);
134
135             n = subtype(p);
136             r = page_ins_head;
137
138             while (n >= subtype(link(r)))
139               r = link(r);
140
141             n = n;
142
143             if (subtype(r) != n)
144             {
145               q = get_node(page_ins_node_size);
146               link(q) = link(r);
147               link(r) = q;
148               r = q;
149               subtype(r) = n;
150               type(r) = inserting;
151               ensure_vbox(n);
152
153               if (box(n) == 0)
154                 height(r) = 0;
155               else
156                 height(r) = height(box(n)) + depth(box(n));
157
158               best_ins_ptr(r) = 0;
159               q = skip(n);
160
161               if (count(n) == 1000)
162                 h = height(r);
163               else
164                 h = x_over_n(height(r), 1000) * count(n);
165
166               page_goal = page_goal - h - width(q);
167               page_so_far[2 + stretch_order(q)] = page_so_far[2 + stretch_order(q)] + stretch(q);
168               page_shrink = page_shrink + shrink(q);
169
170               if ((shrink_order(q) != normal) && (shrink(q) != 0))
171               {
172                 print_err("Infinite glue shrinkage inserted from ");
173                 print_esc("skip");
174                 print_int(n);
175                 help3("The correction glue for page breaking with insertions",
176                     "must have finite shrinkability. But you may proceed,",
177                     "since the offensive shrinkability has been made finite.");
178                 error();
179               }
180             }
181
182             if (type(r) == split_up)
183               insert_penalties = insert_penalties + float_cost(p);
184             else
185             {
186               last_ins_ptr(r) = p;
187               delta = page_goal - page_total - page_depth + page_shrink;
188
189               if (count(n) == 1000)
190                 h = height(p);
191               else
192                 h = x_over_n(height(p), 1000) * count(n);
193
194               if (((h <= 0) || (h <= delta)) && (height(p) + height(r) <= dimen(n)))
195               {
196                 page_goal = page_goal - h;
197                 height(r) = height(r) + height(p);
198               }
199               else
200               {
201                 if (count(n) <= 0)
202                   w = max_dimen;  /* 2^30 - 1 */
203                 else
204                 {
205                   w = page_goal - page_total - page_depth;
206
207                   if (count(n) != 1000)
208                     w = x_over_n(w, count(n)) * 1000;
209                 }
210
211                 if (w > dimen(n) - height(r))
212                   w = dimen(n) - height(r);
213
214                 q = vert_break(ins_ptr(p), w, depth(p));
215                 height(r) = height(r) + best_height_plus_depth;
216
217 #ifdef STAT
218                 if (tracing_pages > 0)
219                 {
220                   begin_diagnostic();
221                   print_nl("% split");
222                   print_int(n);
223                   print_string(" to");
224                   print_scaled(w);
225                   print_char(',');
226                   print_scaled(best_height_plus_depth);
227                   print_string(" p=");
228
229                   if (q == 0)
230                     print_int(eject_penalty);
231                   else if (type(q) == penalty_node)
232                     print_int(penalty(q));
233                   else
234                     print_char('0');
235
236                   end_diagnostic(false);
237                 }
238 #endif /* STAT */
239                 if (count(n) != 1000)
240                   best_height_plus_depth = x_over_n(best_height_plus_depth, 1000) * count(n);
241
242                 page_goal = page_goal - best_height_plus_depth;
243                 type(r) = split_up;
244                 broken_ptr(r) = q;
245                 broken_ins(r) = p;
246
247                 if (q == 0)
248                   insert_penalties = insert_penalties + (eject_penalty);
249                 else if (type(q) == penalty_node)
250                   insert_penalties = insert_penalties + penalty(q);
251               }
252             }
253             goto lab80;
254           }
255           break;
256
257         default:
258           {
259             confusion("page");
260             return;       // abort_flag set
261           }
262           break;
263       }
264
265       if (pi < inf_penalty)
266       {
267         if (page_total < page_goal)
268           if ((page_so_far[3] != 0) || (page_so_far[4] != 0) || (page_so_far[5] != 0))
269             b = 0;
270           else
271             b = badness(page_goal - page_total, page_so_far[2]);
272         else if (page_total - page_goal > page_shrink)
273           b = awful_bad;  /* 2^30 - 1 */
274         else
275           b = badness(page_total - page_goal, page_shrink);
276   
277         if (b < awful_bad) /* 2^30 - 1 */
278           if (pi <= eject_penalty)
279             c = pi; 
280           else if (b < inf_bad)
281             c = b + pi + insert_penalties;
282           else
283             c = deplorable;
284         else
285           c = b;
286
287         if (insert_penalties >= 10000)
288           c = awful_bad;  /* 2^30 - 1 */
289
290 #ifdef STAT
291         if (tracing_pages > 0)
292         {
293           begin_diagnostic();
294           print_nl("%");
295           print_string(" t=");
296           print_totals();
297           print_string(" g=");
298           print_scaled(page_goal);
299           print_string(" b=");
300
301           if (b == awful_bad) /* 2^30 - 1 */
302             print_char('*');
303           else
304             print_int(b);
305
306           print_string(" p=");
307           print_int(pi);
308           print_string(" c=");
309
310           if (c == awful_bad) /* 2^30 - 1 */
311             print_char('*');
312           else
313             print_int(c);
314
315           if (c <= least_page_cost)
316             print_char('#');
317
318           end_diagnostic(false);
319         }
320 #endif /* STAT */
321
322         if (c <= least_page_cost)
323         {
324           best_page_break = p;
325           best_size = page_goal;
326           least_page_cost = c;
327           r = link(page_ins_head);
328
329           while (r != page_ins_head)
330           {
331             best_ins_ptr(r) = last_ins_ptr(r);
332             r = link(r);
333           }
334         }
335
336         if ((c == awful_bad) || (pi <= eject_penalty))  /* 2^30 - 1 */
337         {
338           fire_up(p);
339
340           if (output_active)
341             return;
342
343           goto lab30;
344         }
345       }
346
347       if ((type(p) < glue_node) || (type(p) > kern_node))
348         goto lab80; 
349 lab90:
350       if (type(p) == kern_node)
351         q = p;
352       else
353       {
354         q = glue_ptr(p);
355         page_so_far[2 + stretch_order(q)] = page_so_far[2 + stretch_order(q)] + stretch(q);
356         page_shrink = page_shrink + shrink(q);
357
358         if ((shrink_order(q) != normal) && (shrink(q) != 0))
359         {
360           print_err("Infinite glue shrinkage found on current page");
361           help4("The page about to be output contains some infinitely",
362             "shrinkable glue, e.g., `\\vss' or `\\vskip 0pt minus 1fil'.",
363             "Such glue doesn't belong there; but you can safely proceed,",
364             "since the offensive shrinkability has been made finite.");
365           error();
366           r = new_spec(q);
367           shrink_order(r) = normal;
368           delete_glue_ref(q);
369           glue_ptr(p) = r;
370           q = r;
371         }
372       }
373
374       page_total = page_total + page_depth + width(q);
375       page_depth = 0;
376 lab80:
377       if (page_depth > page_max_depth)
378       {
379         page_total = page_total + page_depth - page_max_depth;
380         page_depth = page_max_depth;
381       }
382
383       link(page_tail) = p;
384       page_tail = p;
385       link(contrib_head) = link(p);
386       link(p) = 0;
387       goto lab30;
388 lab31:
389       link(contrib_head) = link(p);
390       link(p) = 0;
391       flush_node_list(p);
392 lab30:;
393     }
394   while (!(link(contrib_head) == 0));
395
396   if (nest_ptr == 0)
397     tail = contrib_head;
398   else
399     nest[0].tail_field = contrib_head;
400
401 /* sec 1043 */
402 void app_space (void)
403 {
404   halfword q;
405
406   if ((space_factor >= 2000) && (xspace_skip != zero_glue))
407     q = new_param_glue(xspace_skip_code);
408   else
409   {
410     if (space_skip != zero_glue)
411       main_p = space_skip;
412     else
413     {
414       main_p = font_glue[cur_font];
415
416       if (main_p == 0)
417       {
418         main_p = new_spec(zero_glue);
419         main_k = param_base[cur_font] + space_code;
420         width(main_p) = font_info[main_k].cint;
421         stretch(main_p) = font_info[main_k + 1].cint;
422         shrink(main_p) = font_info[main_k + 2].cint;
423         font_glue[cur_font] = main_p;
424       }
425     }
426
427     main_p = new_spec(main_p);
428
429     if (space_factor >= 2000)
430       width(main_p) = width(main_p) + extra_space(cur_font);
431
432     stretch(main_p) = xn_over_d(stretch(main_p), space_factor, 1000);
433     shrink(main_p) = xn_over_d(shrink(main_p), 1000, space_factor);
434     q = new_glue(main_p);
435     glue_ref_count(main_p) = 0;
436   }
437
438   link(tail) = q;
439   tail = q;
440 }
441 /* called from tex8.c only */
442 /* sec 1047 */
443 void insert_dollar_sign (void)
444 {
445   back_input();
446   cur_tok = math_shift_token + '$';
447   print_err("Missing $ inserted");
448   help2("I've inserted a begin-math/end-math symbol since I think",
449       "you left one out. Proceed, with fingers crossed.");
450   ins_error();
451 }
452 /* sec 1049 */
453 void you_cant (void)
454 {
455   print_err("You can't use `");
456   print_cmd_chr(cur_cmd, cur_chr);
457   print_string("' in ");
458   print_mode(mode);
459 }
460 /* sec 1050 */
461 void report_illegal_case (void)
462 {
463   you_cant();
464   help4("Sorry, but I'm not programmed to handle this case;",
465       "I'll just pretend that you didn't ask for it.",
466       "If you're in the wrong mode, you might be able to",
467       "return to the right one by typing `I}' or `I$' or `I\\par'.");
468   error();
469 }
470 /* sec 1051 */
471 bool privileged (void)
472 {
473   if (mode > 0)
474     return true;
475   else
476   {
477     report_illegal_case();
478     return false;
479   }
480 }
481 /* sec 1054 */
482 bool its_all_over (void)
483 {
484   if (privileged ())
485   {
486     if ((page_head == page_tail) && (head == cur_list.tail_field) && (dead_cycles == 0))
487     {
488       return true;
489     }
490
491     back_input();
492     tail_append(new_null_box());
493     width(tail) = hsize;
494     tail_append(new_glue(fill_glue));
495     tail_append(new_penalty(-1073741824L));
496     build_page();
497   }
498
499   return false;
500 }
501 /* sec 1060 */
502 void append_glue (void)
503 {
504   small_number s;
505
506   s = cur_chr;
507
508   switch(s)
509   {
510     case fil_code:
511       cur_val = fil_glue;
512       break;
513
514     case fill_code:
515       cur_val = fill_glue;
516       break;
517
518     case ss_code:
519       cur_val = ss_glue;
520       break;
521
522     case fil_neg_code:
523       cur_val = fil_neg_glue;
524       break;
525
526     case skip_code:
527       scan_glue(glue_val);
528       break;
529
530     case mskip_code:
531       scan_glue(mu_val);
532       break;
533   }
534
535   tail_append(new_glue(cur_val));
536
537   if (s >= skip_code)
538   {
539     decr(glue_ref_count(cur_val));
540
541     if (s > skip_code)
542       subtype(tail) = mu_glue;
543   }
544 }
545 /* sec 1061 */
546 void append_kern (void)
547
548   quarterword s;
549
550   s = cur_chr;
551
552   scan_dimen(s == mu_glue, false, false);
553   tail_append(new_kern(cur_val));
554   subtype(tail) = s;
555 }
556 /* sec 1064 */
557 void off_save (void)
558 {
559   halfword p;
560
561   if (cur_group == bottom_level)
562   {
563     print_err("Extra ");
564     print_cmd_chr(cur_cmd, cur_chr);
565     help1("Things are pretty mixed up, but I think the worst is over.");
566     error();
567   }
568   else
569   {
570     back_input();
571     p = get_avail();
572     link(temp_head) = p;
573     print_err("Missing ");
574
575     switch (cur_group)
576     {
577       case semi_simple_group:
578         {
579           info(p) = cs_token_flag + frozen_end_group;
580           print_esc("endgroup");
581         }
582         break;
583
584       case math_shift_group:
585         {
586           info(p) = math_shift_token + '$';
587           print_char('$');
588         }
589         break;
590
591       case math_left_group:
592         {
593           info(p) = cs_token_flag + frozen_right;
594           link(p) = get_avail();
595           p = link(p);
596           info(p) = other_token + '.';
597           print_esc("right.");
598         }
599         break;
600
601       default:
602         {
603           info(p) = right_brace_token + '}';
604           print_char('}');
605         }
606         break;
607     }
608
609     print_string(" inserted");
610     ins_list(link(temp_head));
611     help5("I've inserted something that you may have forgotten.",
612         "(See the <inserted text> above.)",
613         "With luck, this will get me unwedged. But if you",
614         "really didn't forget anything, try typing `2' now; then",
615         "my insertion and my current dilemma will both disappear.");
616     error();
617   }
618 }
619 /* only called from tex8.c */
620 /* sec 1069 */
621 void extra_right_brace (void)
622 {
623   print_err("Extra }, or forgotten ");
624
625   switch(cur_group)
626   {
627     case semi_simple_group:
628       print_esc("endgroup");
629       break;
630
631     case math_shift_group:
632       print_char('$');
633       break;
634
635     case math_left_group:
636       print_esc("right");
637       break;
638   }
639
640   help5("I've deleted a group-closing symbol because it seems to be",
641       "spurious, as in `$x}$'. But perhaps the } is legitimate and",
642       "you forgot something else, as in `\\hbox{$x}'. In such cases",
643       "the way to recover is to insert both the forgotten and the",
644       "deleted material, e.g., by typing `I$}'.");
645   error();
646   incr(align_state);
647 }
648 /* sec 1070 */
649 void normal_paragraph (void)
650 {
651   if (looseness != 0)
652     eq_word_define(int_base + looseness_code, 0);
653
654   if (hang_indent != 0)
655     eq_word_define(dimen_base + hang_indent_code, 0);
656
657   if (hang_after != 1)
658     eq_word_define(int_base + hang_after_code, 1);
659
660   if (par_shape_ptr != 0)
661     eq_define(par_shape_loc, shape_ref, 0);
662 }
663 /* sec 1075 */
664 void box_end_(integer box_context)
665 {
666   halfword p;
667
668   if (box_context < box_flag)
669   {
670     if (cur_box != 0)
671     {
672       shift_amount(cur_box) = box_context;
673
674       if (abs(mode) == vmode)
675       {
676         append_to_vlist(cur_box);
677
678         if (adjust_tail != 0)
679         {
680           if (adjust_head != adjust_tail)
681           {
682             link(tail) = link(adjust_head);
683             tail = adjust_tail;
684           }
685
686           adjust_tail = 0;
687         }
688
689         if (mode > 0)
690           build_page();
691       }
692       else
693       {
694         if (abs(mode) == hmode)
695           space_factor = 1000;
696         else
697         {
698           p = new_noad();
699           math_type(nucleus(p)) = sub_box;
700           info(nucleus(p)) = cur_box;
701           cur_box = p;
702         }
703
704         link(tail) = cur_box;
705         tail = cur_box;
706       }
707     }
708   }
709   else if (box_context < ship_out_flag)
710     if (box_context < (box_flag + 256))
711       eq_define((box_base - box_flag) + box_context, box_ref, cur_box);
712     else
713       geq_define((box_base - box_flag - 256) + box_context, box_ref, cur_box);
714   else if (cur_box != 0)
715     if (box_context > ship_out_flag)
716     {
717       do
718         {
719           get_x_token();
720         }
721       while(!((cur_cmd != spacer) && (cur_cmd != relax)));
722
723       if (((cur_cmd == hskip) && (abs(mode)!= vmode)) || ((cur_cmd == vskip) && (abs(mode) == vmode)))
724       {
725         append_glue();
726         subtype(tail) = box_context - (leader_flag - a_leaders);
727         leader_ptr(tail) = cur_box;
728       }
729       else
730       {
731         print_err("Leaders not followed by proper glue");
732         help3("You should say `\\leaders <box or rule><hskip or vskip>'.",
733             "I found the <box or rule>, but there's no suitable",
734             "<hskip or vskip>, so I'm ignoring these leaders.");
735         back_error();
736         flush_node_list(cur_box);
737       }
738     }
739     else
740       ship_out(cur_box);
741 }
742 /* called only from tex8.c */
743 /* sec 1079 */
744 void begin_box_(integer box_context)
745 {
746   halfword p, q;
747   quarterword m;
748   halfword k;
749   eight_bits n;
750
751   switch(cur_chr)
752   {
753     case box_code:
754       {
755         scan_eight_bit_int();
756         cur_box = box(cur_val);
757         box(cur_val) = 0;
758       }
759       break;
760
761     case copy_code:
762       {
763         scan_eight_bit_int();
764         cur_box = copy_node_list(box(cur_val));
765       }
766       break;
767
768     case last_box_code:
769       {
770         cur_box = 0;
771
772         if (abs(mode) == mmode)
773         {
774           you_cant();
775           help1("Sorry; this \\lastbox will be void.");
776           error();
777         }
778         else if ((mode == vmode) && (head == cur_list.tail_field))
779         {
780           you_cant();
781           help2("Sorry...I usually can't take things from the current page.",
782               "This \\lastbox will therefore be void.");
783           error();
784         }
785         else
786         {
787           if (!(tail >= hi_mem_min))
788             if ((type(tail) == hlist_node) || (type(tail) == vlist_node))
789             {
790               q = head;
791
792               do
793                 {
794                   p = q;
795
796                   if (!(q >= hi_mem_min))
797                     if (type(q) == disc_node)
798                     {
799                       for (m = 1; m <= replace_count(q); m++)
800                         p = link(p);
801
802                       if (p == tail)
803                         goto lab30;
804                     }
805
806                   q = link(p);
807                 }
808               while (!(q == tail));
809
810               cur_box = tail;
811               shift_amount(cur_box) = 0;
812               tail = p;
813               link(p) = 0;
814 lab30:
815               ;
816             }
817         }
818       }
819       break;
820
821     case vsplit_code:
822       {
823         scan_eight_bit_int();
824         n = cur_val;
825
826         if (!scan_keyword("to"))
827         {
828           print_err("Missing `to' inserted");
829           help2("I'm working on `\\vsplit<box number> to <dimen>';",
830               "will look for the <dimen> next.");
831           error();
832         }
833
834         scan_dimen(false, false, false);
835         cur_box = vsplit(n, cur_val);
836       }
837       break;
838
839     default:
840       {
841         k = cur_chr - vtop_code;
842         saved(0) = box_context;
843
844         if (k == hmode)
845           if ((box_context < box_flag) && (abs(mode) == vmode))
846             scan_spec(adjust_hbox_group, true);
847           else
848             scan_spec(hbox_group, true);
849         else
850         {
851           if (k == vmode)
852             scan_spec(vbox_group, true);
853           else
854           {
855             scan_spec(vtop_group, true);
856             k = vmode;
857           }
858
859           normal_paragraph();
860         }
861
862         push_nest();
863         mode = - (integer) k;
864
865         if (k == vmode)
866         {
867           prev_depth = ignore_depth;
868
869           if (every_vbox != 0)
870             begin_token_list(every_vbox, every_vbox_text);
871         }
872         else
873         {
874           space_factor = 1000;
875
876           if (every_hbox != 0)
877             begin_token_list(every_hbox, every_vbox_text);
878         }
879         return;
880       }
881       break;
882   }
883
884   box_end(box_context);
885 }
886 /* sec 1084 */
887 void scan_box_(integer box_context)
888 {
889   do
890     {
891       get_x_token(); 
892     }
893   while (!((cur_cmd != spacer) && (cur_cmd != relax)));
894
895   if (cur_cmd == make_box)
896   {
897     begin_box(box_context);
898   }
899   else if ((box_context >= leader_flag) && ((cur_cmd == hrule) || (cur_cmd == vrule)))
900   {
901     cur_box = scan_rule_spec();
902     box_end(box_context);
903   }
904   else
905   {
906     print_err("A <box> was supposed to be here");
907     help3("I was expecting to see \\hbox or \\vbox or \\copy or \\box or",
908         "something like that. So you might find something missing in",
909         "your output. But keep trying; you can fix this later.");
910     back_error();
911   }
912 }
913 /****************************************************************************/
914 void package_ (small_number);
915 /****************************************************************************/
916 /* sec 1091 */
917 small_number norm_min_ (integer h)
918 {
919   if (h <= 0)
920     return 1;
921   else if (h >= 63)
922     return 63;
923   else
924     return h;
925 }
926 /* sec 1091 */
927 void new_graf_(bool indented)
928 {
929   prev_graf = 0;
930
931   if ((mode == vmode) || (head != tail))
932     tail_append(new_param_glue(par_skip_code));
933
934   push_nest();
935   mode = hmode;
936   space_factor = 1000;
937   set_cur_lang();
938   clang = cur_lang;
939   prev_graf =(norm_min(left_hyphen_min) * 64 + norm_min(right_hyphen_min)) * 65536L + cur_lang;
940
941   if (indented)
942   {
943     tail = new_null_box();
944     link(head) = tail;
945     width(tail) = par_indent;
946   }
947
948   if (every_par != 0)
949     begin_token_list(every_par, every_par_text);
950
951   if (nest_ptr == 1)
952     build_page();
953 }
954 /* procedure indent_in_hmode; l.21058 */
955 /* sec 1093 */
956 void indent_in_hmode (void)
957 {
958   halfword p, q;
959
960   if (cur_chr > 0)
961   {
962     p = new_null_box();
963     width(p) = par_indent;
964
965     if (abs(mode) == hmode)
966       space_factor = 1000;
967     else
968     {
969       q = new_noad();
970       math_type(nucleus(q)) = sub_box;
971       info(nucleus(q)) = p;
972       p = q;
973     }
974
975     tail_append(p);
976   }
977 }
978 /* only called from tex8.c */
979 /* sec 1095 */
980 void head_for_vmode (void)
981 {
982   if (mode < 0)
983   {
984     if (cur_cmd != hrule)
985       off_save();
986     else
987     {
988       print_err("You can't use `");
989       print_esc("hrule");
990       print_string("' here except with leaders");
991       help2("To put a horizontal rule in an hbox or an alignment,",
992           "you should use \\leaders or \\hrulefill (see The TeXbook).");
993       error();
994     }
995   }
996   else
997   {
998     back_input();
999     cur_tok = par_token;
1000     back_input();
1001     cur_input.index_field = inserted;
1002   }
1003 }
1004 /* sec 1096 */
1005 void end_graf (void)
1006 {
1007   if (mode == hmode)
1008   {
1009     if (head == tail)
1010       pop_nest();
1011     else
1012       line_break(widow_penalty);
1013
1014     normal_paragraph();
1015     error_count = 0;
1016   }
1017 }
1018 /* only called form tex8.c */
1019 /* sec 1099 */
1020 void begin_insert_or_adjust (void)
1021 {
1022   if (cur_cmd == vadjust)
1023     cur_val = 255;
1024   else
1025   {
1026     scan_eight_bit_int();
1027
1028     if (cur_val == 255)
1029     {
1030       print_err("You can't ");
1031       print_esc("insert");
1032       print_int(255);
1033       help1("I'm changing to \\insert0; box 255 is special.");
1034       error();
1035       cur_val = 0;
1036     }
1037   }
1038
1039   saved(0) = cur_val;
1040   incr(save_ptr);
1041   new_save_level(insert_group);
1042   scan_left_brace();
1043   normal_paragraph();
1044   push_nest();
1045   mode = -vmode;
1046   prev_depth = ignore_depth;
1047 }
1048 /* sec 1101 */
1049 void make_mark (void)
1050 {
1051   halfword p;
1052
1053   p = scan_toks(false, true);
1054   p = get_node(small_node_size);
1055   type(p) = mark_node;
1056   subtype(p) = 0;
1057   mark_ptr(p) = def_ref;
1058   link(tail) = p;
1059   tail = p;
1060 }
1061 /* sec 1103 */
1062 void append_penalty (void)
1063 {
1064   scan_int();
1065   tail_append(new_penalty(cur_val));
1066
1067   if (mode == vmode)
1068     build_page();
1069 }
1070 /* only called from tex8.c */
1071 /* sec 1105 */
1072 void delete_last (void)
1073 {
1074   halfword p, q;
1075   quarterword m;
1076
1077   if ((mode == vmode) && (tail == head))
1078   {
1079     if ((cur_chr != glue_node) || (last_glue != max_halfword))
1080     {
1081       you_cant();
1082       help2("Sorry...I usually can't take things from the current page.",
1083           "Try `I\\vskip-\\lastskip' instead.");
1084
1085       if (cur_chr == kern_node)
1086         help_line[0] = "Try `I\\kern-\\last_kern' instead.";
1087       else if (cur_chr != glue_node)
1088         help_line[0] = "Perhaps you can make the output routine do it.";
1089       error();
1090     }
1091   }
1092   else
1093   {
1094     if (!(tail >= hi_mem_min))
1095       if (type(tail) == cur_chr)
1096       {
1097         q = head;
1098
1099         do
1100           {
1101             p = q;
1102
1103             if (!(q >= hi_mem_min))
1104               if (type(q) == disc_node)
1105               {
1106                 for (m = 1; m <= replace_count(q); m++)
1107                   p = link(p);
1108
1109                 if (p == tail)
1110                   return;
1111               }
1112
1113             q = link(p);
1114           }
1115         while (!(q == tail));
1116
1117         link(p) = 0;
1118         flush_node_list(tail);
1119         tail = p;
1120       }
1121   }
1122 }
1123 /* only called from tex8.c */
1124 /* procedure unpackage; l.21256 */
1125 /* sec 1110 */
1126 void unpackage (void)
1127 {
1128   halfword p;
1129   char c;
1130
1131   c = cur_chr;
1132   scan_eight_bit_int();
1133   p = box(cur_val);
1134
1135   if (p == 0)
1136     return;
1137
1138   if ((abs(mode) == mmode) || ((abs(mode) == vmode) && (type(p) != vlist_node)) ||
1139     ((abs(mode) == hmode) && (type(p) != hlist_node)))
1140   {
1141     print_err("Incompatible list can't be unboxed");
1142     help3("Sorry, Pandora. (You sneaky devil.)",
1143         "I refuse to unbox an \\hbox in vertical mode or vice versa.",
1144         "And I can't open any boxes in math mode.");
1145     error();
1146     return;
1147   }
1148
1149   if (c == copy_code)
1150     link(tail) = copy_node_list(list_ptr(p));
1151   else
1152   {
1153     link(tail) = list_ptr(p);
1154     box(cur_val) = 0;
1155     free_node(p, box_node_size);
1156   }
1157
1158   while (link(tail) != 0)
1159     tail = link(tail);
1160 }
1161 /* sec 1113 */
1162 void append_italic_correction (void)
1163 {
1164   halfword p;
1165   internal_font_number f;
1166
1167   if (tail != head)
1168   {
1169     if ((tail >= hi_mem_min))
1170       p = tail;
1171     else if (type(tail) == ligature_node)
1172       p = tail + 1;
1173     else
1174       return;
1175
1176     f = font(p);
1177     tail_append(new_kern(char_italic(f, char_info(f, character(p)))));
1178     subtype(tail) = explicit;
1179   }
1180 }
1181 /* sec 1117 */
1182 void append_discretionary (void)
1183 {
1184   integer c;
1185
1186   tail_append(new_disc());
1187
1188   if (cur_chr == 1)
1189   {
1190     c = hyphen_char[cur_font];
1191
1192     if (c >= 0)
1193       if (c < 256)
1194         pre_break(tail) = new_character(cur_font, c);
1195   }
1196   else
1197   {
1198     incr(save_ptr);
1199     saved(-1) = 0;
1200     new_save_level(disc_group);
1201     scan_left_brace();
1202     push_nest();
1203     mode = -hmode;
1204     space_factor = 1000;
1205   }
1206 }
1207 /* only called form tex8.c */
1208 /* sec 1119 */
1209 void build_discretionary (void)
1210 {
1211   halfword p, q;
1212   integer n;
1213
1214   unsave();
1215   q = head;
1216   p = link(q);
1217   n = 0;
1218
1219   while (p != 0)
1220   {
1221     if (!(p >= hi_mem_min))
1222       if (type(p) > rule_node)
1223         if (type(p) != kern_node)
1224           if (type(p) != ligature_node)
1225           {
1226             print_err("Improper discretionary list");
1227             help1("Discretionary lists must contain only boxes and kerns.");
1228             error();
1229             begin_diagnostic();
1230             print_nl("The following discretionary sublist has been deleted:");
1231             show_box(p);
1232             end_diagnostic(true);
1233             flush_node_list(p);
1234             link(q) = 0;
1235             goto lab30;
1236           }
1237
1238     q = p;
1239     p = link(q);
1240     incr(n);
1241   }
1242
1243 lab30:
1244   p = link(head);
1245   pop_nest();
1246
1247   switch (saved(-1))
1248   {
1249     case 0:
1250       pre_break(tail) = p;
1251       break;
1252
1253     case 1:
1254       post_break(tail) = p;
1255       break;
1256
1257     case 2:
1258       {
1259         if ((n > 0) && (abs(mode) == mmode))
1260         {
1261           print_err("Illegal math ");
1262           print_esc("discretionary");
1263           help2("Sorry: The third part of a discretionary break must be",
1264               "empty, in math formulas. I had to delete your third part.");
1265           flush_node_list(p);
1266           n = 0;
1267           error();
1268         }
1269         else
1270           link(tail) = p;
1271
1272         if (n <= max_quarterword)
1273           replace_count(tail) = n;
1274         else
1275         {
1276           print_err("Discretionary list is too long");
1277           help2("Wow---I never thought anybody would tweak me here.",
1278               "You can't seriously need such a huge discretionary list?");
1279           error();
1280         }
1281
1282         if (n > 0)
1283           tail = q;
1284
1285         decr(save_ptr);
1286         return;
1287       }
1288       break;
1289   }
1290
1291   incr(saved(-1));
1292   new_save_level(disc_group);
1293   scan_left_brace();
1294   push_nest();
1295   mode = -hmode;
1296   space_factor = 1000;
1297 }
1298 /* called only from tex8.c */
1299 /* sec 1123 */
1300 void make_accent (void)
1301 {
1302   real s, t;
1303   halfword p, q, r;
1304   internal_font_number f;
1305   scaled a, h, x, w, delta;
1306   ffourquarters i;
1307
1308   scan_char_num();
1309   f = cur_font;
1310   p = new_character(f, cur_val);
1311
1312   if (p != 0)
1313   {
1314     x = x_height(f);
1315     s = slant(f) / ((double) 65536.0);
1316     a = char_width(f, char_info(f, character(p)));
1317     do_assignments();
1318     q = 0;
1319     f = cur_font;
1320
1321     if ((cur_cmd == letter) || (cur_cmd == other_char) || (cur_cmd == char_given))
1322       q = new_character(f, cur_chr);
1323     else if (cur_cmd == char_num)
1324     {
1325       scan_char_num();
1326       q = new_character(f, cur_val);
1327     }
1328     else
1329       back_input();
1330
1331     if (q != 0)
1332     {
1333       t = slant(f) / ((double) 65536.0);
1334       i = char_info(f, character(q));
1335       w = char_width(f, i);
1336       h = char_height(f, height_depth(i));
1337
1338       if (h != x)
1339       {
1340         p = hpack(p, 0, 1);
1341         shift_amount(p) = x - h;
1342       }
1343
1344       delta = round((w - a) / ((double) 2.0)+ h * t - x * s);
1345       r = new_kern(delta);
1346       subtype(r) = acc_kern;
1347       link(tail) = r;
1348       link(r) = p;
1349       tail = new_kern(- (integer) a - delta);
1350       subtype(tail) = acc_kern;
1351       link(p) = tail;
1352       p = q;
1353     }
1354
1355     link(tail) = p;
1356     tail = p;
1357     space_factor = 1000;
1358   }
1359 }
1360 /* sec 1127 */
1361 void align_error (void)
1362 {
1363   if (abs(align_state) > 2)
1364   {
1365     print_err("Misplaced ");
1366     print_cmd_chr(cur_cmd, cur_chr);
1367
1368     if (cur_tok == tab_token + '&')
1369     {
1370       help6("I can't figure out why you would want to use a tab mark",
1371           "here. If you just want an ampersand, the remedy is",
1372           "simple: Just type `I\\&' now. But if some right brace",
1373           "up above has ended a previous alignment prematurely,",
1374           "you're probably due for more error messages, and you",
1375           "might try typing `S' now just to see what is salvageable.");
1376     }
1377     else
1378     {
1379       help5("I can't figure out why you would want to use a tab mark",
1380           "or \\cr or \\span just now. If something like a right brace",
1381           "up above has ended a previous alignment prematurely,",
1382           "you're probably due for more error messages, and you",
1383           "might try typing `S' now just to see what is salvageable.");
1384     }
1385
1386     error();
1387   }
1388   else
1389   {
1390     back_input();
1391
1392     if (align_state < 0)
1393     {
1394       print_err("Missing { inserted");
1395       incr(align_state);
1396       cur_tok = left_brace_token + '{';
1397     }
1398     else
1399     {
1400       print_err("Missing } inserted");
1401       decr(align_state);
1402       cur_tok = right_brace_token + '}';
1403     }
1404
1405     help3("I've put in what seems to be necessary to fix",
1406         "the current column of the current alignment.",
1407         "Try to go on, since this might almost work.");
1408     ins_error();
1409   }
1410 }
1411 /* sec 1129 */
1412 void noalign_error (void)
1413 {
1414   print_err("Misplaced ");
1415   print_esc("noalign");
1416   help2("I expect to see \\noalign only after the \\cr of",
1417       "an alignment. Proceed, and I'll ignore this case.");
1418   error();
1419 }
1420 /* only called from tex8.c */
1421 /* sec 1129 */
1422 void omit_error (void)
1423 {
1424   print_err("Misplaced ");
1425   print_esc("omit");
1426   help2("I expect to see \\omit only after tab marks or the \\cr of",
1427       "an alignment. Proceed, and I'll ignore this case.");
1428   error();
1429 }
1430 /* sec 1131 */
1431 void do_endv (void)
1432 {
1433   base_ptr = input_ptr;
1434   input_stack[base_ptr] = cur_input;
1435
1436   while ((input_stack[base_ptr].index_field != v_template) &&
1437     (input_stack[base_ptr].loc_field == 0) &&
1438     (input_stack[base_ptr].state_field == token_list))
1439     decr(base_ptr);
1440
1441   if ((input_stack[base_ptr].index_field != v_template) ||
1442     (input_stack[base_ptr].loc_field != 0) ||
1443     (input_stack[base_ptr].state_field != token_list))
1444     fatal_error("(interwoven alignment preambles are not allowed)");
1445
1446   if (cur_group == align_group)
1447   {
1448     end_graf();
1449
1450     if (fin_col ())
1451       fin_row();
1452   }
1453   else
1454     off_save();
1455 }
1456 /* only called form tex8.c */
1457 /* sec 1135 */
1458 void cs_error (void)
1459 {
1460   print_err("Extra ");
1461   print_esc("endcsname");
1462   help1("I'm ignoring this, since I wasn't doing a \\csname."); 
1463   error();
1464 }
1465 /* sec 1136 */
1466 void push_math_(group_code c)
1467 {
1468   push_nest();
1469   mode = -mmode;
1470   incompleat_noad = 0;
1471   new_save_level(c);
1472 }
1473 /* sec 1138 */
1474 void init_math (void)
1475 {
1476   scaled w;
1477   scaled l;
1478   scaled s;
1479   halfword p;
1480   halfword q;
1481   internal_font_number f;
1482   integer n;
1483   scaled v;
1484   scaled d;
1485
1486   get_token();
1487
1488   if ((cur_cmd == math_shift) && (mode > 0))
1489   {
1490     if (head == tail)
1491     {
1492       pop_nest();
1493       w = -max_dimen; /* - (2^30 - 1) */
1494     }
1495     else
1496     {
1497       line_break(display_widow_penalty);
1498       v = shift_amount(just_box) + 2 * quad(cur_font);
1499       w = -max_dimen;  /* - (2^30 - 1) */
1500       p = list_ptr(just_box);
1501
1502       while (p != 0)
1503       {
1504 lab21:
1505         if ((p >= hi_mem_min))
1506         {
1507           f = font(p);
1508           d = char_width(f, char_info(f, character(p)));
1509           goto lab40;
1510         }
1511
1512         switch (type(p))
1513         {
1514           case hlist_node:
1515           case vlist_node:
1516           case rule_node:
1517             {
1518               d = width(p);
1519               goto lab40;
1520             }
1521             break;
1522
1523           case ligature_node:
1524             {
1525               mem[lig_trick] = mem[lig_char(p)];
1526               link(lig_trick) = link(p);
1527               p = lig_trick;
1528               goto lab21;
1529             }
1530             break;
1531
1532           case kern_node:
1533           case math_node:
1534             d = width(p);
1535             break;
1536
1537           case glue_node:
1538             {
1539               q = glue_ptr(p);
1540               d = width(q);
1541
1542               if (glue_sign(just_box) == stretching)
1543               {
1544                 if ((glue_order(just_box) == stretch_order(q)) && (stretch(q) != 0))
1545                   v = max_dimen;  /* - (2^30 - 1) */
1546               }
1547               else if (glue_sign(just_box) == shrinking)
1548               {
1549                 if ((glue_order(just_box) == shrink_order(q)) && (shrink(q) != 0))
1550                   v = max_dimen;  /* - (2^30 - 1) */
1551               }
1552
1553               if (subtype(p) >= a_leaders)
1554                 goto lab40;
1555             }
1556             break;
1557
1558           case whatsit_node:
1559             d = 0;
1560             break;
1561
1562           default:
1563             d = 0;
1564             break;
1565         }
1566
1567         if (v < max_dimen) /* - (2^30 - 1) */
1568           v = v + d;
1569
1570         goto lab45;
1571 lab40:
1572         if (v < max_dimen) /* - (2^30 - 1) */
1573         {
1574           v = v + d;
1575           w = v;
1576         }
1577         else
1578         {
1579           w = max_dimen;  /* - (2^30 - 1) */
1580           goto lab30;
1581         }
1582 lab45:
1583         p = link(p);
1584       }
1585 lab30:;
1586     }
1587
1588     if (par_shape_ptr == 0)
1589       if ((hang_indent != 0) && (((hang_after >= 0) &&
1590         (prev_graf + 2 > hang_after)) || (prev_graf + 1 < - (integer) hang_after)))
1591       {
1592         l = hsize - abs(hang_indent);
1593
1594         if (hang_indent > 0)
1595           s = hang_indent;
1596         else
1597           s = 0;
1598       }
1599       else
1600       {
1601         l = hsize;
1602         s = 0;
1603       }
1604     else
1605     {
1606       n = info(par_shape_ptr);
1607
1608       if (prev_graf + 2 >= n)
1609         p = par_shape_ptr + 2 * n;
1610       else
1611         p = par_shape_ptr + 2 *(prev_graf + 2);
1612
1613       s = mem[p - 1].cint;
1614       l = mem[p].cint;
1615     }
1616
1617     push_math(math_shift_group);
1618     mode = mmode;
1619     eq_word_define(int_base + cur_fam_code, -1);
1620     eq_word_define(dimen_base + pre_display_size_code, w);
1621     eq_word_define(dimen_base + display_width_code, l);
1622     eq_word_define(dimen_base + display_indent_code, s);
1623
1624     if (every_display != 0)
1625       begin_token_list(every_display, every_display_text);
1626
1627     if (nest_ptr == 1)
1628     {
1629       build_page();
1630     }
1631   }
1632   else
1633   {
1634     back_input();
1635
1636     {
1637       push_math(math_shift_group);
1638       eq_word_define(int_base + cur_fam_code, -1);
1639
1640       if (every_math != 0)
1641         begin_token_list(every_math, every_math_text);
1642     }
1643   }
1644 }
1645 /* sec 1142 */
1646 void start_eq_no (void)
1647 {
1648   saved(0) = cur_chr;
1649   incr(save_ptr);
1650
1651   {
1652     push_math(math_shift_group);
1653     eq_word_define(int_base + cur_fam_code, -1);
1654
1655     if (every_math != 0)
1656       begin_token_list(every_math, every_math_text);
1657   }
1658 }
1659 /* sec 1151 */
1660 void scan_math_(halfword p)
1661 {
1662   integer c;
1663
1664 lab20:
1665   do
1666     {
1667       get_x_token();
1668     }
1669   while(!((cur_cmd != spacer) && (cur_cmd != relax)));
1670
1671 lab21:
1672   switch (cur_cmd)
1673   {
1674     case letter:
1675     case other_char:
1676     case char_given:
1677       {
1678         c = math_code(cur_chr);
1679
1680         if (c == 32768L)
1681         {
1682           {
1683             cur_cs = cur_chr + active_base;
1684             cur_cmd = eq_type(cur_cs);
1685             cur_chr = equiv(cur_cs);
1686             x_token();
1687             back_input();
1688           }
1689
1690           goto lab20;
1691         }
1692       }
1693       break;
1694
1695     case char_num:
1696       {
1697         scan_char_num();
1698         cur_chr = cur_val;
1699         cur_cmd = char_given;
1700         goto lab21;
1701       }
1702       break;
1703
1704     case math_char_num:
1705       {
1706         scan_fifteen_bit_int();
1707         c = cur_val;
1708       }
1709       break;
1710
1711     case math_given:
1712       c = cur_chr;
1713       break;
1714
1715     case delim_num:
1716       {
1717         scan_twenty_seven_bit_int();
1718         c = cur_val / 4096;
1719       }
1720       break;
1721
1722     default:
1723       {
1724         back_input();
1725         scan_left_brace();
1726         saved(0) = p;
1727         incr(save_ptr);
1728         push_math(math_group);
1729         return;
1730       }
1731       break;
1732   }
1733
1734   math_type(p) = math_char;
1735   character(p) = c % 256;
1736
1737   if ((c >= var_code) && ((cur_fam >= 0) && (cur_fam < 16)))
1738     fam(p) = cur_fam;
1739   else
1740     fam(p) = (c / 256) % 16;
1741 }
1742 /* sec 1155 */
1743 void set_math_char_(integer c)
1744 {
1745   halfword p;
1746
1747   if (c >= 32768L)
1748   {
1749     cur_cs = cur_chr + active_base;
1750     cur_cmd = eq_type(cur_cs);
1751     cur_chr = equiv(cur_cs);
1752     x_token();
1753     back_input();
1754   }
1755   else
1756   {
1757     p = new_noad();
1758     math_type(nucleus(p)) = math_char;
1759     character(nucleus(p)) = c % 256;
1760     fam(nucleus(p)) = (c / 256) % 16;
1761
1762     if (c >= var_code)
1763     {
1764       if (((cur_fam >= 0) && (cur_fam < 16)))
1765         fam(nucleus(p)) = cur_fam;
1766
1767       type(p) = ord_noad;
1768     }
1769     else
1770       type(p) = ord_noad + (c / 4096);
1771
1772     link(tail) = p;
1773     tail = p;
1774   }
1775 }
1776 /* sec 1159 */
1777 void math_limit_switch (void)
1778 {
1779   if (head != tail)
1780     if (type(tail) == op_noad)
1781     {
1782       subtype(tail) = cur_chr;
1783       return;
1784     }
1785
1786   print_err("Limit controls must follow a math operator");
1787   help1("I'm ignoring this misplaced \\limits or \\nolimits command.");
1788   error();
1789 }
1790 /* sec 1160 */
1791 void scan_delimiter_(halfword p, bool r)
1792 {
1793    if (r)
1794    {
1795      scan_twenty_seven_bit_int();
1796    }
1797    else
1798    {
1799      do
1800       {
1801         get_x_token();
1802       }
1803      while (!((cur_cmd != spacer) && (cur_cmd != relax)));
1804
1805      switch (cur_cmd)
1806      {
1807        case letter:
1808        case other_char:
1809          cur_val = del_code(cur_chr);
1810          break;
1811
1812        case delim_num:
1813          scan_twenty_seven_bit_int();
1814          break;
1815
1816        default:
1817          cur_val = -1;
1818          break;
1819      }
1820    }
1821
1822    if (cur_val < 0)
1823    {
1824      print_err("Missing delimiter (. inserted)");
1825      help6("I was expecting to see something like `(' or `\\{' or",
1826          "`\\}' here. If you typed, e.g., `{' instead of `\\{', you",
1827          "should probably delete the `{' by typing `1' now, so that",
1828          "braces don't get unbalanced. Otherwise just proceed.",
1829          "Acceptable delimiters are characters whose \\delcode is",
1830          "nonnegative, or you can use `\\delimiter <delimiter code>'.");
1831      back_error();
1832      cur_val = 0;
1833    }
1834
1835    small_fam(p) = (cur_val / 1048576L) % 16;
1836    small_char(p) = (cur_val / 4096) % 256;
1837    large_fam(p) = (cur_val / 256) % 16;
1838    large_char(p) = cur_val % 256;
1839 }
1840 /* sec 1163 */
1841 void math_radical (void)
1842 {
1843   tail_append(get_node(radical_noad_size));
1844   type(tail) = radical_noad;
1845   subtype(tail) = normal;
1846   mem[nucleus(tail)].hh = empty_field;
1847   mem[subscr(tail)].hh = empty_field;
1848   mem[supscr(tail)].hh = empty_field;
1849   scan_delimiter(left_delimiter(tail), true);
1850   scan_math(nucleus(tail));
1851 }
1852 /* sec 1165 */
1853 void math_ac (void)
1854 {
1855   if (cur_cmd == accent)
1856   {
1857     print_err("Please use ");
1858     print_esc("mathaccent");
1859     print_string(" for accents in math mode");
1860     help2("I'm changing \\accent to \\mathaccent here; wish me luck.",
1861       "(Accents are not the same in formulas as they are in text.)");
1862     error();
1863   }
1864
1865   tail_append(get_node(accent_noad_size));
1866   type(tail) = accent_noad;
1867   subtype(tail) = normal;
1868   mem[nucleus(tail)].hh = empty_field;
1869   mem[subscr(tail)].hh = empty_field;
1870   mem[supscr(tail)].hh = empty_field;
1871   math_type(accent_chr(tail)) = math_char;
1872   scan_fifteen_bit_int();
1873   character(accent_chr(tail)) = cur_val % 256;
1874
1875   if ((cur_val >= var_code) && ((cur_fam >= 0) && (cur_fam < 16)))
1876     fam(accent_chr(tail)) = cur_fam;
1877   else
1878     fam(accent_chr(tail)) = (cur_val / 256) % 16;
1879
1880   scan_math(nucleus(tail));
1881 }
1882 /* sec 1172 */
1883 void append_choices (void)
1884 {
1885   tail_append(new_choice());
1886   incr(save_ptr);
1887   saved(-1) = 0;
1888   push_math(math_choice_group);
1889   scan_left_brace();
1890 }
1891 /* sec 1184 */
1892 halfword fin_mlist_(halfword p)
1893 {
1894   halfword q;
1895
1896   if (incompleat_noad != 0)
1897   {
1898     math_type(denominator(incompleat_noad)) = sub_mlist;
1899     info(denominator(incompleat_noad)) = link(head);
1900
1901     if (p == 0)
1902       q = incompleat_noad;
1903     else
1904     {
1905       q = info(numerator(incompleat_noad));
1906
1907       if (type(q) != left_noad)
1908       {
1909         confusion("right");
1910         return 0;       // abort_flag set
1911       }
1912
1913       info(numerator(incompleat_noad)) = link(q);
1914       link(q) = incompleat_noad;
1915       link(incompleat_noad) = p;
1916     }
1917   }
1918   else
1919   {
1920     link(tail) = p;
1921     q = link(head);
1922   }
1923   pop_nest();
1924
1925   return q;
1926 }
1927 /* sec 1174 */
1928 void build_choices (void)
1929 {
1930   halfword p;
1931
1932   unsave();
1933   p = fin_mlist(0);
1934
1935   switch (saved(-1))
1936   {
1937     case 0:
1938       display_mlist(tail) = p;
1939       break;
1940
1941     case 1:
1942       text_mlist(tail) = p;
1943       break;
1944
1945     case 2:
1946       script_mlist(tail) = p;
1947       break;
1948
1949     case 3:
1950       {
1951         script_script_mlist(tail) = p;
1952         decr(save_ptr);
1953         return;
1954       }
1955       break;
1956   }
1957
1958   incr(saved(-1));
1959   push_math(math_choice_group);
1960   scan_left_brace();
1961 }
1962 /* sec 1176 */
1963 void sub_sup (void)
1964 {
1965 /*  small_number t; */
1966   int t;              /* 95/Jan/7 */
1967   halfword p;
1968
1969   t = 0;
1970   p = 0;
1971
1972   if (tail != head)
1973     if (script_allowed(tail))
1974     {
1975       p = supscr(tail) + cur_cmd - sup_mark;
1976       t = math_type(p);
1977     }
1978
1979   if ((p == 0) || (t != 0))
1980   {
1981     tail_append(new_noad());
1982     p = supscr(tail) + cur_cmd - sup_mark;
1983
1984     if (t != 0)
1985     {
1986       if (cur_cmd == sup_mark)
1987       {
1988         print_err("Double superscript");
1989         help1("I treat `x^1^2' essentially like `x^1{}^2'.");
1990       }
1991       else
1992       {
1993         print_err("Double subscript");
1994         help1("I treat `x_1_2' essentially like `x_1{}_2'.");
1995       }
1996       error();
1997     }
1998   }
1999   scan_math(p);
2000 }
2001 /* used to continue here with math_fraction etc in tex7.c */
2002 /*****************************************************************************/
2003 /* moved down here to avoid pragma optimize questions 96/Sep/12 */
2004 /* sec 1086 */
2005 void package_(small_number c)
2006 {
2007   scaled h;
2008   halfword p;
2009   scaled d;
2010
2011   d = box_max_depth;
2012   unsave();
2013   save_ptr = save_ptr - 3;
2014
2015   if (mode == -hmode)
2016     cur_box = hpack(link(head), saved(2), saved(1));
2017   else
2018   {
2019     cur_box = vpackage(link(head), saved(2), saved(1), d);
2020
2021     if (c == vtop_code)
2022     {
2023       h = 0;
2024       p = list_ptr(cur_box);
2025
2026       if (p != 0)
2027         if (type(p) <= rule_node)
2028           h = height(p);
2029
2030       depth(cur_box) = depth(cur_box) - h + height(cur_box);
2031       height(cur_box) = h;
2032     }
2033   }
2034   pop_nest();
2035   box_end(saved(0));
2036 }
2037 //#pragma optimize ("", on)           /* 96/Sep/12 */