OSDN Git Service

string pool 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     tail_append(new_null_box());
444     width(tail) = hsize;
445     tail_append(new_glue(8));
446     tail_append(new_penalty(-1073741824L));
447     build_page();
448   }
449   Result = false;
450   return Result;
451 }
452 /* sec 1060 */
453 void append_glue (void)
454 {
455   small_number s;
456
457   s = cur_chr;
458
459   switch(s)
460   {
461     case 0:
462       cur_val = 4;
463       break;
464     case 1:
465       cur_val = 8;
466       break;
467     case 2:
468       cur_val = 12;
469       break;
470     case 3:
471       cur_val = 16;
472       break;
473     case 4:
474       scan_glue(2);
475       break;
476     case 5:
477       scan_glue(3);
478       break;
479   }
480
481   tail_append(new_glue(cur_val));
482
483   if (s >= 4)
484   {
485     decr(mem[cur_val].hh.v.RH);
486     if (s > 4)
487       mem[tail].hh.b1 = 99;
488   }
489 }
490 /* sec 1061 */
491 void append_kern (void)
492
493   quarterword s;
494
495   s = cur_chr;
496
497   scan_dimen(s == mu_glue, false, false);
498   tail_append(new_kern(cur_val));
499   subtype(tail) = s;
500 }
501 /* sec 1054 */
502 void off_save (void)
503 {
504   halfword p;
505
506   if (cur_group == 0)
507   {
508     print_err("Extra ");
509     print_cmd_chr(cur_cmd, cur_chr);
510     help1("Things are pretty mixed up, but I think the worst is over.");
511     error();
512   }
513   else
514   {
515     back_input();
516     p = get_avail();
517     mem[temp_head].hh.v.RH = p;
518     print_err("Missing ");
519
520     switch (cur_group)
521     {
522       case 14:
523         {
524 /*  mem[p].hh.v.LH = (hash_size + 4611);  */
525 /*  mem[p].hh.v.LH = (hash_size + 4095 + 516);  */
526           mem[p].hh.v.LH = (hash_size + hash_extra + 4095 + 516); /* 96/Jan/10 */
527           print_esc("endgroup");
528         }
529         break;
530       case 15:
531         {
532           mem[p].hh.v.LH = 804;
533           print_char('$');
534         }
535         break;
536       case 16:
537         {
538 /*  mem[p].hh.v.LH = (hash_size + 4612);  */
539 /*  mem[p].hh.v.LH = (hash_size + 4095 + 517);  */
540           mem[p].hh.v.LH = (hash_size + hash_extra + 4095 + 517); /* 96/Jan/10 */
541           mem[p].hh.v.RH = get_avail();
542           p = mem[p].hh.v.RH;
543           mem[p].hh.v.LH = 3118;
544           print_esc("right.");
545         }
546         break;
547       default:
548         {
549           mem[p].hh.v.LH = 637;
550           print_char('}');
551         }
552         break;
553     }
554     print_string(" inserted");
555     begin_token_list(mem[temp_head].hh.v.RH, 4);
556     help5("I've inserted something that you may have forgotten.",
557         "(See the <inserted text> above.)",
558         "With luck, this will get me unwedged. But if you",
559         "really didn't forget anything, try typing `2' now; then",
560         "my insertion and my current dilemma will both disappear.");
561     error();
562   }
563 }
564 /* only called from tex8.c */
565 /* sec 1069 */
566 void extra_right_brace (void)
567 {
568   print_err("Extra }, or forgotten ");
569
570   switch(cur_group)
571   {
572     case 14:
573       print_esc("endgroup");
574       break;
575     case 15:
576       print_char('$');
577       break;
578     case 16:
579       print_esc("right");
580       break;
581   }
582   help5("I've deleted a group-closing symbol because it seems to be",
583       "spurious, as in `$x}$'. But perhaps the } is legitimate and",
584       "you forgot something else, as in `\\hbox{$x}'. In such cases",
585       "the way to recover is to insert both the forgotten and the",
586       "deleted material, e.g., by typing `I$}'.");
587   error();
588   incr(align_state);
589 }
590 /* sec 1070 */
591 void normal_paragraph (void)
592 {
593   if (looseness != 0)
594     eq_word_define(int_base + looseness_code, 0);
595
596   if (hang_indent != 0)
597     eq_word_define(dimen_base + hang_indent_code, 0);
598
599   if (hang_after != 1)
600     eq_word_define(int_base + hang_after_code, 1);
601
602   if (par_shape_ptr != 0)
603     eq_define(par_shape_loc, shape_ref, 0);
604 }
605 /* sec 1075 */
606 void box_end_(integer boxcontext)
607 {
608   halfword p;
609
610   if (boxcontext < box_flag)
611   {
612     if (cur_box != 0)
613     {
614       shift_amount(cur_box) = boxcontext;
615       if (abs(mode) == vmode)
616       {
617         append_to_vlist(cur_box);
618         if (adjust_tail != 0)
619         {
620           if (adjust_head != adjust_tail)
621           {
622             link(tail) = link(adjust_head);
623             tail = adjust_tail;
624           }
625           adjust_tail = 0;
626         }
627
628         if (mode > 0)
629           build_page();
630       }
631       else
632       {
633         if (abs(mode) == hmode)
634           space_factor = 1000;
635         else
636         {
637           p = new_noad();
638           math_type(nucleus(p)) = sub_box;
639           info(nucleus(p)) = cur_box;
640           cur_box = p;
641         }
642         link(tail) = cur_box;
643         tail = cur_box;
644       }
645     }
646   }
647   else if (boxcontext < ship_out_flag)
648     if (boxcontext < (box_flag + 256))
649       eq_define((box_base - box_flag) + boxcontext, box_ref, cur_box);
650     else
651       geq_define((box_base - box_flag - 256) + boxcontext, box_ref, cur_box);
652   else if (cur_box != 0)
653     if (boxcontext > (ship_out_flag))
654     {
655       do
656         {
657           get_x_token();
658         }
659       while(!((cur_cmd != spacer) && (cur_cmd != relax)));
660
661       if (((cur_cmd == hskip) && (abs(mode)!= vmode)) || ((cur_cmd == vskip) && (abs(mode) == vmode)))
662       {
663         append_glue();
664         subtype(tail) = boxcontext - (leader_flag - a_leaders);
665         leader_ptr(tail) = cur_box;
666       }
667       else
668       {
669         print_err("Leaders not followed by proper glue");
670         help3("You should say `\\leaders <box or rule><hskip or vskip>'.",
671             "I found the <box or rule>, but there's no suitable",
672             "<hskip or vskip>, so I'm ignoring these leaders.");
673         back_error();
674         flush_node_list(cur_box);
675       }
676     }
677     else
678       ship_out(cur_box);
679 }
680 /* called only from tex8.c */
681 /* sec 1079 */
682 void begin_box_(integer boxcontext)
683 {
684   halfword p, q;
685   quarterword m;
686   halfword k;
687   eight_bits n;
688
689   switch(cur_chr)
690   {
691     case box_code:
692       {
693         scan_eight_bit_int();
694         cur_box = box(cur_val);
695         box(cur_val) = 0;
696       }
697       break;
698     case copy_code:
699       {
700         scan_eight_bit_int();
701         cur_box = copy_node_list(box(cur_val));
702       }
703       break;
704     case last_box_code:
705       {
706         cur_box = 0;
707
708         if (abs(mode) == mmode)
709         {
710           you_cant();
711           help1("Sorry; this \\lastbox will be void.");
712           error();
713         }
714         else if ((mode == vmode) && (head == cur_list.tail_field))
715         {
716           you_cant();
717           help2("Sorry...I usually can't take things from the current page.",
718               "This \\lastbox will therefore be void.");
719           error();
720         }
721         else
722         {
723           if (!(tail >= hi_mem_min))
724             if ((type(tail) == hlist_node) || (type(tail) == vlist_node))
725             {
726               q = head;
727               do
728                 {
729                   p = q;
730                   if (!(q >= hi_mem_min))
731                     if (type(q) == disc_node)
732                     {
733                       for (m = 1; m <= replace_count(q); m++)
734                         p = link(p);
735
736                       if (p == tail)
737                         goto lab30;
738                     }
739                   q = link(p);
740                 }
741               while (!(q == tail));
742               cur_box = tail;
743               shift_amount(cur_box) = 0;
744               tail = p;
745               link(p) = 0;
746 lab30:
747               ;
748             }
749         }
750       }
751       break;
752     case vsplit_code:
753       {
754         scan_eight_bit_int();
755         n = cur_val;
756         if (!scan_keyword("to"))
757         {
758           print_err("Missing `to' inserted");
759           help2("I'm working on `\\vsplit<box number> to <dimen>';",
760               "will look for the <dimen> next.");
761           error();
762         }
763         scan_dimen(false, false, false);
764         cur_box = vsplit(n, cur_val);
765       }
766       break;
767     default:
768       {
769         k = cur_chr - vtop_code;
770         save_stack[save_ptr + 0].cint = boxcontext;
771
772         if (k == hmode)
773           if ((boxcontext < box_flag) && (abs(mode) == vmode))
774             scan_spec(adjust_hbox_group, true);
775           else
776             scan_spec(hbox_group, true);
777         else
778         {
779           if (k == vmode)
780             scan_spec(vbox_group, true);
781           else
782           {
783             scan_spec(vtop_group, true);
784             k = vmode;
785           }
786           normal_paragraph();
787         }
788         push_nest();
789         mode = - (integer) k;
790
791         if (k == vmode)
792         {
793           prev_depth = ignore_depth;
794
795           if (every_vbox != 0)
796             begin_token_list(every_vbox, every_vbox_text);
797         }
798         else
799         {
800           space_factor = 1000;
801
802           if (every_hbox != 0)
803             begin_token_list(every_hbox, every_vbox_text);
804         }
805         return;
806       }
807       break;
808   }
809   box_end(boxcontext);
810 }
811 /* sec 1084 */
812 void scan_box_(integer boxcontext)
813 {
814   do
815     {
816       get_x_token(); 
817     }
818   while (!((cur_cmd != spacer) && (cur_cmd != relax)));
819
820   if (cur_cmd == make_box)
821   {
822     begin_box(boxcontext);
823   }
824   else if ((boxcontext >= leader_flag) && ((cur_cmd == hrule) || (cur_cmd == vrule)))
825   {
826     cur_box = scan_rule_spec();
827     box_end(boxcontext);
828   }
829   else
830   {
831     print_err("A <box> was supposed to be here");
832     help3("I was expecting to see \\hbox or \\vbox or \\copy or \\box or",
833         "something like that. So you might find something missing in",
834         "your output. But keep trying; you can fix this later.");
835     back_error();
836   }
837 }
838 /****************************************************************************/
839 void package_ (small_number);
840 /****************************************************************************/
841 /* sec 1091 */
842 small_number norm_min_ (integer h)
843 {
844   if (h <= 0)
845     return 1;
846   else if (h >= 63)
847     return 63;
848   else
849     return h;
850 }
851 /* sec 1091 */
852 void new_graf_(bool indented)
853 {
854   prev_graf = 0;
855
856   if ((mode == vmode) || (head != tail))
857     tail_append(new_param_glue(par_skip_code));
858
859   push_nest();
860   mode = hmode;
861   space_factor = 1000;
862   set_cur_lang();
863   clang = cur_lang;
864   prev_graf =(norm_min(left_hyphen_min) * 64 + norm_min(right_hyphen_min)) * 65536L + cur_lang;
865
866   if (indented)
867   {
868     tail = new_null_box();
869     link(head) = tail;
870     width(tail) = par_indent;
871   }
872
873   if (every_par != 0)
874     begin_token_list(every_par, every_par_text);
875
876   if (nest_ptr == 1)
877     build_page();
878 }
879 /* procedure indent_in_hmode; l.21058 */
880 /* sec 1093 */
881 void indent_in_hmode (void)
882 {
883   halfword p, q;
884
885   if (cur_chr > 0)
886   {
887     p = new_null_box();
888     width(p) = par_indent;
889
890     if (abs(mode) == hmode)
891       space_factor = 1000;
892     else
893     {
894       q = new_noad();
895       math_type(nucleus(q)) = sub_box;
896       info(nucleus(q)) = p;
897       p = q;
898     }
899     tail_append(p);
900   }
901 }
902 /* only called from tex8.c */
903 /* sec 1095 */
904 void head_for_vmode (void)
905 {
906   if (mode < 0)
907     if (cur_cmd != hrule)
908       off_save();
909     else
910     {
911       print_err("You can't use `");
912       print_esc("hrule");
913       print_string("' here except with leaders");
914       help2("To put a horizontal rule in an hbox or an alignment,",
915           "you should use \\leaders or \\hrulefill (see The TeXbook).");
916       error();
917     }
918   else
919   {
920     back_input();
921     cur_tok = par_token;
922     back_input();
923     cur_input.index_field = inserted;
924   }
925 }
926 /* sec 1096 */
927 void end_graf (void)
928 {
929   if (mode == hmode)
930   {
931     if (head == tail)
932       pop_nest();
933     else
934       line_break(widow_penalty);
935
936     normal_paragraph();
937     error_count = 0;
938   }
939 }
940 /* only called form tex8.c */
941 /* sec 1099 */
942 void begin_insert_or_adjust (void)
943 {
944   if (cur_cmd == vadjust)
945     cur_val = 255;
946   else
947   {
948     scan_eight_bit_int();
949
950     if (cur_val == 255)
951     {
952       print_err("You can't ");
953       print_esc("insert");
954       print_int(255);
955       help1("I'm changing to \\insert0; box 255 is special.");
956       error();
957       cur_val = 0;
958     }
959   }
960   save_stack[save_ptr + 0].cint = cur_val;
961   incr(save_ptr);
962   new_save_level(insert_group);
963   scan_left_brace();
964   normal_paragraph();
965   push_nest();
966   mode = -vmode;
967   prev_depth = ignore_depth;
968 }
969 /* sec 1101 */
970 void make_mark (void)
971 {
972   halfword p;
973   p = scan_toks(false, true);
974   p = get_node(small_node_size);
975   type(p) = mark_node;
976   subtype(p) = 0;
977   mark_ptr(p) = def_ref;
978   link(tail) = p;
979   tail = p;
980 }
981 /* sec 1103 */
982 void append_penalty (void)
983 {
984   scan_int();
985   tail_append(new_penalty(cur_val));
986
987   if (mode == vmode)
988     build_page();
989 }
990 /* only called from tex8.c */
991 /* sec 1105 */
992 void delete_last (void)
993 {
994   halfword p, q;
995   quarterword m;
996
997   if ((mode == vmode) && (tail == head))
998   {
999     if ((cur_chr != glue_node) || (last_glue != empty_flag))
1000     {
1001       you_cant();
1002       help2("Sorry...I usually can't take things from the current page.",
1003           "Try `I\\vskip-\\lastskip' instead.");
1004
1005       if (cur_chr == kern_node)
1006         help_line[0] = "Try `I\\kern-\\last_kern' instead.";
1007       else if (cur_chr != glue_node)
1008         help_line[0] = "Perhaps you can make the output routine do it.";
1009       error();
1010     }
1011   }
1012   else
1013   {
1014     if (!(tail >= hi_mem_min))
1015       if (type(tail) == cur_chr)
1016       {
1017         q = head;
1018
1019         do
1020           {
1021             p = q;
1022
1023             if (!(q >= hi_mem_min))
1024               if (type(q) == disc_node)
1025               {
1026                 for (m = 1; m <= replace_count(q); m++)
1027                   p = link(p);
1028
1029                 if (p == tail)
1030                   return;
1031               }
1032             q = link(p);
1033           }
1034         while (!(q == tail));
1035         link(p) = 0;
1036         flush_node_list(tail);
1037         tail = p;
1038       }
1039   }
1040 }
1041 /* only called from tex8.c */
1042 /* procedure unpackage; l.21256 */
1043 /* sec 1110 */
1044 void unpackage (void)
1045 {
1046   halfword p;
1047   char c;
1048
1049   c = cur_chr;
1050   scan_eight_bit_int();
1051   p = box(cur_val);
1052
1053   if (p == 0)
1054     return; 
1055   if ((abs(mode) == mmode) || ((abs(mode) == vmode) && (type(p) != vlist_node)) ||
1056     ((abs(mode) == hmode) && (type(p) != hlist_node)))
1057   {
1058     print_err("Incompatible list can't be unboxed");
1059     help3("Sorry, Pandora. (You sneaky devil.)",
1060         "I refuse to unbox an \\hbox in vertical mode or vice versa.",
1061         "And I can't open any boxes in math mode.");
1062     error();
1063     return;
1064   }
1065
1066   if (c == copy_code)
1067     link(tail) = copy_node_list(list_ptr(p));
1068   else
1069   {
1070     link(tail) = list_ptr(p);
1071     box(cur_val) = 0;
1072     free_node(p, box_node_size);
1073   }
1074
1075   while (link(tail) != 0)
1076     tail = link(tail);
1077 }
1078 /* sec 1113 */
1079 void append_italic_correction (void)
1080 {
1081   halfword p;
1082   internal_font_number f;
1083
1084   if (tail != head)
1085   {
1086     if ((tail >= hi_mem_min))
1087       p = tail;
1088     else if (type(tail) == ligature_node)
1089       p = tail + 1;
1090     else
1091       return;
1092     f = font(p);
1093     tail_append(new_kern(font_info[italic_base[f] + (font_info[char_base[f] + mem[p].hh.b1].qqqq.b2) / 4].cint));
1094     subtype(tail) = explicit;
1095   }
1096 }
1097 /* sec 1117 */
1098 void append_discretionary (void)
1099 {
1100   integer c;
1101
1102   tail_append(new_disc());
1103
1104   if (cur_chr == 1)
1105   {
1106     c = hyphen_char[cur_font];
1107     if (c >= 0)
1108       if (c < 256)
1109         pre_break(tail) = new_character(cur_font, c);
1110   }
1111   else
1112   {
1113     incr(save_ptr);
1114     save_stack[save_ptr - 1].cint = 0;
1115     new_save_level(disc_group);
1116     scan_left_brace();
1117     push_nest();
1118     mode = -102;
1119     space_factor = 1000;
1120   }
1121 }
1122 /* only called form tex8.c */
1123 /* sec 1119 */
1124 void build_discretionary (void)
1125 {
1126   halfword p, q;
1127   integer n;
1128
1129   unsave();
1130   q = head;
1131   p = mem[q].hh.v.RH;
1132   n = 0;
1133
1134   while (p != 0)
1135   {
1136     if (!(p >= hi_mem_min))
1137       if (mem[p].hh.b0 > 2)
1138         if (mem[p].hh.b0 != 11)
1139           if (mem[p].hh.b0 != 6)
1140           {
1141             print_err("Improper discretionary list");
1142             help1("Discretionary lists must contain only boxes and kerns.");
1143             error();
1144             begin_diagnostic();
1145             print_nl("The following discretionary sublist has been deleted:");
1146             show_box(p);
1147             end_diagnostic(true);
1148             flush_node_list(p);
1149             mem[q].hh.v.RH = 0;
1150             goto lab30;
1151           }
1152     q = p;
1153     p = mem[q].hh.v.RH;
1154     incr(n);
1155   }
1156 lab30:
1157   ;
1158   p = mem[head].hh.v.RH;
1159   pop_nest();
1160
1161   switch (save_stack[save_ptr - 1].cint)
1162   {
1163     case 0:
1164       mem[tail + 1].hh.v.LH = p;
1165       break;
1166     case 1:
1167       mem[tail + 1].hh.v.RH = p;
1168       break;
1169     case 2:
1170       {
1171         if ((n > 0) && (abs(mode)== 203))
1172         {
1173           print_err("Illegal math ");
1174           print_esc("discretionary");
1175           help2("Sorry: The third part of a discretionary break must be",
1176               "empty, in math formulas. I had to delete your third part.");
1177           flush_node_list(p);
1178           n = 0;
1179           error();
1180         }
1181         else
1182           mem[tail].hh.v.RH = p;
1183 /* if n <= max_quarterword then replace_count(tail) <- n; p.1120 */
1184 /*      if (n <= 255) */       /* 94/Apr/4 ? */
1185         if (n <= max_quarterword)     /* 96/Oct/12 ??? */
1186           mem[tail].hh.b1 = n;
1187         else
1188         {
1189           print_err("Discretionary list is too long");
1190           help2("Wow---I never thought anybody would tweak me here.",
1191               "You can't seriously need such a huge discretionary list?");
1192           error();
1193         }
1194         if (n > 0)
1195           tail = q;
1196         decr(save_ptr);
1197         return;
1198       }
1199       break;
1200   }
1201   incr(save_stack[save_ptr - 1].cint);
1202   new_save_level(10);
1203   scan_left_brace();
1204   push_nest();
1205   mode = -102;
1206   space_factor = 1000;
1207 }
1208 /* called only from tex8.c */
1209 /* sec 1123 */
1210 void make_accent (void)
1211 {
1212   real s, t;
1213   halfword p, q, r;
1214   internal_font_number f;
1215   scaled a, h, x, w, delta;
1216   ffourquarters i;
1217
1218   scan_char_num();
1219   f = cur_font;
1220   p = new_character(f, cur_val);
1221
1222   if (p != 0)
1223   {
1224     x = x_height(f);
1225     s = slant(f) / ((double) 65536.0);
1226     a = char_width(f, char_info(f, character(p)));
1227     do_assignments();
1228     q = 0;
1229     f = cur_font;
1230
1231     if ((cur_cmd == letter) || (cur_cmd == other_char) || (cur_cmd == char_given))
1232       q = new_character(f, cur_chr);
1233     else if (cur_cmd == char_num)
1234     {
1235       scan_char_num();
1236       q = new_character(f, cur_val);
1237     }
1238     else
1239       back_input();
1240
1241     if (q != 0)
1242     {
1243       t = slant(f) / ((double) 65536.0);
1244       i = char_info(f, character(q));
1245       w = char_width(f, i);
1246       h = char_height(f, height_depth(i));
1247
1248       if (h != x)
1249       {
1250         p = hpack(p, 0, 1);
1251         shift_amount(p) = x - h;
1252       }
1253       delta = round((w - a) / ((double) 2.0)+ h * t - x * s);
1254       r = new_kern(delta);
1255       subtype(r) = acc_kern;
1256       link(tail) = r;
1257       link(r) = p;
1258       tail = new_kern(- (integer) a - delta);
1259       subtype(tail) = acc_kern;
1260       link(p) = tail;
1261       p = q;
1262     }
1263     link(tail) = p;
1264     tail = p;
1265     space_factor = 1000;
1266   }
1267 }
1268 /* sec 1127 */
1269 void align_error (void)
1270 {
1271   if (abs(align_state) > 2)
1272   {
1273     print_err("Misplaced ");
1274     print_cmd_chr(cur_cmd, cur_chr);
1275     if (cur_tok == 1062)
1276     {
1277       help6("I can't figure out why you would want to use a tab mark",
1278           "here. If you just want an ampersand, the remedy is",
1279           "simple: Just type `I\\&' now. But if some right brace",
1280           "up above has ended a previous alignment prematurely,",
1281           "you're probably due for more error messages, and you",
1282           "might try typing `S' now just to see what is salvageable.");
1283     }
1284     else
1285     {
1286       help5("I can't figure out why you would want to use a tab mark",
1287           "or \\cr or \\span just now. If something like a right brace",
1288           "up above has ended a previous alignment prematurely,",
1289           "you're probably due for more error messages, and you",
1290           "might try typing `S' now just to see what is salvageable.");
1291     }
1292     error();
1293   }
1294   else
1295   {
1296     back_input();
1297
1298     if (align_state < 0)
1299     {
1300       print_err("Missing { inserted");
1301       incr(align_state);
1302       cur_tok = 379;    /* belowdisplayshortskip ? */
1303     }
1304     else
1305     {
1306       print_err("Missing } inserted");
1307       decr(align_state);
1308       cur_tok = 637;
1309     }
1310     help3("I've put in what seems to be necessary to fix",
1311         "the current column of the current alignment.",
1312         "Try to go on, since this might almost work.");
1313     ins_error();
1314   }
1315 }
1316 /* sec 1129 */
1317 void noalign_error (void)
1318 {
1319   print_err("Misplaced ");
1320   print_esc("noalign");
1321   help2("I expect to see \\noalign only after the \\cr of",
1322       "an alignment. Proceed, and I'll ignore this case.");
1323   error();
1324 }
1325 /* only called from tex8.c */
1326 /* sec 1129 */
1327 void omit_error (void)
1328 {
1329   print_err("Misplaced ");
1330   print_esc("omit");
1331   help2("I expect to see \\omit only after tab marks or the \\cr of",
1332       "an alignment. Proceed, and I'll ignore this case.");
1333   error();
1334 }
1335 /* sec 1131 */
1336 void do_endv (void)
1337 {
1338   if (cur_group == 6)
1339   {
1340     end_graf();
1341
1342     if (fin_col ())
1343       fin_row();
1344   }
1345   else
1346     off_save();
1347 }
1348 /* only called form tex8.c */
1349 /* sec 1135 */
1350 void cs_error (void)
1351 {
1352   print_err("Extra ");
1353   print_esc("endcsname");
1354   help1("I'm ignoring this, since I wasn't doing a \\csname."); 
1355   error();
1356 }
1357 /* sec 1136 */
1358 void push_math_(group_code c)
1359 {
1360   push_nest();
1361   mode = -203;
1362   cur_list.aux_field.cint = 0;
1363   new_save_level(c);
1364 }
1365 /* sec 1138 */
1366 void init_math (void)
1367 {
1368   scaled w;
1369   scaled l;
1370   scaled s;
1371   halfword p;
1372   halfword q;
1373   internal_font_number f;
1374   integer n;
1375   scaled v;
1376   scaled d;
1377
1378   get_token();
1379
1380   if ((cur_cmd == 3) && (mode > 0))
1381   {
1382     if (head == tail)
1383     {
1384       pop_nest();
1385       w = -1073741823L; /* - (2^30 - 1) */
1386     }
1387     else
1388     {
1389       line_break(display_widow_penalty);
1390       v = mem[just_box + 4].cint + 2 * font_info[6 + param_base[eqtb[(hash_size + 1834)].hh.v.RH]].cint;
1391       w = -1073741823L;  /* - (2^30 - 1) */
1392       p = mem[just_box + 5].hh.v.RH;
1393       while (p != 0)
1394       {
1395 lab21:
1396         if ((p >= hi_mem_min))
1397         {
1398           f = mem[p].hh.b0;
1399           d = font_info[width_base[f] + font_info[char_base[f] + mem[p].hh.b1].qqqq.b0].cint;
1400           goto lab40;
1401         }
1402         switch (mem[p].hh.b0)
1403         {
1404           case 0:
1405           case 1:
1406           case 2:
1407             {
1408               d = mem[p + 1].cint;
1409               goto lab40;
1410             }
1411             break;
1412           case 6:
1413             {
1414               mem[lig_trick]= mem[p + 1];
1415               mem[lig_trick].hh.v.RH = mem[p].hh.v.RH;
1416               p = lig_trick;
1417               goto lab21;
1418             }
1419             break;
1420           case 11:
1421           case 9:
1422             d = mem[p + 1].cint;
1423             break;
1424           case 10:
1425             {
1426               q = mem[p + 1].hh.v.LH;
1427               d = mem[q + 1].cint;
1428               if (mem[just_box + 5].hh.b0 == 1)
1429               {
1430                 if ((mem[just_box + 5].hh.b1 == mem[q].hh.b0) && (mem[q + 2].cint != 0))
1431                   v = 1073741823L;  /* - (2^30 - 1) */
1432               }
1433               else if (mem[just_box + 5].hh.b0 == 2)
1434               {
1435                 if ((mem[just_box + 5].hh.b1 == mem[q].hh.b1) && (mem[q + 3].cint != 0))
1436                   v = 1073741823L;  /* - (2^30 - 1) */
1437               }
1438               if (mem[p].hh.b1 >= 100)
1439                 goto lab40;
1440             }
1441             break;
1442           case 8:
1443             d = 0;
1444             break;
1445           default:
1446             d = 0;
1447             break;
1448         }
1449         if (v < 1073741823L) /* - (2^30 - 1) */
1450           v = v + d;
1451         goto lab45;
1452 lab40:
1453         if (v < 1073741823L) /* - (2^30 - 1) */
1454         {
1455           v = v + d;
1456           w = v;
1457         }
1458         else
1459         {
1460           w = 1073741823L;  /* - (2^30 - 1) */
1461           goto lab30;
1462         }
1463 lab45:
1464         p = mem[p].hh.v.RH;
1465       }
1466 lab30:
1467       ;
1468     }
1469     if (par_shape_ptr == 0)
1470       if ((hang_indent != 0) && (((hang_after >= 0) && (prev_graf + 2 > hang_after)) || (prev_graf + 1 < - (integer) hang_after)))
1471       {
1472         l = hsize - abs(hang_indent);
1473         if (hang_indent > 0)
1474           s = hang_indent;
1475         else
1476           s = 0;
1477       }
1478       else
1479       {
1480         l = hsize;
1481         s = 0;
1482       }
1483     else
1484     {
1485       n = mem[par_shape_ptr].hh.v.LH;
1486       if (prev_graf + 2 >= n)
1487         p = par_shape_ptr + 2 * n;
1488       else
1489         p = par_shape_ptr + 2 *(prev_graf + 2);
1490       s = mem[p - 1].cint;
1491       l = mem[p].cint;
1492     }
1493     push_math(15);
1494     mode = 203;
1495     eq_word_define((hash_size + 3207), -1);
1496     eq_word_define((hash_size + 3743), w);
1497     eq_word_define((hash_size + 3744), l);
1498     eq_word_define((hash_size + 3745), s);
1499
1500     if (every_display != 0)/* everydisplay */
1501       begin_token_list(every_display, 9);
1502
1503     if (nest_ptr == 1)
1504     {
1505       build_page();
1506     }
1507   }
1508   else
1509   {
1510     back_input();
1511     {
1512       push_math(15);
1513       eq_word_define((hash_size + 3207), -1);
1514       if (every_math != 0)/* everymath */
1515         begin_token_list(every_math, 8);
1516     }
1517   }
1518 }
1519 /* sec 1142 */
1520 void start_eq_no (void)
1521 {
1522   save_stack[save_ptr + 0].cint = cur_chr;
1523   incr(save_ptr);
1524   {
1525     push_math(math_shift_group);
1526     eq_word_define(int_base + cur_fam_code, -1);
1527
1528     if (every_math != 0)
1529       begin_token_list(every_math, every_math_text);
1530   }
1531 }
1532 /* sec 1151 */
1533 void scan_math_(halfword p)
1534 {
1535   integer c;
1536
1537 lab20:
1538   do
1539     {
1540       get_x_token();
1541     }
1542   while(!((cur_cmd != spacer) && (cur_cmd != relax)));
1543
1544 lab21:
1545   switch (cur_cmd)
1546   {
1547     case letter:
1548     case other_char:
1549     case char_given:
1550       {
1551         c = math_code(cur_chr);
1552
1553         if (c == 32768L)
1554         {
1555           {
1556             cur_cs = cur_chr + active_base;
1557             cur_cmd = eq_type(cur_cs);
1558             cur_chr = equiv(cur_cs);
1559             x_token();
1560             back_input();
1561           }
1562           goto lab20;
1563         }
1564       }
1565       break;
1566     case char_num:
1567       {
1568         scan_char_num();
1569         cur_chr = cur_val;
1570         cur_cmd = char_given;
1571         goto lab21;
1572       }
1573       break;
1574     case math_char_num:
1575       {
1576         scan_fifteen_bit_int();
1577         c = cur_val;
1578       }
1579       break;
1580     case math_given:
1581       c = cur_chr;
1582       break;
1583     case delim_num:
1584       {
1585         scan_twenty_seven_bit_int();
1586         c = cur_val / 4096;
1587       }
1588       break;
1589     default:
1590       {
1591         back_input();
1592         scan_left_brace();
1593         save_stack[save_ptr + 0].cint = p;
1594         incr(save_ptr);
1595         push_math(math_group);
1596         return;
1597       }
1598       break;
1599   }
1600   math_type(p) = math_char;
1601   character(p) = c % 256;
1602
1603   if ((c >= var_code) && ((cur_fam >= 0) && (cur_fam < 16)))
1604     fam(p) = cur_fam;
1605   else
1606     fam(p) = (c / 256) % 16;
1607 }
1608 /* sec 1155 */
1609 void set_math_char_(integer c)
1610 {
1611   halfword p;
1612
1613   if (c >= 32768L)
1614   {
1615     cur_cs = cur_chr + active_base;
1616     cur_cmd = eq_type(cur_cs);
1617     cur_chr = equiv(cur_cs);
1618     x_token();
1619     back_input();
1620   }
1621   else
1622   {
1623     p = new_noad();
1624     math_type(nucleus(p)) = math_char;
1625     character(nucleus(p)) = c % 256;
1626     fam(nucleus(p)) = (c / 256) % 16;
1627
1628     if (c >= var_code)
1629     {
1630       if (((cur_fam >= 0) && (cur_fam < 16)))
1631         fam(nucleus(p)) = cur_fam;
1632
1633       type(p) = ord_noad;
1634     }
1635     else
1636       type(p) = ord_noad + (c / 4096);
1637
1638     link(tail) = p;
1639     tail = p;
1640   }
1641 }
1642 /* sec 1159 */
1643 void math_limit_switch (void)
1644 {
1645   if (head != tail)
1646     if (mem[tail].hh.b0 == op_noad)
1647     {
1648       subtype(tail) = cur_chr;
1649       return;
1650     }
1651
1652   print_err("Limit controls must follow a math operator");
1653   help1("I'm ignoring this misplaced \\limits or \\nolimits command.");
1654   error();
1655 }
1656 /* sec 1160 */
1657 void scan_delimiter_(halfword p, bool r)
1658 {
1659    if (r)
1660    {
1661      scan_twenty_seven_bit_int();
1662    }
1663    else
1664    {
1665      do
1666       {
1667         get_x_token();
1668       }
1669      while (!((cur_cmd != spacer) && (cur_cmd != relax)));
1670
1671      switch (cur_cmd)
1672      {
1673        case letter:
1674        case other_char:
1675          cur_val = del_code(cur_chr);
1676          break;
1677        case delim_num:
1678          scan_twenty_seven_bit_int();
1679          break;
1680        default:
1681          cur_val = -1;
1682          break;
1683      }
1684    }
1685
1686    if (cur_val < 0)
1687    {
1688      print_err("Missing delimiter (. inserted)");
1689      help6("I was expecting to see something like `(' or `\\{' or",
1690          "`\\}' here. If you typed, e.g., `{' instead of `\\{', you",
1691          "should probably delete the `{' by typing `1' now, so that",
1692          "braces don't get unbalanced. Otherwise just proceed.",
1693          "Acceptable delimiters are characters whose \\delcode is",
1694          "nonnegative, or you can use `\\delimiter <delimiter code>'.");
1695      back_error();
1696      cur_val = 0;
1697    }
1698
1699    small_fam(p) = (cur_val / 1048576L) % 16;
1700    small_char(p) = (cur_val / 4096) % 256;
1701    large_fam(p) = (cur_val / 256) % 16;
1702    large_char(p) = cur_val % 256;
1703 }
1704 /* sec 1163 */
1705 void math_radical (void)
1706 {
1707   tail_append(get_node(radical_noad_size));
1708   type(tail) = radical_noad;
1709   subtype(tail) = normal;
1710   mem[nucleus(tail)].hh = empty_field;
1711   mem[subscr(tail)].hh = empty_field;
1712   mem[supscr(tail)].hh = empty_field;
1713   scan_delimiter(left_delimiter(tail), true);
1714   scan_math(nucleus(tail));
1715 }
1716 /* sec 1165 */
1717 void math_ac (void)
1718 {
1719   if (cur_cmd == accent)
1720   {
1721     print_err("Please use ");
1722     print_esc("mathaccent");
1723     print_string(" for accents in math mode");
1724     help2("I'm changing \\accent to \\mathaccent here; wish me luck.",
1725       "(Accents are not the same in formulas as they are in text.)");
1726     error();
1727   }
1728
1729   tail_append(get_node(5));
1730   type(tail) = accent_noad;
1731   subtype(tail) = normal;
1732   mem[nucleus(tail)].hh = empty_field;
1733   mem[subscr(tail)].hh = empty_field;
1734   mem[supscr(tail)].hh = empty_field;
1735   math_type(accent_chr(tail)) = math_char;
1736   scan_fifteen_bit_int();
1737   character(accent_chr(tail)) = cur_val % 256;
1738
1739   if ((cur_val >= var_code) && ((cur_fam >= 0) && (cur_fam < 16)))
1740     fam(accent_chr(tail)) = cur_fam;
1741   else
1742     fam(accent_chr(tail)) = (cur_val / 256) % 16;
1743
1744   scan_math(nucleus(tail));
1745 }
1746 /* sec 1172 */
1747 void append_choices (void)
1748 {
1749   tail_append(new_choice());
1750   incr(save_ptr);
1751   save_stack[save_ptr - 1].cint = 0;
1752   push_math(math_choice_group);
1753   scan_left_brace();
1754 }
1755 /* sec 1184 */
1756 halfword fin_mlist_(halfword p)
1757 {
1758   register halfword Result;
1759   halfword q;
1760
1761   if (incompleat_noad != 0)
1762   {
1763     math_type(denominator(incompleat_noad)) = sub_mlist;
1764     info(denominator(incompleat_noad)) = link(head);
1765
1766     if (p == 0)
1767       q = incompleat_noad;
1768     else
1769     {
1770       q = info(numerator(incompleat_noad));
1771
1772       if (type(q) != left_noad)
1773       {
1774         confusion("right");
1775         return 0;       // abort_flag set
1776       }
1777
1778       info(numerator(incompleat_noad)) = link(q);
1779       link(q) = incompleat_noad;
1780       link(incompleat_noad) = p;
1781     }
1782   }
1783   else
1784   {
1785     link(tail) = p;
1786     q = link(head);
1787   }
1788   pop_nest();
1789   Result = q;
1790   return Result;
1791 }
1792 /* sec 1174 */
1793 void build_choices (void)
1794 {
1795   halfword p;
1796
1797   unsave();
1798   p = fin_mlist(0);
1799
1800   switch (save_stack[save_ptr - 1].cint)
1801   {
1802     case 0:
1803       display_mlist(tail) = p;
1804       break;
1805     case 1:
1806       text_mlist(tail) = p;
1807       break;
1808     case 2:
1809       script_mlist(tail) = p;
1810       break;
1811     case 3:
1812       {
1813         script_script_mlist(tail) = p;
1814         decr(save_ptr);
1815         return;
1816       }
1817       break;
1818   }
1819   incr(save_stack[save_ptr - 1].cint);
1820   push_math(math_choice_group);
1821   scan_left_brace();
1822 }
1823 /* sec 1176 */
1824 void sub_sup (void)
1825 {
1826 /*  small_number t; */
1827   int t;              /* 95/Jan/7 */
1828   halfword p;
1829
1830   t = 0;
1831   p = 0;
1832
1833   if (tail != head)
1834     if ((mem[tail].hh.b0 >= 16) && (mem[tail].hh.b0 < 30))
1835     {
1836       p = supscr(tail) + cur_cmd - sup_mark;
1837       t = math_type(p);
1838     }
1839
1840   if ((p == 0) || (t != 0))
1841   {
1842     tail_append(new_noad());
1843     p = supscr(tail) + cur_cmd - sup_mark;
1844
1845     if (t != 0)
1846     {
1847       if (cur_cmd == sup_mark)
1848       {
1849         print_err("Double superscript");
1850         help1("I treat `x^1^2' essentially like `x^1{}^2'.");
1851       }
1852       else
1853       {
1854         print_err("Double subscript");
1855         help1("I treat `x_1_2' essentially like `x_1{}_2'.");
1856       }
1857       error();
1858     }
1859   }
1860   scan_math(p);
1861 }
1862 /* used to continue here with math_fraction etc in tex7.c */
1863 /*****************************************************************************/
1864 /* moved down here to avoid pragma optimize questions 96/Sep/12 */
1865 /* sec 1086 */
1866 void package_(small_number c)
1867 {
1868   scaled h;
1869   halfword p;
1870   scaled d;
1871
1872   d = box_max_depth;
1873   unsave();
1874   save_ptr = save_ptr - 3;
1875
1876   if (mode == -102)
1877     cur_box = hpack(link(head), save_stack[save_ptr + 2].cint, save_stack[save_ptr + 1].cint);
1878   else
1879   {
1880     cur_box = vpackage(link(head), save_stack[save_ptr + 2].cint, save_stack[save_ptr + 1].cint, d);
1881
1882     if (c == vtop_code)
1883     {
1884       h = 0;
1885       p = list_ptr(cur_box);
1886
1887       if (p != 0)
1888         if (type(p) <= rule_node)
1889           h = height(p);
1890
1891       depth(cur_box) = depth(cur_box) - h + height(cur_box);
1892       height(cur_box) = h;
1893     }
1894   }
1895   pop_nest();
1896   box_end(save_stack[save_ptr + 0].cint);
1897 }
1898 #pragma optimize ("", on)           /* 96/Sep/12 */