OSDN Git Service

pause_for_instructions().
[putex/putex.git] / src / texsourc / tex6.c
1 /* Copyright 2014 Clerk Ma
2
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License as published by
5    the Free Software Foundation; either version 2 of the License, or
6    (at your option) any later version.
7
8    This program is distributed in the hope that it will be useful, but
9    WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11    General Public License for more details.
12
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16    02110-1301 USA.  */
17
18 #define EXTERN extern
19
20 #include "texd.h"
21
22 /* sec 0785 */
23 void align_peek (void)
24 {
25 lab20:
26   align_state = 1000000L;
27
28   do
29     {
30       get_x_token();
31     }
32   while (!(cur_cmd != spacer));
33
34   if (cur_cmd == no_align)
35   {
36     scan_left_brace();
37
38     new_save_level(no_align_group);
39
40     if (mode == -1)
41       normal_paragraph();
42   }
43   else if (cur_cmd == right_brace)
44   {
45     fin_align();
46   }
47   else if ((cur_cmd == car_ret) && (cur_chr == cr_cr_code))
48     goto lab20;
49   else
50   {
51     init_row();
52     init_col();
53   }
54 }
55 /* sec 0826 */
56 halfword finite_shrink_(halfword p)
57 {
58   halfword q;
59
60   if (no_shrink_error_yet)
61   {
62     no_shrink_error_yet = false;
63     print_err("Infinite glue shrinkage found in a paragraph");
64     help5("The paragraph just ended includes some glue that has",
65         "infinite shrinkability, e.g., `\\hskip 0pt minus 1fil'.",
66         "Such glue doesn't belong there---it allows a paragraph",
67         "of any length to fit on one line. But it's safe to proceed,",
68         "since the offensive shrinkability has been made finite.");
69     error();
70   }
71
72   q = new_spec(p);
73   shrink_order(q) = normal;
74   delete_glue_ref(p);
75
76   return q;
77 }
78 /* sec 0829 */
79 void try_break_ (integer pi, small_number break_type)
80 {
81   halfword r;
82   halfword prev_r;
83   halfword old_l;
84   boolean no_break_yet;
85   halfword prev_prev_r;
86   halfword s;
87   halfword q;
88   halfword v;
89   integer t;
90   internal_font_number f;
91   halfword l;
92   boolean node_r_stays_active;
93   scaled line_width;
94   char fit_class;
95   halfword b;
96   integer d;
97   boolean artificial_demerits;
98   halfword save_link;
99   scaled shortfall;
100
101   if (abs(pi)>= inf_penalty)
102     if (pi > 0)
103       goto lab10;
104     else
105       pi = eject_penalty;
106
107   no_break_yet = true;
108   prev_r = active;
109   old_l = 0;
110   do_all_six(copy_to_cur_active);
111
112   while (true)
113   {
114 lab22:
115     r = link(prev_r);
116
117     if (type(r) == delta_node)
118     {
119       do_all_six(update_width);
120       prev_prev_r = prev_r;
121       prev_r = r;
122       goto lab22;
123     }
124
125     {
126       l = line_number(r);
127
128       if (l > old_l)
129       {
130         if ((minimum_demerits < awful_bad) && ((old_l != easyline) || (r == active)))
131         {
132           if (no_break_yet)
133           {
134             no_break_yet = false;
135             do_all_six(set_break_width_to_background);
136             s = cur_p;
137
138             if (break_type > unhyphenated)
139               if (cur_p != 0)
140               {
141                 t = replace_count(cur_p);
142                 v = cur_p;
143                 s = post_break(cur_p);
144
145                 while (t > 0)
146                 {
147                   decr(t);
148                   v = link(v);
149
150                   if (is_char_node(v))
151                   {
152                     f = font(v);
153                     break_width[1] = break_width[1] - char_width(f, char_info(f, character(v)));
154                   }
155                   else switch (type(v))
156                   {
157                     case ligature_node:
158                       {
159                         f = font(lig_char(v));
160                         break_width[1] = break_width[1] - char_width(f, char_info(f, character(lig_char(v))));
161                       }
162                       break;
163
164                     case hlist_node:
165                     case vlist_node:
166                     case rule_node:
167                     case kern_node:
168                       break_width[1] = break_width[1] - width(v);
169                       break;
170
171                     default:
172                       {
173                         confusion("disc1");
174                         return;
175                       }
176                       break;
177                   }
178                 }
179
180                 while (s != 0)
181                 {
182                   if (is_char_node(s))
183                   {
184                     f = font(s);
185                     break_width[1] = break_width[1] + char_width(f, char_info(f, character(s)));
186                   }
187                   else switch(type(s))
188                   {
189                     case ligature_node:
190                       {
191                         f = font(lig_char(s));
192                         break_width[1] = break_width[1] + char_width(f, char_info(f, character(lig_char(s))));
193                       }
194                       break;
195
196                     case hlist_node:
197                     case vlist_node:
198                     case rule_node:
199                     case kern_node:
200                       break_width[1] = break_width[1] + width(s);
201                       break;
202
203                     default:
204                       {
205                         confusion("disc2");
206                         return;       // abort_flag set
207                       }
208                       break;
209                   }
210
211                   s = link(s);
212                 }
213
214                 break_width[1] = break_width[1] + disc_width;
215
216                 if (post_break(cur_p) == 0)
217                   s = link(v);
218               }
219
220               while (s != 0)
221               {
222                 if (is_char_node(s))
223                   goto lab30;
224
225                 switch (type(s))
226                 {
227                   case glue_node:
228                     {
229                       v = glue_ptr(s);
230                       break_width[1] = break_width[1] - width(v);
231                       break_width[2 + stretch_order(v)] = break_width[2 + stretch_order(v)] - stretch(v);
232                       break_width[6] = break_width[6] - shrink(v);
233                     }
234                     break;
235
236                   case penalty_node:
237                     ;
238                     break;
239
240                   case math_node:
241                     break_width[1] = break_width[1] - width(s);
242                     break;
243
244                   case kern_node:
245                     if (subtype(s) != explicit)
246                       goto lab30;
247                     else
248                       break_width[1] = break_width[1] - width(s);
249                     break;
250
251                   default:
252                     goto lab30;
253                     break;
254                 }
255
256                 s = link(s);
257               }
258 lab30:;
259           }
260
261           if (type(prev_r) == delta_node)
262           {
263             do_all_six(convert_to_break_width);
264           }
265           else if (prev_r == active)
266           {
267             do_all_six(store_break_width);
268           }
269           else
270           {
271             q = get_node(delta_node_size);
272             link(q) = r;
273             type(q) = delta_node;
274             subtype(q) = 0;
275             do_all_six(new_delta_to_break_width);
276             link(prev_r) = q;
277             prev_prev_r = prev_r;
278             prev_r = q;
279           }
280
281           if (abs(adj_demerits) >= awful_bad - minimum_demerits)
282             minimum_demerits = awful_bad - 1;
283           else
284             minimum_demerits = minimum_demerits + abs(adj_demerits);
285
286           for (fit_class = very_loose_fit; fit_class <= tight_fit; fit_class++)
287           {
288             if (minimal_demerits[fit_class] <= minimum_demerits)
289             {
290               q = get_node(passive_node_size);
291               link(q) = passive;
292               passive = q;
293               cur_break(q) = cur_p;
294 #ifdef STAT
295               incr(pass_number);
296               serial(q) = pass_number;
297 #endif
298               prev_break(q) = best_place[fit_class];
299               q = get_node(active_node_size);
300               break_node(q) = passive;
301               line_number(q) = best_pl_line[fit_class] + 1;
302               fitness(q) = fit_class;
303               type(q) = break_type;
304               total_demerits(q) = minimal_demerits[fit_class];
305               link(q) = r;
306               link(prev_r) = q;
307               prev_r = q;
308 #ifdef STAT
309               if (tracing_paragraphs > 0)
310               {
311                 print_nl("@@");
312                 print_int(serial(passive));
313                 print_string(": line ");
314                 print_int(line_number(q) - 1);
315                 print_char('.');
316                 print_int(fit_class);
317
318                 if (break_type == hyphenated)
319                   print_char('-');
320
321                 print_string(" t=");
322                 print_int(total_demerits(q));
323                 print_string(" -> @@");
324
325                 if (prev_break(passive) == 0)
326                   print_char('0');
327                 else
328                   print_int(serial(prev_break(passive)));
329               }
330 #endif /* STAT */
331             }
332
333             minimal_demerits[fit_class] = awful_bad;
334           }
335
336           minimum_demerits = 1073741823L; /* 2^30 - 1 */
337
338           if (r != active)
339           {
340             q = get_node(delta_node_size);
341             link(q) = r;
342             type(q) = delta_node;
343             subtype(q) = 0;
344             do_all_six(new_delta_from_break_width);
345             link(prev_r) = q;
346             prev_prev_r = prev_r;
347             prev_r = q;
348           }
349         }
350
351         if (r == active)
352           goto lab10;
353
354         if (l > easyline)
355         {
356           line_width = second_width;
357           old_l = max_halfword - 1; /*262142L*/ /* 2^18 - 2 ? */
358         }
359         else
360         {
361           old_l = l;
362
363           if (l > last_special_line)
364             line_width = second_width;
365           else if (par_shape_ptr == 0)
366             line_width = first_width;
367           else
368             line_width = mem[par_shape_ptr + 2 * l].cint;
369         }
370       }
371     }
372
373     {
374       artificial_demerits = false;
375       shortfall = line_width - cur_active_width[1];
376
377       if (shortfall > 0)
378         if ((cur_active_width[3] != 0) || (cur_active_width[4] != 0) || (cur_active_width[5] != 0))
379         {
380           b = 0;
381           fit_class = decent_fit;
382         }
383         else
384         {
385           if (shortfall > 7230584L)
386             if (cur_active_width[2] < 1663497L)
387             {
388               b = 10000;
389               fit_class = very_loose_fit;
390               goto lab31;
391             }
392
393           b = badness(shortfall, cur_active_width[2]);
394
395           if (b > 12)
396             if (b > 99)
397               fit_class = very_loose_fit;
398             else
399               fit_class = loose_fit;
400           else
401             fit_class = decent_fit;
402 lab31:;
403         }
404       else
405       {
406         if (- (integer) shortfall > cur_active_width[6])
407           b = inf_bad + 1;
408         else
409           b = badness(- (integer) shortfall, cur_active_width[6]);
410
411         if (b > 12)
412           fit_class = tight_fit;
413         else
414           fit_class = decent_fit;
415       }
416
417       if ((b > inf_bad) || (pi == eject_penalty))
418       {
419         if (final_pass && (minimum_demerits == awful_bad) && (link(r) == active) && (prev_r == active))
420           artificial_demerits = true;
421         else if (b > threshold)
422           goto lab60;
423
424         node_r_stays_active = false;
425       }
426       else
427       {
428         prev_r = r;
429
430         if (b > threshold)
431           goto lab22;
432
433         node_r_stays_active = true;
434       }
435
436       if (artificial_demerits)
437         d = 0;
438       else
439       {
440         d = line_penalty + b;
441
442         if (abs(d) >= 10000)
443           d = 100000000L;
444         else
445           d = d * d;
446
447         if (pi != 0)
448           if (pi > 0)
449             d = d + pi * pi;
450           else if (pi > -10000)
451             d = d - pi * pi;
452
453         if ((break_type == hyphenated) && (type(r) == hyphenated))
454           if (cur_p != 0)
455             d = d + double_hyphen_demerits;
456           else
457             d = d + final_hyphen_demerits;
458
459         if (abs(toint(fit_class)- toint(fitness(r))) > 1)
460           d = d + adj_demerits;
461       }
462
463 #ifdef STAT
464       if (tracing_paragraphs > 0)
465       {
466         if (printed_node != cur_p)
467         {
468           print_nl("");
469
470           if (cur_p == 0)
471             short_display(link(printed_node));
472           else
473           {
474             save_link = link(cur_p);
475             link(cur_p) = 0;
476             print_nl("");
477             short_display(link(printed_node));
478             link(cur_p) = save_link;
479           }
480
481           printed_node = cur_p;
482         }
483
484         print_nl("@");
485
486         if (cur_p == 0)
487           print_esc("par");
488         else if (type(cur_p) != glue_node)
489         {
490           if (type(cur_p) == penalty_node)
491             print_esc("penalty");
492           else if (type(cur_p) == disc_node)
493             print_esc("discretionary");
494           else if (type(cur_p) == kern_node)
495             print_esc("kern");
496           else
497             print_esc("math");
498         }
499
500         print_string(" via @@");
501
502         if (break_node(r) == 0)
503           print_char('0');
504         else
505           print_int(serial(break_node(r)));
506
507         print_string(" b=");
508
509         if (b > inf_bad)
510           print_char('*');
511         else
512           print_int(b);
513
514         print_string(" p=");
515         print_int(pi);
516         print_string(" d=");
517
518         if (artificial_demerits)
519           print_char('*');
520         else
521           print_int(d);
522       }
523 #endif /* STAT */
524
525       d = d + total_demerits(r);
526
527       if (d <= minimal_demerits[fit_class])
528       {
529         minimal_demerits[fit_class] = d;
530         best_place[fit_class] = break_node(r);
531         best_pl_line[fit_class] = l;
532
533         if (d < minimum_demerits)
534           minimum_demerits = d;
535       }
536
537       if (node_r_stays_active)
538         goto lab22;
539 lab60:
540       link(prev_r) = link(r);
541       free_node(r, active_node_size);
542
543       if (prev_r == active)
544       {
545         r = link(active);
546
547         if (type(r) == delta_node)
548         {
549           do_all_six(update_active);
550           do_all_six(copy_to_cur_active);
551           link(active) = link(r);
552           free_node(r, delta_node_size);
553         }
554       }
555       else if (type(prev_r) == delta_node)
556       {
557         r = link(prev_r);
558
559         if (r == active)
560         {
561           do_all_six(downdate_width);
562           link(prev_prev_r) = active;
563           free_node(prev_r, delta_node_size);
564           prev_r = prev_prev_r;
565         }
566         else if (type(r) == delta_node)
567         {
568           do_all_six(update_width);
569           do_all_six(combine_two_deltas);
570           link(prev_r) = link(r);
571           free_node(r, delta_node_size);
572         }
573       }
574     }
575   }
576 lab10:
577   ;
578 #ifdef STAT
579   if (cur_p == printed_node)
580     if (cur_p != 0)
581       if (type(cur_p) == disc_node)
582       {
583         t = replace_count(cur_p);
584
585         while (t > 0)
586         {
587           decr(t);
588           printed_node = link(printed_node);
589         }
590       }
591 #endif /* STAT */
592 }
593 /* end of the old tex5.c here */
594 /* sec 0877 */
595 void post_line_break_(integer final_widow_penalty)
596 {
597   halfword q, r, s;
598   boolean disc_break;
599   boolean post_disc_break;
600   scaled cur_width;
601   scaled cur_indent;
602   quarterword t;
603   integer pen;
604   halfword cur_line;
605
606   q = break_node(best_bet);
607   cur_p = 0;
608
609   do
610     {
611       r = q;
612       q = prev_break(q);
613       next_break(r) = cur_p;
614       cur_p = r;
615     }
616   while (!(q == 0));
617
618   cur_line = prev_graf + 1;
619
620   do
621     {
622       q = cur_break(cur_p);
623       disc_break = false;
624       post_disc_break = false;
625
626       if (q != 0)
627         if (type(q) == glue_node)
628         {
629           delete_glue_ref(glue_ptr(q));
630           glue_ptr(q) = right_skip;
631           subtype(q) = right_skip_code + 1;
632           add_glue_ref(right_skip);
633           goto lab30;
634         }
635         else
636         {
637           if (type(q) == disc_node)
638           {
639             t = replace_count(q);
640
641             if (t == 0)
642               r = link(q);
643             else
644             {
645               r = q;
646
647               while (t > 1)
648               {
649                 r = link(r);
650                 decr(t);
651               }
652
653               s = link(r);
654               r = link(s);
655               link(s) = 0;
656               flush_node_list(link(q));
657               replace_count(q) = 0;
658             }
659
660             if (post_break(q) != 0)
661             {
662               s = post_break(q);
663
664               while (link(s) != 0)
665                 s = link(s);
666
667               link(s) = r;
668               r = post_break(q);
669               post_break(q) = 0;
670               post_disc_break = true;
671             }
672
673             if (pre_break(q) != 0)
674             {
675               s = prev_break(q);
676               link(q) = s;
677
678               while (link(s) != 0)
679                 s = link(s);
680
681               prev_break(q) = 0;
682               q = s;
683             }
684
685             link(q) = r;
686             disc_break = true;
687           }
688           else if ((type(q) == math_node) || (type(q) == kern_node))
689             width(q) = 0;
690         }
691       else
692       {
693         q = temp_head;
694
695         while (link(q) != 0)
696           q = link(q);
697       }
698
699       r = new_param_glue(right_skip_code);
700       link(r) = link(q);
701       link(q) = r;
702       q = r;
703 lab30:
704       r = link(q);
705       link(q) = 0;
706       q = link(temp_head);
707       link(temp_head) = r;
708
709       if (left_skip != 0)
710       {
711         r = new_param_glue(left_skip_code);
712         link(r) = q;
713         q = r;
714       }
715
716       if (cur_line > last_special_line)
717       {
718         cur_width = second_width;
719         cur_indent = second_indent;
720       }
721       else if (par_shape_ptr == 0)
722       {
723         cur_width = first_width;
724         cur_indent = first_indent;
725       }
726       else
727       {
728         cur_width = mem[par_shape_ptr + 2 * cur_line].cint;
729         cur_indent = mem[par_shape_ptr + 2 * cur_line - 1].cint;
730       }
731
732       adjust_tail = adjust_head;
733       just_box = hpack(q, cur_width, 0);
734       shift_amount(just_box) = cur_indent;
735       append_to_vlist(just_box);
736
737       if (adjust_head != adjust_tail)
738       {
739         link(tail) = link(adjust_head);
740         tail = adjust_tail;
741       }
742
743       adjust_tail = 0;
744
745       if (cur_line + 1 != best_line)
746       {
747         pen = inter_line_penalty;
748
749         if (cur_line == prev_graf + 1)
750           pen = pen + club_penalty;
751
752         if (cur_line + 2 == best_line)
753           pen = pen + final_widow_penalty;
754
755         if (disc_break)
756           pen = pen + broken_penalty;
757
758         if (pen != 0)
759         {
760           r = new_penalty(pen);
761           link(tail) = r;
762           tail = r;
763         }
764       }
765
766       incr(cur_line);
767       cur_p = next_break(cur_p);
768
769       if (cur_p != 0)
770         if (!post_disc_break)
771         {
772           r = temp_head;
773
774           while (true)
775           {
776             q = link(r);
777
778             if (q == cur_break(cur_p))
779               goto lab31;
780
781             if (is_char_node(q))
782               goto lab31;
783
784             if (non_discardable(q))
785               goto lab31;
786
787             if (type(q) == kern_node)
788               if (subtype(q) != 1)
789                 goto lab31;
790
791             r = q;
792           }
793 lab31:
794           if (r != temp_head)
795           {
796             link(r) = 0;
797             flush_node_list(link(temp_head));
798             link(temp_head) = q;
799           }
800         }
801     }
802   while (!(cur_p == 0));
803
804   if ((cur_line != best_line) || (link(temp_head) != 0))
805   {
806     confusion("line breaking");
807     return;       // abort_flag set
808   }
809
810   prev_graf = best_line - 1;
811 }
812 /* sec 0906 */
813 small_number reconstitute_(small_number j, small_number n, halfword bchar, halfword hchar)
814 {
815   halfword p;
816   halfword t;
817   four_quarters q;
818   halfword cur_rh;
819   halfword test_char;
820   scaled w;
821   font_index k;
822
823   hyphen_passed = 0;
824   t = hold_head;
825   w = 0;
826   link(hold_head) = 0;
827   cur_l = hu[j];
828   cur_q = t;
829
830   if (j == 0)
831   {
832     ligature_present = init_lig;
833     p = init_list; 
834
835     if (ligature_present)
836       lft_hit = init_lft; 
837
838     while (p != 0) /* 94/Mar/22 BUG FIX */
839     {
840       append_charnode_to_t(character(p));
841       p = link(p);
842     }
843   }
844   else if (cur_l < 256)
845   {
846     append_charnode_to_t(cur_l);
847   }
848
849   lig_stack = 0;
850   set_cur_r();
851
852 lab22:
853   if (cur_l == non_char)
854   {
855     k = bchar_label[hf];
856
857     if (k == non_address)
858       goto lab30;
859     else
860       q = font_info[k].qqqq;
861   }
862   else
863   {
864     q = char_info(hf, cur_l);
865
866     if (char_tag(q) != lig_tag)
867       goto lab30;
868
869     k = lig_kern_start(hf, q);
870     q = font_info[k].qqqq;
871
872     if (skip_byte(q) > stop_flag)
873     {
874       k = lig_kern_restart(hf, q);
875       q = font_info[k].qqqq;
876     }
877   }
878
879   if (cur_rh < non_char)
880     test_char = cur_rh;
881   else
882     test_char = cur_r;
883
884   while (true)
885   {
886     if (next_char(q) == test_char)
887       if (skip_byte(q) <= 128)
888         if (cur_rh < non_char)
889         {
890           hyphen_passed = j;
891           hchar = non_char;
892           cur_rh = non_char;
893           goto lab22;     /* goto continue; */
894         }
895         else
896         {
897           if (hchar < non_char)
898             if (odd(hyf[j]))
899             {
900               hyphen_passed = j;
901               hchar = non_char;
902             }
903
904           if (op_byte(q) < kern_flag)
905           {
906             if (cur_l == non_char)
907               lft_hit = true;
908
909             if (j == n)
910               if (lig_stack == 0)
911                 rt_hit = true;
912
913             check_interrupt();
914
915             switch (op_byte(q))
916             {
917               case 1:
918               case 5:
919                 {
920                   cur_l = rem_byte(q);
921                   ligature_present = true;
922                 }
923                 break;
924
925               case 2:
926               case 6:
927                 {
928                   cur_r = rem_byte(q);
929
930                   if (lig_stack != 0)
931                     character(lig_stack) = cur_r;
932                   else
933                   {
934                     lig_stack = new_lig_item(cur_r);
935
936                     if (j == n)
937                       bchar = non_char;
938                     else
939                     {
940                       p = get_avail();
941                       list_ptr(lig_stack) = p;
942                       character(p) = hu[j + 1];
943                       font(p) = hf;
944                     }
945                   }
946                 }
947                 break;
948
949               case 3:
950                 {
951                   cur_r = rem_byte(q);
952                   p = lig_stack;
953                   lig_stack = new_lig_item(cur_r);
954                   link(lig_stack) = p;
955                 }
956                 break;
957
958               case 7:
959               case 11:
960                 {
961                   if (ligature_present)
962                   {
963                     p = new_ligature(hf, cur_l, mem[cur_q].hh.rh);
964
965                     if (lft_hit)
966                     {
967                       mem[p].hh.b1 = 2;
968                       lft_hit = false;
969                     }
970
971                     mem[cur_q].hh.rh = p;
972                     t = p;
973                     ligature_present = false;
974                   }
975                   cur_q = t;
976                   cur_l = rem_byte(q);
977                   ligature_present = true;
978                 }
979                 break;
980
981               default:
982                 {
983                   cur_l = rem_byte(q);
984                   ligature_present = true;
985
986                   if (lig_stack != 0)        /* BUG FIX  */
987                   {
988                     if (mem[lig_stack + 1].hh.rh != 0) /* l.17828 ? */
989                     {
990                       mem[t].hh.rh = mem[lig_stack + 1].hh.rh;
991                       t = mem[t].hh.rh;
992                       incr(j);
993                     }
994                     p = lig_stack;
995                     lig_stack = mem[p].hh.rh;
996                     free_node(p, 2);
997                     if (lig_stack == 0)  /* if lig_stack=null ? */
998                     {
999                       if (j < n)
1000                         cur_r = hu[j + 1];
1001                       else
1002                         cur_r = bchar;
1003                       if (odd(hyf[j]))
1004                         cur_rh = hchar;
1005                       else
1006                         cur_rh = 256;
1007                     }
1008                     else
1009                       cur_r = mem[lig_stack].hh.b1;
1010                   }
1011                   else if (j == n)
1012                     goto lab30;
1013                   else
1014                   {
1015                     append_charnode_to_t(cur_r);
1016                     incr(j);
1017                     set_cur_r();
1018                   }
1019                 }
1020                 break;
1021             }
1022
1023             if (op_byte(q) > 4)
1024               if (op_byte(q) != 7)
1025                 goto lab30;
1026
1027             goto lab22;
1028           }
1029
1030           w = char_kern(hf, q);
1031           goto lab30;
1032         }
1033
1034     if (q.b0 >= stop_flag)
1035       if (cur_rh == non_char)
1036         goto lab30;
1037       else
1038       {
1039         cur_rh = non_char;
1040         goto lab22;
1041       }
1042       
1043     k = k + skip_byte(q) + 1;
1044     q = font_info[k].qqqq;
1045   }
1046 lab30:
1047   wrap_lig(rt_hit);
1048
1049   if (w != 0)
1050   {
1051     link(t) = new_kern(w);
1052     t = link(t);
1053     w = 0;
1054   }
1055
1056   if (lig_stack != 0)        /* l.17841 */
1057   {
1058     cur_q = t;
1059     cur_l = character(lig_stack);
1060     ligature_present = true;
1061     pop_lig_stack();
1062     goto lab22;
1063   }
1064
1065   return j;
1066 }
1067 /* sec 0895 */
1068 void hyphenate (void)
1069 {
1070 /*  char i, j, l;  */
1071   char i, j;
1072   int l;              /* 95/Jan/7 */
1073   halfword q, r, s;
1074   halfword bchar;
1075   halfword major_tail, minor_tail;
1076 /*  ASCII_code c;  */
1077   int c;              /* 95/Jan/7 */
1078   char c_loc;
1079 /*  integer r_count; */
1080   int r_count;           /* 95/Jan/7 */
1081   halfword hyf_node;
1082   trie_pointer z;
1083   integer v;
1084   hyph_pointer h;
1085   str_number k;
1086   pool_pointer u;
1087
1088   for (j = 0; j <= hn; j++)
1089     hyf[j] = 0;
1090
1091   h = hc[1];
1092   incr(hn);
1093   hc[hn] = cur_lang;
1094
1095   for (j = 2; j <= hn; j++)
1096     h = (h + h + hc[j]) % hyphen_prime;
1097
1098   while (true)
1099   {
1100     k = hyph_word[h];
1101
1102     if (k == 0)
1103       goto lab45;
1104
1105     if (length(k) < hn)
1106       goto lab45;
1107
1108     if (length(k) == hn)
1109     {
1110       j = 1;
1111       u = str_start[k];
1112
1113       do
1114         {
1115           if (str_pool[u] < hc[j])
1116             goto lab45;
1117
1118           if (str_pool[u] > hc[j])
1119             goto lab30;
1120
1121           incr(j);
1122           incr(u);
1123         }
1124       while (!(j > hn));
1125
1126       s = hyph_list[h];
1127
1128       while (s != 0)
1129       {
1130         hyf[info(s)] = 1;
1131         s = link(s);
1132       }
1133
1134       decr(hn);
1135       goto lab40;
1136     }
1137
1138 lab30:;
1139     if (h > 0)
1140       decr(h);
1141     else
1142       h = hyphen_prime;
1143   }
1144 lab45:
1145   decr(hn);
1146
1147   if (trie_trc[cur_lang + 1] != cur_lang)
1148     return;
1149
1150   hc[0] = 0;
1151   hc[hn + 1] = 0;
1152   hc[hn + 2] = 256;
1153
1154   for (j = 0; j <= hn - rhyf + 1; j++)
1155   {
1156     z = trie_trl[cur_lang + 1] + hc[j];
1157     l = j;
1158
1159     while (hc[l] == trie_trc[z])
1160     {
1161       if (trie_tro[z] != min_trie_op)
1162       {
1163         v = trie_tro[z];
1164
1165         do
1166           {
1167             v = v + op_start[cur_lang];
1168             i = l - hyf_distance[v];
1169
1170             if (hyf_num[v] > hyf[i])
1171               hyf[i]= hyf_num[v];
1172
1173             v = hyf_next[v];
1174           }
1175         while (!(v == min_trie_op));
1176       }
1177
1178       incr(l);
1179       z = trie_trl[z] + hc[l];
1180     }
1181   }
1182 lab40:
1183   for (j = 0; j <= lhyf - 1; j++)
1184     hyf[j] = 0;
1185
1186   for (j = 0; j <= rhyf - 1; j++)
1187     hyf[hn - j]= 0;
1188
1189   for (j = lhyf; j <= hn - rhyf; j++)
1190     if (odd(hyf[j]))
1191       goto lab41;
1192
1193   return;
1194 lab41:;
1195   q = link(hb);
1196   link(hb) = 0;
1197   r = link(ha);
1198   link(ha) = 0;
1199   bchar = hyfbchar;
1200
1201   if (is_char_node(ha))
1202     if (font(ha) != hf)
1203       goto lab42;
1204     else
1205     {
1206       init_list = ha;
1207       init_lig = false;
1208       hu[0] = character(ha);
1209     }
1210   else if (type(ha) == ligature_node)
1211     if (font(lig_char(ha)) != hf)
1212       goto lab42;
1213     else
1214     {
1215       init_list = lig_ptr(ha);
1216       init_lig = true;
1217       init_lft = (subtype(ha) > 1);
1218       hu[0] = character(lig_char(ha));
1219
1220       if (init_list == 0)
1221         if (init_lft)
1222         {
1223           hu[0] = 256;
1224           init_lig = false;
1225         }
1226
1227       free_node(ha, small_node_size);
1228     }
1229   else
1230   {
1231     if (!is_char_node(r))
1232       if (type(r) == ligature_node)
1233         if (subtype(r) > 1)
1234           goto lab42;
1235
1236     j = 1;
1237     s = ha;
1238     init_list = 0;
1239     goto lab50;
1240   }
1241
1242   s = cur_p;
1243
1244   while (link(s) != ha)
1245     s = link(s);
1246
1247   j = 0;
1248   goto lab50;
1249 lab42:
1250   s = ha;
1251   j = 0;
1252   hu[0] = 256;
1253   init_lig = false;
1254   init_list = 0;
1255 lab50:
1256   flush_node_list(r);
1257
1258   do
1259     {
1260       l = j;
1261       j = reconstitute(j, hn, bchar, hyf_char) + 1;
1262
1263       if (hyphen_passed == 0)
1264       {
1265         link(s) = link(hold_head);
1266
1267         while (link(s) != 0) /* l.17903 */
1268           s = link(s);
1269
1270         if (odd(hyf[j - 1]))
1271         {
1272           l = j;
1273           hyphen_passed = j - 1;
1274           link(hold_head) = 0;
1275         }
1276       }
1277
1278       if (hyphen_passed > 0)
1279         do
1280           {
1281             r = get_node(small_node_size);
1282             link(r) = link(hold_head);
1283             type(r) = disc_node;
1284             major_tail = r;
1285             r_count = 0;
1286
1287             while (mem[major_tail].hh.rh != 0)
1288             {
1289               major_tail = link(major_tail);
1290               incr(r_count);
1291             }
1292
1293             i = hyphen_passed;
1294             hyf[i] = 0;
1295             minor_tail = 0;
1296             pre_break(r) = 0;
1297             hyf_node = new_character(hf, hyf_char);
1298
1299             if (hyf_node != 0)
1300             {
1301               incr(i);
1302               c = hu[i];
1303               hu[i] = hyf_char;
1304               free_avail(hyf_node);
1305             }
1306
1307             while (l <= i)
1308             {
1309               l = reconstitute(l, i, font_bchar[hf], non_char) + 1;
1310
1311               if (link(hold_head) != 0) /* BUG FIX ??? */
1312               {
1313                 if (minor_tail == 0)
1314                   pre_break(r) = link(hold_head);
1315                 else
1316                   link(minor_tail) = link(hold_head);
1317
1318                 minor_tail = link(hold_head);
1319
1320                 while (link(minor_tail) != 0)  /* BUG FIX */
1321                   minor_tail = link(minor_tail);
1322               }
1323             }
1324
1325             if (hyf_node != 0) /* if hyf_node<>null then l.17956 */
1326             {
1327               hu[i] = c;
1328               l = i;
1329               decr(i);
1330             }
1331
1332             minor_tail = 0;
1333             post_break(r) = 0;
1334             c_loc = 0;
1335
1336             if (bchar_label[hf] != non_address) /* i.e. 0 --- 96/Jan/15 */
1337             {
1338               decr(l);
1339               c = hu[l];
1340               c_loc = l;
1341               hu[l]= 256;
1342             }
1343
1344             while (l < j)
1345             {
1346               do
1347                 {
1348                   l = reconstitute(l, hn, bchar, 256) + 1;
1349
1350                   if (c_loc > 0)
1351                   {
1352                     hu[c_loc] = c;    /* c may be used ... */
1353                     c_loc = 0;
1354                   }
1355
1356                   if (link(hold_head) != 0)     /* BUG FIX */
1357                   {
1358                     if (minor_tail == 0) /* begin if minor_tail=null then */
1359                       post_break(r) = link(hold_head);
1360                     else
1361                       link(minor_tail) = link(hold_head);
1362
1363                     minor_tail = link(hold_head);
1364
1365                     while (link(minor_tail) != 0)    /* ??? */
1366                       minor_tail = link(minor_tail);
1367                   }
1368                 }
1369               while (!(l >= j));
1370
1371               while (l > j)
1372               {
1373                 j = reconstitute(j, hn, bchar, non_char) + 1;
1374                 link(major_tail) = link(hold_head);
1375
1376                 while (mem[major_tail].hh.rh != 0)
1377                 {
1378                   major_tail = link(major_tail);
1379                   incr(r_count);
1380                 }
1381               }
1382             }
1383
1384             if (r_count > 127)
1385             {
1386               link(s) = link(r);
1387               link(r) = 0;
1388               flush_node_list(r);
1389             }
1390             else
1391             {
1392               link(s) = r;
1393               replace_count(r) = r_count;
1394             }
1395
1396             s = major_tail;
1397             hyphen_passed = j - 1;
1398             link(hold_head) = 0;
1399           }
1400         while (!(! odd(hyf[j - 1])));
1401     }
1402   while (!(j > hn));
1403
1404   link(s) = q;
1405   flush_list(init_list);
1406 }
1407 /* sec 0934 */
1408 void new_hyph_exceptions (void)
1409 {
1410 /*  small_number n;  */ /* in 3.141 */
1411   char n;
1412 /*  small_number j;  */ /* in 3.141 */
1413   char j;
1414   hyph_pointer h;
1415   str_number k;
1416   halfword p;
1417   halfword q;
1418   str_number s, t;
1419   pool_pointer u, v;
1420
1421   scan_left_brace();
1422   set_cur_lang();
1423   n = 0;
1424   p = 0;
1425
1426   while (true)
1427   {
1428     get_x_token();
1429 lab21:
1430     switch (cur_cmd)
1431     {
1432       case letter:
1433       case other_char:
1434       case char_given:
1435         if (cur_chr == '-')
1436         {
1437           if (n < 63)
1438           {
1439             q = get_avail();
1440             link(q) = p;
1441             info(q) = n;
1442             p = q;
1443           }
1444         }
1445         else
1446         {
1447           if (lc_code(cur_chr) == 0)
1448           {
1449             print_err("Not a letter");
1450             help2("Letters in \\hyphenation words must have \\lccode>0.",
1451                 "Proceed; I'll ignore the character I just read.");
1452             error();
1453           }
1454           else if (n < 63)
1455           {
1456             incr(n);
1457             hc[n] = lc_code(cur_chr);
1458           }
1459         }
1460         break;
1461
1462       case char_num:
1463         {
1464           scan_char_num();
1465           cur_chr = cur_val;
1466           cur_cmd = char_given;
1467           goto lab21;
1468         }
1469         break;
1470
1471       case spacer:
1472       case right_brace:
1473         {
1474           if (n > 1)
1475           {
1476             incr(n);
1477             hc[n] = cur_lang;
1478             str_room(n);
1479             h = 0;
1480
1481             for (j = 1; j <= n; j++)
1482             {
1483               h = (h + h + hc[j]) % hyphen_prime;
1484               append_char(hc[j]);
1485             }
1486
1487             s = make_string();
1488
1489             if (hyph_count == hyphen_prime)
1490             {
1491               overflow("exception dictionary", hyphen_prime); /* exception dictionary - NOT DYNAMIC */
1492               return;
1493             }
1494
1495             incr(hyph_count);
1496
1497             while (hyph_word[h] != 0)
1498             {
1499               k = hyph_word[h];
1500
1501               if (length(k) < length(s))
1502                 goto lab40;
1503
1504               if (length(k) > length(s))
1505                 goto lab45;
1506
1507               u = str_start[k];
1508               v = str_start[s];
1509
1510               do
1511                 {
1512                   if (str_pool[u] < str_pool[v])
1513                     goto lab40;
1514
1515                   if (str_pool[u] > str_pool[v])
1516                     goto lab45;
1517
1518                   incr(u);
1519                   incr(v);
1520                 }
1521               while (!(u == str_start[k + 1]));
1522 lab40:
1523               q = hyph_list[h];
1524               hyph_list[h] = p;
1525               p = q;
1526               t = hyph_word[h];
1527               hyph_word[h] = s;
1528               s = t;
1529 lab45:;
1530               if (h > 0)
1531                 decr(h);
1532               else
1533                 h = hyphen_prime;
1534             }
1535
1536             hyph_word[h] = s;
1537             hyph_list[h] = p;
1538           }
1539
1540           if (cur_cmd == right_brace)
1541             return;
1542
1543           n = 0;
1544           p = 0;
1545         }
1546         break;
1547
1548       default:
1549         {
1550           print_err("Improper ");
1551           print_esc("hyphenation");
1552           print_string(" will be flushed");
1553           help2("Hyphenation exceptions must contain only letters",
1554               "and hyphens. But continue; I'll forgive and forget.");
1555           error();
1556         }
1557         break;
1558     } /* end of switch */
1559   }
1560 }
1561 /* sec 0968 */
1562 halfword prune_page_top_(halfword p)
1563 {
1564   halfword prev_p;
1565   halfword q;
1566
1567   prev_p = temp_head;
1568   link(temp_head) = p;
1569
1570   while (p != 0)
1571     switch(type(p))
1572     {
1573       case hlist_node:
1574       case vlist_node:
1575       case rule_node:
1576         {
1577           q = new_skip_param(split_top_skip_code);
1578           link(prev_p) = q;
1579           link(q) = p;
1580
1581           if (width(temp_ptr) > height(p))
1582             width(temp_ptr) = width(temp_ptr) - height(p);
1583           else
1584             width(temp_ptr) = 0;
1585
1586           p = 0;
1587         }
1588         break;
1589
1590       case whatsit_node:
1591       case mark_node:
1592       case ins_node:
1593         {
1594           prev_p = p;
1595           p = link(prev_p);
1596         }
1597         break;
1598
1599       case glue_node:
1600       case kern_node:
1601       case penalty_node:
1602         {
1603           q = p;
1604           p = link(q);
1605           link(q) = 0;
1606           link(prev_p) = p;
1607           flush_node_list(q);
1608         }
1609         break;
1610
1611       default:
1612         {
1613           confusion("pruning");
1614           return 0;       // abort_flag set
1615         }
1616         break;
1617     }
1618
1619   return link(temp_head);
1620 }
1621 /* sec 0970 */
1622 halfword vert_break_(halfword p, scaled h, scaled d)
1623 {
1624   halfword prev_p;
1625   halfword q, r;
1626   integer pi;
1627   integer b;
1628   integer least_cost;
1629   halfword best_place;
1630   scaled prev_dp; 
1631 /*  small_number t;  */
1632   int t;              /* 95/Jan/7 */
1633   prev_p = p;
1634
1635   least_cost = awful_bad;
1636   do_all_six(set_height_zero);
1637   prev_dp = 0;
1638
1639   while (true)
1640   {
1641     if (p == 0)
1642       pi = eject_penalty;
1643     else switch(type(p))
1644     {
1645       case hlist_node:
1646       case vlist_node:
1647       case rule_node:
1648         {
1649           cur_height = cur_height + prev_dp + height(p);
1650           prev_dp = depth(p);
1651           goto lab45;
1652         }
1653         break;
1654
1655       case whatsit_node:
1656         goto lab45;
1657         break;
1658
1659       case glue_node:
1660         if (precedes_break(prev_p))
1661           pi = 0;
1662         else
1663           goto lab90;
1664         break;
1665
1666       case kern_node:
1667         {
1668           if (link(p) == 0)
1669             t = penalty_node;
1670           else
1671             t = type(link(p));
1672
1673           if (t == glue_node)
1674             pi = 0;
1675           else
1676             goto lab90;
1677         }
1678         break;
1679
1680       case penalty_node:
1681         pi = penalty(p);
1682         break;
1683
1684       case mark_node:
1685       case ins_node:
1686         goto lab45;
1687         break;
1688
1689       default:
1690         {
1691           confusion("vertbreak");
1692           return 0;       // abort_flag set
1693         }
1694         break;
1695     }
1696
1697     if (pi < inf_penalty)
1698     {
1699       if (cur_height < h)
1700         if ((active_width[3] != 0) || (active_width[4] != 0) || (active_width[5]!= 0))
1701           b = 0;
1702         else
1703           b = badness(h - cur_height, active_width[2]);
1704       else
1705         if (active_width[1] - h > active_width[6])
1706           b = awful_bad;
1707         else
1708           b = badness(cur_height - h, active_width[6]);
1709
1710       if (b < awful_bad)
1711         if (pi <= eject_penalty)
1712           b = pi;
1713         else
1714           if (b < inf_bad)
1715             b = b + pi;
1716           else
1717             b = deplorable;
1718
1719       if (b <= least_cost)
1720       {
1721         best_place = p;
1722         least_cost = b;
1723         best_height_plus_depth = cur_height + prev_dp;
1724       }
1725
1726       if ((b == awful_bad) || (pi <= eject_penalty))
1727         goto lab30;
1728     }
1729
1730     if ((type(p) < glue_node) || (type(p) > kern_node))
1731       goto lab45;
1732 lab90:
1733     if (type(p) == kern_node)
1734       q = p;
1735     else
1736     {
1737       q = glue_ptr(p);
1738       active_width[2 + stretch_order(q)] = active_width[2 + stretch_order(q)] + stretch(q);
1739       active_width[6] = active_width[6] + shrink(q);
1740
1741       if ((shrink_order(q) != normal) && (shrink(q) != 0))
1742       {
1743         print_err("Infinite glue shrinkage found in box being split");
1744         help4("The box you are \\vsplitting contains some infinitely",
1745             "shrinkable glue, e.g., `\\vss' or `\\vskip 0pt minus 1fil'.",
1746             "Such glue doesn't belong there; but you can safely proceed,",
1747             "since the offensive shrinkability has been made finite.");
1748         error();
1749         r = new_spec(q);
1750         shrink_order(r) = normal;
1751         delete_glue_ref(q);
1752         glue_ptr(p) = r;
1753         q = r;
1754       }
1755     }
1756
1757     cur_height = cur_height + prev_dp + width(q);
1758     prev_dp = 0;
1759 lab45:
1760     if (prev_dp > d)
1761     {
1762       cur_height = cur_height + prev_dp - d;
1763       prev_dp = d;
1764     }
1765
1766     prev_p = p;
1767     p = link(prev_p);
1768   }
1769
1770 lab30:
1771   return best_place;
1772 }
1773 /* sec 0977 */
1774 halfword vsplit_(eight_bits n, scaled h)
1775 {
1776   halfword v;
1777   halfword p;
1778   halfword q;
1779
1780   v = box(n);
1781
1782   if (split_first_mark != 0)
1783   {
1784     delete_token_ref(split_first_mark);
1785     split_first_mark = 0;
1786     delete_token_ref(split_bot_mark);
1787     split_bot_mark = 0;
1788   }
1789
1790   if (v == 0)
1791   {
1792     return 0;
1793   }
1794
1795   if (type(v) != vlist_node)
1796   {
1797     print_err("");
1798     print_esc("vsplit");
1799     print_string(" needs a ");
1800     print_esc("vbox");
1801     help2("The box you are trying to split is an \\hbox.",
1802         "I can't split such a box, so I'll leave it alone.");
1803     error();
1804     return 0;
1805   }
1806
1807   q = vert_break(list_ptr(v), h, split_max_depth);
1808   p = list_ptr(v);
1809
1810   if (p == q)
1811     list_ptr(v) = 0;
1812   else while (true)
1813   {
1814     if (type(p) == mark_node)
1815       if (split_first_mark == 0)
1816       {
1817         split_first_mark = mark_ptr(p);
1818         split_bot_mark = split_first_mark;
1819         token_ref_count(split_first_mark) = token_ref_count(split_first_mark) + 2;
1820       }
1821       else
1822       {
1823         delete_token_ref(split_bot_mark);
1824         split_bot_mark = mark_ptr(p);
1825         add_token_ref(split_bot_mark);
1826       }
1827
1828     if (link(p) == q)
1829     {
1830       link(p) = 0;
1831       goto lab30;
1832     }
1833     p = link(p);
1834   }
1835 lab30:;
1836   q = prune_page_top(q);
1837   p = list_ptr(v);
1838   free_node(v, box_node_size);
1839  
1840   if (q == 0)
1841     box(n) = 0;
1842   else
1843     box(n) = vpackage(q, 0, 1, 1073741823L);  /* 2^30 - 1 */
1844
1845   return vpackage(p, h, exactly, split_max_depth);
1846 }
1847 /* sec 0985 */
1848 void print_totals (void)
1849 {
1850   print_scaled(page_so_far[1]);
1851
1852   if (page_so_far[2] != 0)
1853   {
1854     print_string(" plus ");
1855     print_scaled(page_so_far[2]);
1856     print_string("");
1857   }
1858
1859   if (page_so_far[3] != 0)
1860   {
1861     print_string(" plus ");
1862     print_scaled(page_so_far[3]);
1863     print_string("fil");
1864   }
1865
1866   if (page_so_far[4] != 0)
1867   {
1868     print_string(" plus ");
1869     print_scaled(page_so_far[4]);
1870     print_string("fill");
1871   }
1872
1873   if (page_so_far[5] != 0)
1874   {
1875     print_string(" plus ");
1876     print_scaled(page_so_far[5]);
1877     print_string("filll");
1878   }
1879
1880   if (page_so_far[6] != 0)
1881   {
1882     print_string(" minus ");
1883     print_scaled(page_so_far[6]);
1884   }
1885 }
1886 /* sec 0987 */
1887 void freeze_page_specs_(small_number s)
1888 {
1889   page_contents = s;
1890   page_goal = vsize;
1891   page_max_depth = max_depth;
1892   page_depth = 0;
1893   do_all_six(set_page_so_far_zero);
1894   least_page_cost = awful_bad;
1895
1896 #ifdef STAT
1897   if (tracing_pages > 0)
1898   {
1899     begin_diagnostic();
1900     print_nl("%% goal height=");
1901     print_scaled(page_goal);
1902     print_string(", max depth=");
1903     print_scaled(page_max_depth);
1904     end_diagnostic(false);
1905   }
1906 #endif /* STAT */
1907 }
1908 /* sec 0992 */
1909 void box_error_(eight_bits n)
1910 {
1911   error();
1912   begin_diagnostic();
1913   print_nl("The following box has been deleted:");
1914   show_box(box(n));
1915   end_diagnostic(true);
1916   flush_node_list(box(n));
1917   box(n) = 0;
1918 }
1919 /* sec 0993 */
1920 void ensure_vbox_(eight_bits n)
1921 {
1922   halfword p;
1923
1924   p = box(n);
1925
1926   if (p != 0)
1927     if (type(p) == hlist_node)
1928     {
1929       print_err("Insertions can only be added to a vbox");
1930       help3("Tut tut: You're trying to \\insert into a",
1931           "\\box register that now contains an \\hbox.",
1932           "Proceed, and I'll discard its present contents.");
1933       box_error(n);
1934     }
1935 }
1936 /* sec 1012 */
1937 void fire_up_(halfword c)
1938 {
1939   pointer p, q, r, s;
1940   pointer prev_p;
1941 /*  unsigned char n;  */
1942   unsigned int n;         /* 95/Jan/7 */
1943   boolean wait;
1944   integer save_vbadness;
1945   scaled save_vfuzz;
1946   pointer save_split_top_skip;
1947
1948   if (type(best_page_break) == penalty_node)
1949   {
1950     geq_word_define(int_base + output_penalty_code, penalty(best_page_break));
1951     penalty(best_page_break) = inf_penalty;
1952   }
1953   else
1954     geq_word_define(int_base + output_penalty_code, inf_penalty);
1955
1956   if (bot_mark != 0)
1957   {
1958     if (top_mark != 0)
1959       delete_token_ref(top_mark);
1960
1961     top_mark = bot_mark;
1962     add_token_ref(top_mark);
1963     delete_token_ref(first_mark);
1964     first_mark = 0;
1965   }
1966
1967   if (c == best_page_break)
1968     best_page_break = 0;
1969
1970   if (box(255) != 0)
1971   {
1972     print_err("");
1973     print_esc("box");
1974     print_string("255 is not void");
1975     help2("You shouldn't use \\box255 except in \\output routines.",
1976         "Proceed, and I'll discard its present contents.");
1977     box_error(255);
1978   }
1979
1980   insert_penalties = 0;
1981   save_split_top_skip = split_top_skip;
1982
1983   if (holding_inserts <= 0)
1984   {
1985     r = link(page_ins_head);
1986
1987     while (r != page_ins_head)
1988     {
1989       if (best_ins_ptr(r) != 0)
1990       {
1991         n = subtype(r);
1992         ensure_vbox(n);
1993
1994         if (box(n) == 0)
1995           box(n) = new_null_box();
1996
1997         p = box(n) + list_offset;
1998
1999         while (link(p) != 0)
2000           p = link(p);
2001
2002         last_ins_ptr(r) = p;
2003       }
2004
2005       r = link(r);
2006     }
2007   }
2008
2009   q = hold_head;
2010   link(q) = 0;
2011   prev_p = page_head;
2012   p = link(prev_p);
2013
2014   while (p != best_page_break)
2015   {
2016     if (type(p) == ins_node)
2017     {
2018       if (holding_inserts <= 0)
2019       {
2020         r = link(page_ins_head);
2021
2022         while (subtype(r) != subtype(p))
2023           r = link(r);
2024
2025         if (best_ins_ptr(r) == 0)
2026           wait = true;
2027         else
2028         {
2029           wait = false;
2030           s = last_ins_ptr(r);
2031           link(s) = ins_ptr(p);
2032
2033           if (best_ins_ptr(r) == p)
2034           {
2035             if (type(r) == split_up)
2036               if ((broken_ins(r) == p) && (broken_ins(r) != 0))
2037               {
2038                 while (link(s) != broken_ptr(r))
2039                   s = link(s);
2040
2041                 link(s) = 0;
2042                 split_top_skip = split_top_ptr(p);
2043                 ins_ptr(p) = prune_page_top(broken_ptr(r));
2044
2045                 if (ins_ptr(p) != 0)
2046                 {
2047                   temp_ptr = vpackage(ins_ptr(p), 0, 1, 1073741823L);  /* 2^30 - 1 */
2048                   height(p) = height(temp_ptr) + depth(temp_ptr);
2049                   free_node(temp_ptr, box_node_size);
2050                   wait = true;
2051                 }
2052               }
2053
2054             best_ins_ptr(r) = 0;
2055             n = subtype(r);
2056             temp_ptr = list_ptr(box(n));
2057             free_node(box(n), box_node_size);
2058             box(n) = vpackage(temp_ptr, 0, 1, 1073741823L);  /* 2^30 - 1 */
2059           }
2060           else
2061           {
2062             while (link(s) != 0)
2063               s = link(s);
2064
2065             last_ins_ptr(r) = s;
2066           }
2067         }
2068
2069         link(prev_p) = link(p);
2070         link(p) = 0;
2071
2072         if (wait)
2073         {
2074           link(q) = p;
2075           q = p;
2076           incr(insert_penalties);
2077         }
2078         else
2079         {
2080           delete_glue_ref(split_top_ptr(p));
2081           free_node(p, ins_node_size);
2082         }
2083
2084         p = prev_p;
2085       }
2086     }
2087     else if (type(p) == mark_node)
2088     {
2089       if (first_mark == 0)
2090       {
2091         first_mark = mark_ptr(p);
2092         add_token_ref(first_mark);
2093       }
2094
2095       if (bot_mark != 0)
2096         delete_token_ref(bot_mark);
2097
2098       bot_mark = mark_ptr(p);
2099       add_token_ref(bot_mark);
2100     }
2101     prev_p = p;
2102     p = link(prev_p);
2103   }
2104
2105   split_top_skip = save_split_top_skip;
2106
2107   if (p != 0)    /* if p<>null then l.19730 */
2108   {
2109     if (link(contrib_head) == 0)
2110       if (nest_ptr == 0)
2111         tail = page_tail;
2112       else
2113         nest[0].tail_field = page_tail;
2114
2115     link(page_tail) = link(contrib_head);
2116     link(contrib_head) = p;
2117     link(prev_p) = 0;
2118   }
2119
2120   save_vbadness = vbadness;
2121   vbadness = inf_bad;
2122   save_vfuzz = vfuzz;
2123   vfuzz = max_dimen;
2124   box(255) = vpackage(link(page_head), best_size, 0, page_max_depth);
2125   vbadness = save_vbadness;
2126   vfuzz = save_vfuzz;
2127
2128   if (last_glue != empty_flag)
2129     delete_glue_ref(last_glue);
2130
2131   page_contents = 0;
2132   page_tail = page_head;
2133   link(page_head) = 0;
2134   last_glue = empty_flag;
2135   last_penalty = 0;
2136   last_kern = 0;
2137   page_depth = 0;
2138   page_max_depth = 0;
2139
2140   if (q != hold_head)
2141   {
2142     link(page_head) = link(hold_head);
2143     page_tail = q;
2144   }
2145
2146   r = link(page_ins_head);
2147
2148   while (r != page_ins_head)
2149   {
2150     q = link(r);
2151     free_node(r, page_ins_node_size);
2152     r = q;
2153   }
2154  
2155   link(page_ins_head) = page_ins_head;
2156
2157   if ((top_mark != 0) && (first_mark == 0))
2158   {
2159     first_mark = top_mark;
2160     add_token_ref(top_mark);
2161   }
2162
2163   if (output_routine != 0)
2164     if (dead_cycles >= max_dead_cycles)
2165     {
2166       print_err("Output loop---");
2167       print_int(dead_cycles);
2168       print_string(" consecutive dead cycles");
2169       help3("I've concluded that your \\output is awry; it never does",
2170           "\\ship_out, so I'm shipping \box255 out myself. Next ",
2171           "increase \\maxdeadcycles if you want me to be more patient!");
2172       error();
2173     }
2174     else
2175     {
2176       output_active = true;
2177       incr(dead_cycles);
2178       push_nest();
2179       mode = -vmode;
2180       cur_list.aux_field.cint = ignore_depth;
2181       mode_line = - (integer) line;
2182       begin_token_list(output_routine, output_text);
2183       new_save_level(output_group);
2184       normal_paragraph();
2185       scan_left_brace();
2186       return;
2187     }
2188
2189   {
2190     if (link(page_head) != 0)
2191     {
2192       if (link(contrib_head) == 0)
2193         if (nest_ptr == 0)
2194           tail = page_tail;
2195         else
2196           nest[0].tail_field = page_tail;
2197       else
2198         link(page_tail) = link(contrib_head);
2199
2200       link(contrib_head) = link(page_head);
2201       link(page_head) = 0;
2202       page_tail = page_head;
2203     }
2204
2205     ship_out(box(255));
2206     box(255) = 0;
2207   }
2208 }