OSDN Git Service

memory aligning.
[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   bool 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   bool node_r_stays_active;
93   scaled line_width;
94   char fit_class;
95   halfword b;       /* current badness */
96   integer d;
97   bool 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 ((v >= hi_mem_min))
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;       // abort_flag set
175                       }
176                       break;
177                   }
178                 }
179
180                 while (s != 0)
181                 {
182                   if ((s >= hi_mem_min))
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 ((s >= hi_mem_min))
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 /* STAT */
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   bool disc_break;
599   bool 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 ((q >= hi_mem_min))
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             {
914               if (interrupt != 0)
915               {
916                 pause_for_instructions();
917               }
918             }
919
920             switch (op_byte(q))
921             {
922               case 1:
923               case 5:
924                 {
925                   cur_l = rem_byte(q);
926                   ligature_present = true;
927                 }
928                 break;
929
930               case 2:
931               case 6:
932                 {
933                   cur_r = rem_byte(q);
934
935                   if (lig_stack != 0)
936                     character(lig_stack) = cur_r;
937                   else
938                   {
939                     lig_stack = new_lig_item(cur_r);
940
941                     if (j == n)
942                       bchar = non_char;
943                     else
944                     {
945                       p = get_avail();
946                       list_ptr(lig_stack) = p;
947                       character(p) = hu[j + 1];
948                       font(p) = hf;
949                     }
950                   }
951                 }
952                 break;
953
954               case 3:
955                 {
956                   cur_r = rem_byte(q);
957                   p = lig_stack;
958                   lig_stack = new_lig_item(cur_r);
959                   link(lig_stack) = p;
960                 }
961                 break;
962
963               case 7:
964               case 11:
965                 {
966                   if (ligature_present)
967                   {
968                     p = new_ligature(hf, cur_l, mem[cur_q].hh.rh);
969
970                     if (lft_hit)
971                     {
972                       mem[p].hh.b1 = 2;
973                       lft_hit = false;
974                     }
975 /*        if (false)
976         if (lig_stack == 0){
977           incr(mem[p].hh.b1); 
978           rt_hit = false; 
979         } */              /* removed 99/Jan/6 */
980                     mem[cur_q].hh.rh = p;
981                     t = p;
982                     ligature_present = false;
983                   }
984                   cur_q = t;
985                   cur_l = rem_byte(q);
986                   ligature_present = true;
987                 }
988                 break;
989
990               default:
991                 {
992                   cur_l = rem_byte(q);
993                   ligature_present = true;
994
995                   if (lig_stack != 0)        /* BUG FIX  */
996                   {
997                     if (mem[lig_stack + 1].hh.rh != 0) /* l.17828 ? */
998                     {
999                       mem[t].hh.rh = mem[lig_stack + 1].hh.rh;
1000                       t = mem[t].hh.rh;
1001                       incr(j);
1002                     }
1003                     p = lig_stack;
1004                     lig_stack = mem[p].hh.rh;
1005                     free_node(p, 2);
1006                     if (lig_stack == 0)  /* if lig_stack=null ? */
1007                     {
1008                       if (j < n)
1009                         cur_r = hu[j + 1];
1010                       else
1011                         cur_r = bchar;
1012                       if (odd(hyf[j]))
1013                         cur_rh = hchar;
1014                       else
1015                         cur_rh = 256;
1016                     }
1017                     else
1018                       cur_r = mem[lig_stack].hh.b1;
1019                   }
1020                   else if (j == n)
1021                     goto lab30;
1022                   else
1023                   {
1024                     append_charnode_to_t(cur_r);
1025                     incr(j);
1026                     set_cur_r();
1027                   }
1028                 }
1029                 break;
1030             }
1031
1032             if (op_byte(q) > 4)
1033               if (op_byte(q) != 7)
1034                 goto lab30;
1035
1036             goto lab22;
1037           }
1038
1039           w = char_kern(hf, q);
1040           goto lab30;
1041         }
1042
1043     if (q.b0 >= stop_flag)
1044       if (cur_rh == non_char)
1045         goto lab30;
1046       else
1047       {
1048         cur_rh = non_char;
1049         goto lab22;
1050       }
1051       
1052     k = k + skip_byte(q) + 1;
1053     q = font_info[k].qqqq;
1054   }
1055 lab30:
1056   wrap_lig(rt_hit);
1057
1058   if (w != 0)
1059   {
1060     link(t) = new_kern(w);
1061     t = link(t);
1062     w = 0;
1063   }
1064
1065   if (lig_stack != 0)        /* l.17841 */
1066   {
1067     cur_q = t;
1068     cur_l = character(lig_stack);
1069     ligature_present = true;
1070     pop_lig_stack();
1071     goto lab22;
1072   }
1073
1074   return j;
1075 }
1076 /* sec 0895 */
1077 void hyphenate (void)
1078 {
1079 /*  char i, j, l;  */
1080   char i, j;
1081   int l;              /* 95/Jan/7 */
1082   halfword q, r, s;
1083   halfword bchar;
1084   halfword major_tail, minor_tail;
1085 /*  ASCII_code c;  */
1086   int c;              /* 95/Jan/7 */
1087   char c_loc;
1088 /*  integer r_count; */
1089   int r_count;           /* 95/Jan/7 */
1090   halfword hyf_node;
1091   trie_pointer z;
1092   integer v;
1093   hyph_pointer h;
1094   str_number k;
1095   pool_pointer u;
1096
1097   for (j = 0; j <= hn; j++)
1098     hyf[j] = 0;
1099
1100   h = hc[1];
1101   incr(hn);
1102   hc[hn] = cur_lang;
1103
1104   for (j = 2; j <= hn; j++)
1105     h = (h + h + hc[j]) % hyphen_prime;
1106
1107   while (true)
1108   {
1109     k = hyph_word[h];
1110
1111     if (k == 0)
1112       goto lab45;
1113
1114     if (length(k) < hn)
1115       goto lab45;
1116
1117     if (length(k) == hn)
1118     {
1119       j = 1;
1120       u = str_start[k];
1121
1122       do
1123         {
1124           if (str_pool[u] < hc[j])
1125             goto lab45;
1126
1127           if (str_pool[u] > hc[j])
1128             goto lab30;
1129
1130           incr(j);
1131           incr(u);
1132         }
1133       while(!(j > hn));
1134
1135       s = hyph_list[h];
1136
1137       while (s != 0)
1138       {
1139         hyf[info(s)] = 1;
1140         s = link(s);
1141       }
1142
1143       decr(hn);
1144       goto lab40;
1145     }
1146
1147 lab30:;
1148     if (h > 0)
1149       decr(h);
1150     else
1151       h = hyphen_prime;
1152   }
1153 lab45:
1154   decr(hn);
1155
1156   if (trie_trc[cur_lang + 1] != cur_lang)
1157     return;
1158
1159   hc[0] = 0;
1160   hc[hn + 1] = 0;
1161   hc[hn + 2] = 256;
1162
1163   for (j = 0; j <= hn - rhyf + 1; j++)
1164   {
1165     z = trie_trl[cur_lang + 1] + hc[j];
1166     l = j;
1167
1168     while (hc[l] == trie_trc[z])
1169     {
1170       if (trie_tro[z] != min_trie_op)
1171       {
1172         v = trie_tro[z];
1173
1174         do
1175           {
1176             v = v + op_start[cur_lang];
1177             i = l - hyf_distance[v];
1178
1179             if (hyf_num[v] > hyf[i])
1180               hyf[i]= hyf_num[v];
1181
1182             v = hyf_next[v];
1183           }
1184         while(!(v == min_trie_op));
1185       }
1186
1187       incr(l);
1188       z = trie_trl[z] + hc[l];
1189     }
1190   }
1191 lab40:
1192   for (j = 0; j <= lhyf - 1; j++)
1193     hyf[j] = 0;
1194
1195   for (j = 0; j <= rhyf - 1; j++)
1196     hyf[hn - j]= 0;
1197
1198   for (j = lhyf; j <= hn - rhyf; j++)
1199     if (odd(hyf[j]))
1200       goto lab41;
1201
1202   return;
1203 lab41:;
1204   q = link(hb);
1205   link(hb) = 0;
1206   r = link(ha);
1207   link(ha) = 0;
1208   bchar = hyfbchar;
1209
1210   if ((ha >= hi_mem_min))
1211     if (font(ha) != hf)
1212       goto lab42;
1213     else
1214     {
1215       init_list = ha;
1216       init_lig = false;
1217       hu[0] = character(ha);
1218     }
1219   else if (type(ha) == ligature_node)
1220     if (font(lig_char(ha)) != hf)
1221       goto lab42;
1222     else
1223     {
1224       init_list = lig_ptr(ha);
1225       init_lig = true;
1226       init_lft = (subtype(ha) > 1);
1227       hu[0] = character(lig_char(ha));
1228
1229       if (init_list == 0)
1230         if (init_lft)
1231         {
1232           hu[0] = 256;
1233           init_lig = false;
1234         }
1235
1236       free_node(ha, small_node_size);
1237     }
1238   else
1239   {
1240     if (!(r >= hi_mem_min))
1241       if (type(r) == ligature_node)
1242         if (subtype(r) > 1)
1243           goto lab42;
1244
1245     j = 1;
1246     s = ha;
1247     init_list = 0;
1248     goto lab50;
1249   }
1250
1251   s = cur_p;
1252
1253   while (link(s) != ha)
1254     s = link(s);
1255
1256   j = 0;
1257   goto lab50;
1258 lab42:
1259   s = ha;
1260   j = 0;
1261   hu[0] = 256;
1262   init_lig = false;
1263   init_list = 0;
1264 lab50:
1265   flush_node_list(r);
1266
1267   do
1268     {
1269       l = j;
1270       j = reconstitute(j, hn, bchar, hyf_char) + 1;
1271
1272       if (hyphen_passed == 0)
1273       {
1274         link(s) = link(hold_head);
1275
1276         while (link(s) != 0) /* l.17903 */
1277           s = link(s);
1278
1279         if (odd(hyf[j - 1]))
1280         {
1281           l = j;
1282           hyphen_passed = j - 1;
1283           link(hold_head) = 0;
1284         }
1285       }
1286
1287       if (hyphen_passed > 0)
1288         do
1289           {
1290             r = get_node(small_node_size);
1291             link(r) = link(hold_head);
1292             type(r) = disc_node;
1293             major_tail = r;
1294             r_count = 0;
1295
1296             while (mem[major_tail].hh.rh != 0)
1297             {
1298               major_tail = link(major_tail);
1299               incr(r_count);
1300             }
1301
1302             i = hyphen_passed;
1303             hyf[i] = 0;
1304             minor_tail = 0;
1305             pre_break(r) = 0;
1306             hyf_node = new_character(hf, hyf_char);
1307
1308             if (hyf_node != 0)
1309             {
1310               incr(i);
1311               c = hu[i];
1312               hu[i] = hyf_char;
1313               free_avail(hyf_node);
1314             }
1315
1316             while (l <= i)
1317             {
1318               l = reconstitute(l, i, font_bchar[hf], non_char) + 1;
1319
1320               if (link(hold_head) != 0) /* BUG FIX ??? */
1321               {
1322                 if (minor_tail == 0)
1323                   pre_break(r) = link(hold_head);
1324                 else
1325                   link(minor_tail) = link(hold_head);
1326
1327                 minor_tail = link(hold_head);
1328
1329                 while (link(minor_tail) != 0)  /* BUG FIX */
1330                   minor_tail = link(minor_tail);
1331               }
1332             }
1333
1334             if (hyf_node != 0) /* if hyf_node<>null then l.17956 */
1335             {
1336               hu[i] = c;
1337               l = i;
1338               decr(i);
1339             }
1340
1341             minor_tail = 0;
1342             post_break(r) = 0;
1343             c_loc = 0;
1344
1345             if (bchar_label[hf] != non_address) /* i.e. 0 --- 96/Jan/15 */
1346             {
1347               decr(l);
1348               c = hu[l];
1349               c_loc = l;
1350               hu[l]= 256;
1351             }
1352
1353             while (l < j)
1354             {
1355               do
1356                 {
1357                   l = reconstitute(l, hn, bchar, 256) + 1;
1358
1359                   if (c_loc > 0)
1360                   {
1361                     hu[c_loc] = c;    /* c may be used ... */
1362                     c_loc = 0;
1363                   }
1364
1365                   if (link(hold_head) != 0)     /* BUG FIX */
1366                   {
1367                     if (minor_tail == 0) /* begin if minor_tail=null then */
1368                       post_break(r) = link(hold_head);
1369                     else
1370                       link(minor_tail) = link(hold_head);
1371
1372                     minor_tail = link(hold_head);
1373
1374                     while (link(minor_tail) != 0)    /* ??? */
1375                       minor_tail = link(minor_tail);
1376                   }
1377                 }
1378               while (!(l >= j));
1379
1380               while (l > j)
1381               {
1382                 j = reconstitute(j, hn, bchar, non_char) + 1;
1383                 link(major_tail) = link(hold_head);
1384
1385                 while (mem[major_tail].hh.rh != 0)
1386                 {
1387                   major_tail = link(major_tail);
1388                   incr(r_count);
1389                 }
1390               }
1391             }
1392
1393             if (r_count > 127)
1394             {
1395               link(s) = link(r);
1396               link(r) = 0;
1397               flush_node_list(r);
1398             }
1399             else
1400             {
1401               link(s) = r;
1402               replace_count(r) = r_count;
1403             }
1404
1405             s = major_tail;
1406             hyphen_passed = j - 1;
1407             link(hold_head) = 0;
1408           }
1409         while(!(! odd(hyf[j - 1])));
1410     }
1411   while(!(j > hn));
1412
1413   link(s) = q;
1414   flush_list(init_list);
1415 }
1416 /* sec 0934 */
1417 void new_hyph_exceptions (void)
1418 {
1419 /*  small_number n;  */ /* in 3.141 */
1420   char n;
1421 /*  small_number j;  */ /* in 3.141 */
1422   char j;
1423   hyph_pointer h;
1424   str_number k;
1425   halfword p;
1426   halfword q;
1427   str_number s, t;
1428   pool_pointer u, v;
1429
1430   scan_left_brace();
1431   set_cur_lang();
1432   n = 0;
1433   p = 0;
1434
1435   while (true)
1436   {
1437     get_x_token();
1438 lab21:
1439     switch (cur_cmd)
1440     {
1441       case letter:
1442       case other_char:
1443       case char_given:
1444         if (cur_chr == '-')
1445         {
1446           if (n < 63)
1447           {
1448             q = get_avail();
1449             link(q) = p;
1450             info(q) = n;
1451             p = q;
1452           }
1453         }
1454         else
1455         {
1456           if (lc_code(cur_chr) == 0)
1457           {
1458             print_err("Not a letter");
1459             help2("Letters in \\hyphenation words must have \\lccode>0.",
1460                 "Proceed; I'll ignore the character I just read.");
1461             error();
1462           }
1463           else if (n < 63)
1464           {
1465             incr(n);
1466             hc[n] = lc_code(cur_chr);
1467           }
1468         }
1469         break;
1470
1471       case char_num:
1472         {
1473           scan_char_num();
1474           cur_chr = cur_val;
1475           cur_cmd = char_given;
1476           goto lab21;
1477         }
1478         break;
1479
1480       case spacer:
1481       case right_brace:
1482         {
1483           if (n > 1)
1484           {
1485             incr(n);
1486             hc[n] = cur_lang;
1487             str_room(n);
1488             h = 0;
1489
1490             for (j = 1; j <= n; j++)
1491             {
1492               h = (h + h + hc[j]) % hyphen_prime;
1493               append_char(hc[j]);
1494             }
1495
1496             s = make_string();
1497
1498             if (hyph_count == hyphen_prime)
1499             {
1500               overflow("exception dictionary", hyphen_prime); /* exception dictionary - NOT DYNAMIC */
1501               /*    not dynamic ---- but can be set -e=... from command line in ini-TeX */
1502               return;     // abort_flag set
1503             }
1504
1505             incr(hyph_count);
1506
1507             while (hyph_word[h] != 0)
1508             {
1509               k = hyph_word[h];
1510
1511               if (length(k) < length(s))
1512                 goto lab40;
1513
1514               if (length(k) > length(s))
1515                 goto lab45;
1516
1517               u = str_start[k];
1518               v = str_start[s];
1519
1520               do
1521                 {
1522                   if (str_pool[u] < str_pool[v])
1523                     goto lab40;
1524
1525                   if (str_pool[u] > str_pool[v])
1526                     goto lab45;
1527
1528                   incr(u);
1529                   incr(v);
1530                 }
1531               while(!(u == str_start[k + 1]));
1532 lab40:
1533               q = hyph_list[h];
1534               hyph_list[h] = p;
1535               p = q;
1536               t = hyph_word[h];
1537               hyph_word[h] = s;
1538               s = t;
1539 lab45:;
1540               if (h > 0)
1541                 decr(h);
1542               else
1543                 h = hyphen_prime;
1544             }
1545
1546             hyph_word[h] = s;
1547             hyph_list[h] = p;
1548           }
1549
1550           if (cur_cmd == right_brace)
1551             return;
1552
1553           n = 0;
1554           p = 0;
1555         }
1556         break;
1557
1558       default:
1559         {
1560           print_err("Improper ");
1561           print_esc("hyphenation");
1562           print_string(" will be flushed");
1563           help2("Hyphenation exceptions must contain only letters",
1564               "and hyphens. But continue; I'll forgive and forget.");
1565           error();
1566         }
1567         break;
1568     } /* end of switch */
1569   }
1570 }
1571 /* sec 0968 */
1572 halfword prune_page_top_(halfword p)
1573 {
1574   halfword prev_p;
1575   halfword q;
1576
1577   prev_p = temp_head;
1578   link(temp_head) = p;
1579
1580   while(p != 0)
1581     switch(type(p))
1582     {
1583       case hlist_node:
1584       case vlist_node:
1585       case rule_node:
1586         {
1587           q = new_skip_param(split_top_skip_code);
1588           link(prev_p) = q;
1589           link(q) = p;
1590
1591           if (width(temp_ptr) > height(p))
1592             width(temp_ptr) = width(temp_ptr) - height(p);
1593           else
1594             width(temp_ptr) = 0;
1595
1596           p = 0;
1597         }
1598         break;
1599
1600       case whatsit_node:
1601       case mark_node:
1602       case ins_node:
1603         {
1604           prev_p = p;
1605           p = link(prev_p);
1606         }
1607         break;
1608
1609       case glue_node:
1610       case kern_node:
1611       case penalty_node:
1612         {
1613           q = p;
1614           p = link(q);
1615           link(q) = 0;
1616           link(prev_p) = p;
1617           flush_node_list(q);
1618         }
1619         break;
1620
1621       default:
1622         {
1623           confusion("pruning");
1624           return 0;       // abort_flag set
1625         }
1626         break;
1627     }
1628
1629   return link(temp_head);
1630 }
1631 /* sec 0970 */
1632 halfword vert_break_(halfword p, scaled h, scaled d)
1633 {
1634   halfword prev_p;
1635   halfword q, r;
1636   integer pi;
1637   integer b;
1638   integer least_cost;
1639   halfword best_place;
1640   scaled prev_dp; 
1641 /*  small_number t;  */
1642   int t;              /* 95/Jan/7 */
1643   prev_p = p;
1644
1645   least_cost = awful_bad;
1646   do_all_six(set_height_zero);
1647   prev_dp = 0;
1648
1649   while (true)
1650   {
1651     if (p == 0)
1652       pi = eject_penalty;
1653     else switch(type(p))
1654     {
1655       case hlist_node:
1656       case vlist_node:
1657       case rule_node:
1658         {
1659           cur_height = cur_height + prev_dp + height(p);
1660           prev_dp = depth(p);
1661           goto lab45;
1662         }
1663         break;
1664
1665       case whatsit_node:
1666         goto lab45;
1667         break;
1668
1669       case glue_node:
1670         if (precedes_break(prev_p))
1671           pi = 0;
1672         else
1673           goto lab90;
1674         break;
1675
1676       case kern_node:
1677         {
1678           if (link(p) == 0)
1679             t = penalty_node;
1680           else
1681             t = type(link(p));
1682
1683           if (t == glue_node)
1684             pi = 0;
1685           else
1686             goto lab90;
1687         }
1688         break;
1689
1690       case penalty_node:
1691         pi = penalty(p);
1692         break;
1693
1694       case mark_node:
1695       case ins_node:
1696         goto lab45;
1697         break;
1698
1699       default:
1700         {
1701           confusion("vertbreak");
1702           return 0;       // abort_flag set
1703         }
1704         break;
1705     }
1706
1707     if (pi < inf_penalty)
1708     {
1709       if (cur_height < h)
1710         if ((active_width[3] != 0) || (active_width[4] != 0) || (active_width[5]!= 0))
1711           b = 0;
1712         else
1713           b = badness(h - cur_height, active_width[2]);
1714       else
1715         if (active_width[1] - h > active_width[6])
1716           b = awful_bad;
1717         else
1718           b = badness(cur_height - h, active_width[6]);
1719
1720       if (b < awful_bad)
1721         if (pi <= eject_penalty)
1722           b = pi;
1723         else
1724           if (b < inf_bad)
1725             b = b + pi;
1726           else
1727             b = deplorable;
1728
1729       if (b <= least_cost)
1730       {
1731         best_place = p;
1732         least_cost = b;
1733         best_height_plus_depth = cur_height + prev_dp;
1734       }
1735
1736       if ((b == awful_bad) || (pi <= eject_penalty))
1737         goto lab30;
1738     }
1739
1740     if ((type(p) < glue_node) || (type(p) > kern_node))
1741       goto lab45;
1742 lab90:
1743     if (type(p) == kern_node)
1744       q = p;
1745     else
1746     {
1747       q = glue_ptr(p);
1748       active_width[2 + stretch_order(q)] = active_width[2 + stretch_order(q)] + stretch(q);
1749       active_width[6] = active_width[6] + shrink(q);
1750
1751       if ((shrink_order(q) != normal) && (shrink(q) != 0))
1752       {
1753         print_err("Infinite glue shrinkage found in box being split");
1754         help4("The box you are \\vsplitting contains some infinitely",
1755             "shrinkable glue, e.g., `\\vss' or `\\vskip 0pt minus 1fil'.",
1756             "Such glue doesn't belong there; but you can safely proceed,",
1757             "since the offensive shrinkability has been made finite.");
1758         error();
1759         r = new_spec(q);
1760         shrink_order(r) = normal;
1761         delete_glue_ref(q);
1762         glue_ptr(p) = r;
1763         q = r;
1764       }
1765     }
1766
1767     cur_height = cur_height + prev_dp + width(q);
1768     prev_dp = 0;
1769 lab45:
1770     if (prev_dp > d)
1771     {
1772       cur_height = cur_height + prev_dp - d;
1773       prev_dp = d;
1774     }
1775
1776     prev_p = p;
1777     p = link(prev_p);
1778   }
1779
1780 lab30:
1781   return best_place;
1782 }
1783 /* sec 0977 */
1784 halfword vsplit_(eight_bits n, scaled h)
1785 {
1786   halfword v;
1787   halfword p;
1788   halfword q;
1789
1790   v = box(n);
1791
1792   if (split_first_mark != 0)
1793   {
1794     delete_token_ref(split_first_mark);
1795     split_first_mark = 0;
1796     delete_token_ref(split_bot_mark);
1797     split_bot_mark = 0;
1798   }
1799
1800   if (v == 0)
1801   {
1802     return 0;
1803   }
1804
1805   if (type(v) != vlist_node)
1806   {
1807     print_err("");
1808     print_esc("vsplit");
1809     print_string(" needs a ");
1810     print_esc("vbox");
1811     help2("The box you are trying to split is an \\hbox.",
1812         "I can't split such a box, so I'll leave it alone.");
1813     error();
1814     return 0;
1815   }
1816
1817   q = vert_break(list_ptr(v), h, split_max_depth);
1818   p = list_ptr(v);
1819
1820   if (p == q)
1821     list_ptr(v) = 0;
1822   else while (true)
1823   {
1824     if (type(p) == mark_node)
1825       if (split_first_mark == 0)
1826       {
1827         split_first_mark = mark_ptr(p);
1828         split_bot_mark = split_first_mark;
1829         token_ref_count(split_first_mark) = token_ref_count(split_first_mark) + 2;
1830       }
1831       else
1832       {
1833         delete_token_ref(split_bot_mark);
1834         split_bot_mark = mark_ptr(p);
1835         add_token_ref(split_bot_mark);
1836       }
1837
1838     if (link(p) == q)
1839     {
1840       link(p) = 0;
1841       goto lab30;
1842     }
1843     p = link(p);
1844   }
1845 lab30:;
1846   q = prune_page_top(q);
1847   p = list_ptr(v);
1848   free_node(v, box_node_size);
1849  
1850   if (q == 0)
1851     box(n) = 0;
1852   else
1853     box(n) = vpackage(q, 0, 1, 1073741823L);  /* 2^30 - 1 */
1854
1855   return vpackage(p, h, exactly, split_max_depth);
1856 }
1857 /* sec 0985 */
1858 void print_totals (void)
1859 {
1860   print_scaled(page_so_far[1]);
1861
1862   if (page_so_far[2] != 0)
1863   {
1864     print_string(" plus ");
1865     print_scaled(page_so_far[2]);
1866     print_string("");
1867   }
1868
1869   if (page_so_far[3] != 0)
1870   {
1871     print_string(" plus ");
1872     print_scaled(page_so_far[3]);
1873     print_string("fil");
1874   }
1875
1876   if (page_so_far[4] != 0)
1877   {
1878     print_string(" plus ");
1879     print_scaled(page_so_far[4]);
1880     print_string("fill");
1881   }
1882
1883   if (page_so_far[5] != 0)
1884   {
1885     print_string(" plus ");
1886     print_scaled(page_so_far[5]);
1887     print_string("filll");
1888   }
1889
1890   if (page_so_far[6] != 0)
1891   {
1892     print_string(" minus ");
1893     print_scaled(page_so_far[6]);
1894   }
1895 }
1896 /* sec 0987 */
1897 void freeze_page_specs_(small_number s)
1898 {
1899   page_contents = s;
1900   page_goal = vsize;
1901   page_max_depth = max_depth;
1902   page_depth = 0;
1903   do_all_six(set_page_so_far_zero);
1904   least_page_cost = awful_bad;
1905
1906 #ifdef STAT
1907   if (tracing_pages > 0)
1908   {
1909     begin_diagnostic();
1910     print_nl("%% goal height=");
1911     print_scaled(page_goal);
1912     print_string(", max depth=");
1913     print_scaled(page_max_depth);
1914     end_diagnostic(false);
1915   }
1916 #endif /* STAT */
1917 }
1918 /* sec 0992 */
1919 void box_error_(eight_bits n)
1920 {
1921   error();
1922   begin_diagnostic();
1923   print_nl("The following box has been deleted:");
1924   show_box(box(n));
1925   end_diagnostic(true);
1926   flush_node_list(box(n));
1927   box(n) = 0;
1928 }
1929 /* sec 0993 */
1930 void ensure_vbox_(eight_bits n)
1931 {
1932   halfword p;
1933
1934   p = box(n);
1935
1936   if (p != 0)
1937     if (type(p) == hlist_node)
1938     {
1939       print_err("Insertions can only be added to a vbox");
1940       help3("Tut tut: You're trying to \\insert into a",
1941           "\\box register that now contains an \\hbox.",
1942           "Proceed, and I'll discard its present contents.");
1943       box_error(n);
1944     }
1945 }
1946 /* sec 1012 */
1947 void fire_up_(halfword c)
1948 {
1949   halfword p, q, r, s;
1950   halfword prev_p;
1951 /*  unsigned char n;  */
1952   unsigned int n;         /* 95/Jan/7 */
1953   bool wait;
1954   integer save_vbadness;
1955   scaled save_vfuzz;
1956   halfword save_split_top_skip;
1957
1958   if (type(best_page_break) == penalty_node)
1959   {
1960     geq_word_define(int_base + output_penalty_code, penalty(best_page_break));
1961     penalty(best_page_break) = inf_penalty;
1962   }
1963   else
1964     geq_word_define(int_base + output_penalty_code, inf_penalty);
1965
1966   if (bot_mark != 0)
1967   {
1968     if (top_mark != 0)
1969       delete_token_ref(top_mark);
1970
1971     top_mark = bot_mark;
1972     add_token_ref(top_mark);
1973     delete_token_ref(first_mark);
1974     first_mark = 0;
1975   }
1976
1977   if (c == best_page_break)
1978     best_page_break = 0;
1979
1980   if (box(255) != 0)
1981   {
1982     print_err("");
1983     print_esc("box");
1984     print_string("255 is not void");
1985     help2("You shouldn't use \\box255 except in \\output routines.",
1986         "Proceed, and I'll discard its present contents.");
1987     box_error(255);
1988   }
1989
1990   insert_penalties = 0;
1991   save_split_top_skip = split_top_skip;
1992
1993   if (holding_inserts <= 0)
1994   {
1995     r = link(page_ins_head);
1996
1997     while (r != page_ins_head)
1998     {
1999       if (best_ins_ptr(r) != 0)
2000       {
2001         n = subtype(r);
2002         ensure_vbox(n);
2003
2004         if (box(n) == 0)
2005           box(n) = new_null_box();
2006
2007         p = box(n) + list_offset;
2008
2009         while (link(p) != 0)
2010           p = link(p);
2011
2012         last_ins_ptr(r) = p;
2013       }
2014
2015       r = link(r);
2016     }
2017   }
2018
2019   q = hold_head;
2020   link(q) = 0;
2021   prev_p = page_head;
2022   p = link(prev_p);
2023
2024   while (p != best_page_break)
2025   {
2026     if (type(p) == ins_node)
2027     {
2028       if (holding_inserts <= 0)
2029       {
2030         r = link(page_ins_head);
2031
2032         while (subtype(r) != subtype(p))
2033           r = link(r);
2034
2035         if (best_ins_ptr(r) == 0)
2036           wait = true;
2037         else
2038         {
2039           wait = false;
2040           s = last_ins_ptr(r);
2041           link(s) = ins_ptr(p);
2042
2043           if (best_ins_ptr(r) == p)
2044           {
2045             if (type(r) == split_up)
2046               if ((broken_ins(r) == p) && (broken_ins(r) != 0))
2047               {
2048                 while (link(s) != broken_ptr(r))
2049                   s = link(s);
2050
2051                 link(s) = 0;
2052                 split_top_skip = split_top_ptr(p);
2053                 ins_ptr(p) = prune_page_top(broken_ptr(r));
2054
2055                 if (ins_ptr(p) != 0)
2056                 {
2057                   temp_ptr = vpackage(ins_ptr(p), 0, 1, 1073741823L);  /* 2^30 - 1 */
2058                   height(p) = height(temp_ptr) + depth(temp_ptr);
2059                   free_node(temp_ptr, box_node_size);
2060                   wait = true;
2061                 }
2062               }
2063
2064             best_ins_ptr(r) = 0;
2065             n = subtype(r);
2066             temp_ptr = list_ptr(box(n));
2067             free_node(box(n), box_node_size);
2068             box(n) = vpackage(temp_ptr, 0, 1, 1073741823L);  /* 2^30 - 1 */
2069           }
2070           else
2071           {
2072             while (link(s) != 0)
2073               s = link(s);
2074
2075             last_ins_ptr(r) = s;
2076           }
2077         }
2078
2079         link(prev_p) = link(p);
2080         link(p) = 0;
2081
2082         if (wait)
2083         {
2084           link(q) = p;
2085           q = p;
2086           incr(insert_penalties);
2087         }
2088         else
2089         {
2090           delete_glue_ref(split_top_ptr(p));
2091           free_node(p, ins_node_size);
2092         }
2093
2094         p = prev_p;
2095       }
2096     }
2097     else if (type(p) == mark_node)
2098     {
2099       if (first_mark == 0)
2100       {
2101         first_mark = mark_ptr(p);
2102         add_token_ref(first_mark);
2103       }
2104
2105       if (bot_mark != 0)
2106         delete_token_ref(bot_mark);
2107
2108       bot_mark = mark_ptr(p);
2109       add_token_ref(bot_mark);
2110     }
2111     prev_p = p;
2112     p = link(prev_p);
2113   }
2114
2115   split_top_skip = save_split_top_skip;
2116
2117   if (p != 0)    /* if p<>null then l.19730 */
2118   {
2119     if (link(contrib_head) == 0)
2120       if (nest_ptr == 0)
2121         tail = page_tail;
2122       else
2123         nest[0].tail_field = page_tail;
2124
2125     link(page_tail) = link(contrib_head);
2126     link(contrib_head) = p;
2127     link(prev_p) = 0;
2128   }
2129
2130   save_vbadness = vbadness;
2131   vbadness = inf_bad;
2132   save_vfuzz = vfuzz;
2133   vfuzz = max_dimen;
2134   box(255) = vpackage(link(page_head), best_size, 0, page_max_depth);
2135   vbadness = save_vbadness;
2136   vfuzz = save_vfuzz;
2137
2138   if (last_glue != empty_flag)
2139     delete_glue_ref(last_glue);
2140
2141   page_contents = 0;
2142   page_tail = page_head;
2143   link(page_head) = 0;
2144   last_glue = empty_flag;
2145   last_penalty = 0;
2146   last_kern = 0;
2147   page_depth = 0;
2148   page_max_depth = 0;
2149
2150   if (q != hold_head)
2151   {
2152     link(page_head) = link(hold_head);
2153     page_tail = q;
2154   }
2155
2156   r = link(page_ins_head);
2157
2158   while (r != page_ins_head)
2159   {
2160     q = link(r);
2161     free_node(r, page_ins_node_size);
2162     r = q;
2163   }
2164  
2165   link(page_ins_head) = page_ins_head;
2166
2167   if ((top_mark != 0) && (first_mark == 0))
2168   {
2169     first_mark = top_mark;
2170     add_token_ref(top_mark);
2171   }
2172
2173   if (output_routine != 0)
2174     if (dead_cycles >= max_dead_cycles)
2175     {
2176       print_err("Output loop---");
2177       print_int(dead_cycles);
2178       print_string(" consecutive dead cycles");
2179       help3("I've concluded that your \\output is awry; it never does",
2180           "\\ship_out, so I'm shipping \box255 out myself. Next ",
2181           "increase \\maxdeadcycles if you want me to be more patient!");
2182       error();
2183     }
2184     else
2185     {
2186       output_active = true;
2187       incr(dead_cycles);
2188       push_nest();
2189       mode = -vmode;
2190       cur_list.aux_field.cint = ignore_depth;
2191       mode_line = - (integer) line;
2192       begin_token_list(output_routine, output_text);
2193       new_save_level(output_group);
2194       normal_paragraph();
2195       scan_left_brace();
2196       return;
2197     }
2198
2199   {
2200     if (link(page_head) != 0)
2201     {
2202       if (link(contrib_head) == 0)
2203         if (nest_ptr == 0)
2204           tail = page_tail;
2205         else
2206           nest[0].tail_field = page_tail;
2207       else
2208         link(page_tail) = link(contrib_head);
2209
2210       link(contrib_head) = link(page_head);
2211       link(page_head) = 0;
2212       page_tail = page_head;
2213     }
2214
2215     ship_out(box(255));
2216     box(255) = 0;
2217   }
2218 }