OSDN Git Service

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