OSDN Git Service

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