OSDN Git Service

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