OSDN Git Service

makefile of clang.
[putex/putex.git] / src / texsourc / tex0.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 #include "texd.h"
20
21 /* sec 0058 */
22 void print_ln (void)
23 {
24   switch (selector)
25   {
26     case term_and_log:
27       show_char('\n');
28       term_offset = 0;
29       putc('\n', log_file);
30       file_offset = 0;
31       break;
32
33     case log_only:
34       putc('\n', log_file);
35       file_offset = 0;
36       break;
37
38     case term_only:
39       show_char('\n');
40       term_offset = 0;
41       break;
42
43     case no_print:
44     case pseudo:
45     case new_string:
46       break;
47
48     default:
49       putc('\n', write_file[selector]);
50       break;
51   }
52 }
53 /* sec 0058 */
54 void print_char_ (ASCII_code s)
55 {
56   if (s == new_line_char)
57     if (selector < pseudo)
58     {
59       print_ln();
60       return;
61     }
62
63   switch (selector)
64   {
65     case term_and_log:
66       show_char(xchr[s]);
67       incr(term_offset);
68       putc(xchr[s], log_file);
69       incr(file_offset);
70
71       if (term_offset == max_print_line)
72       {
73         show_char('\n');
74         term_offset = 0;
75       }
76       
77       if (file_offset == max_print_line)
78       {
79         putc ('\n', log_file);
80         file_offset = 0;
81       }
82
83       break;
84
85     case log_only:
86       putc(xchr[s], log_file);
87       incr(file_offset);
88
89       if (file_offset == max_print_line)
90         print_ln();
91
92       break;
93
94     case term_only:
95       show_char(xchr[s]);
96       incr(term_offset);
97
98       if (term_offset == max_print_line)
99         print_ln();
100
101       break;
102
103     case no_print:
104       break;
105
106     case pseudo:
107       if (tally < trick_count)
108         trick_buf[tally % error_line] = s;
109
110       break;
111
112     case new_string:
113 #ifdef ALLOCATESTRING
114       if (pool_ptr + 1 > current_pool_size)
115         str_pool = realloc_str_pool (increment_pool_size);
116       
117       if (pool_ptr < current_pool_size)
118         append_char(s);
119 #else
120       if (pool_ptr < pool_size)
121         append_char(s);
122 #endif
123       break;
124
125     default:
126       putc(xchr[s], write_file[selector]);
127       break;
128   }
129
130   incr(tally);
131 }
132 /* sec 0059 */
133 void print_ (integer s)
134 {
135   pool_pointer j;
136   integer nl;
137
138   if (s >= str_ptr)
139     s = 259; /* ??? */
140   else
141   {
142     if (s < 256)
143     {
144       if (s < 0)
145         s = 259; /* ??? */
146       else
147       {
148         if (selector > pseudo)
149         {
150           print_char(s);
151           return;
152         }
153
154         if (s == new_line_char)
155           if (selector < pseudo)
156           {
157             print_ln();
158             return;
159           }
160           
161         nl = new_line_char;
162         new_line_char = -1;
163           
164         /* translate ansi to dos 850 */
165         if (!show_in_hex && s < 256 && s >= 32)
166         {
167           if (show_in_dos && s > 127)
168           {
169             if (wintodos[s - 128] > 0)
170             {
171               print_char(wintodos[s - 128]);
172             }
173             else
174             {
175               j = str_start[s];
176
177               while (j < str_start[s + 1])
178               {
179                 print_char(str_pool[j]);
180                 incr(j);
181               }
182             }
183           }
184           else
185           {
186             print_char(s);       /* don't translate to hex */
187           }
188         }
189         else
190         {                       /* not just a character */
191           j = str_start[s];
192
193           while (j < str_start[s + 1])
194           {
195             print_char(str_pool[j]);
196             incr(j);
197           }
198         }
199
200         new_line_char = nl; /* restore eol */
201         return;
202       }
203     }
204   }
205 /*  we get here with s > 256 - i.e. not a single character */
206   j = str_start[s];
207
208   while (j < str_start[s + 1])
209   {
210     print_char(str_pool[j]);
211     incr(j);
212   }
213 }
214 /* string version print. */
215 void prints_ (const char *s)
216 {
217   while (*s > 0)
218     print_char(*s++);
219 }
220 /* sec 0060 */
221 void slow_print_ (integer s)
222 {
223   pool_pointer j;
224
225   if ((s >= str_ptr) || (s < 256))
226     print(s);
227   else
228   {
229     j = str_start[s];
230
231     while (j < str_start[s + 1])
232     {
233       print(str_pool[j]);
234       incr(j);
235     }
236   }
237 }
238 /* sec 0062 */
239 void print_nl (const char * s)
240 {
241   if (((term_offset > 0) && (odd(selector))) ||
242       ((file_offset > 0) && (selector >= log_only)))
243     print_ln();
244
245   prints(s);
246 }
247 /* sec 0063 */
248 void print_esc (const char * s)
249 {
250   integer c;
251
252   c = escape_char;
253
254   if (c >= 0)
255     if (c < 256)
256       print(c);
257
258   prints(s);
259 }
260 /* sec 0064 */
261 void print_the_digs_ (eight_bits k)
262 {
263   while (k > 0)
264   {
265     decr(k);
266
267     if (dig[k] < 10)
268       print_char('0' + dig[k]);
269     else
270       print_char('A' + dig[k]);
271   }
272 }
273 /* sec 0065 */
274 void print_int_ (integer n)
275 {
276   char k;
277   integer m;
278
279   k = 0;
280
281   if (n < 0)
282   {
283     print_char('-');
284
285     if (n > -100000000L)
286       n = - (integer) n;
287     else
288     {
289       m = -1 - n;
290       n = m / 10;
291       m = (m % 10) + 1;
292       k = 1;
293
294       if (m < 10)
295         dig[0] = (char) m;
296       else
297       {
298         dig[0] = 0;
299         incr(n);
300       }
301     }
302   }
303
304   do
305     {
306       dig[k] = (char) (n % 10);
307       n = n / 10;
308       incr(k);
309     }
310   while (!(n == 0));
311
312   print_the_digs(k);
313 }
314 /* sec 0262 */
315 void print_cs_ (integer p)
316 {
317   if (p < hash_base)
318     if (p >= single_base)
319       if (p == null_cs)
320       {
321         print_esc("csname");
322         print_esc("endcsname");
323         print_char(' ');
324       }
325       else
326       {
327         print_esc(""); print(p - single_base);
328
329         if (cat_code(p - single_base) == letter)
330           print_char(' ');
331       }
332     else if (p < active_base)
333       print_esc("IMPOSSIBLE.");
334     else
335       print(p - active_base);
336   else if (p >= undefined_control_sequence)
337     print_esc("IMPOSSIBLE.");
338   else if ((text(p) >= str_ptr))
339     print_esc("NONEXISTENT.");
340   else
341   {
342     print_esc("");
343     print(text(p));
344     print_char(' ');
345   }
346 }
347 /* sec 0263 */
348 void sprint_cs_(halfword p)
349
350   if (p < hash_base)
351     if (p < single_base)
352       print(p - active_base);
353     else if (p < null_cs)
354     {
355       print_esc("");
356       print(p - single_base);
357     }
358     else
359     {
360       print_esc("csname");
361       print_esc("endcsname");
362     }
363   else
364   {
365     print_esc(""); print(text(p));
366   }
367 }
368 /* sec 0518 */
369 void print_file_name_(integer n, integer a, integer e)
370 {
371   slow_print(a);
372   slow_print(n);
373   slow_print(e);
374 }
375 /* sec 0699 */
376 void print_size_ (integer s)
377
378   if (s == 0)
379     print_esc("textfont");
380   else if (s == 16)
381     print_esc("scriptfont");
382   else
383     print_esc("scriptscriptfont");
384
385 /* sec 1355 */
386 void print_write_whatsit_(str_number s, pointer p)
387 {
388   print_esc("");
389   print(s);
390
391   if (write_stream(p) < 16)
392     print_int(write_stream(p)); 
393   else if (write_stream(p) == 16)
394     print_char('*');
395   else print_char('-');
396 }
397 /* sec 0081 */
398 void jump_out (void) 
399 {
400   close_files_and_terminate();
401
402   {
403     int code;
404
405 #ifndef _WINDOWS
406     fflush(stdout); 
407 #endif
408
409     ready_already = 0;
410
411     if (trace_flag)
412       puts("EXITING at JUMPOUT");
413
414     if ((history != 0) && (history != 1))
415       code = 1;
416     else
417       code = 0;
418
419     uexit(code);
420   }
421 }
422 /* sec 0082 */
423 // deal with error by asking for user response 0-9, D, E, H, I, X, Q, R, S
424 // NOTE: this may JUMPOUT either via X, or because of too many errors
425 void error (void)
426 {
427   ASCII_code c;
428   integer s1, s2, s3, s4;
429
430   if (history < error_message_issued)
431     history = error_message_issued;
432
433   print_char('.');
434   show_context();
435
436   if (interaction == error_stop_mode)
437     while (true)
438     {
439 continu:
440       clear_for_error_prompt();
441       prompt_input("? ");
442
443       if (last == first)
444         return; // no input
445
446       c = buffer[first];
447
448       if (c >= 'a')
449         c = (c + 'A' - 'a'); 
450
451       switch (c)
452       {
453         case '0':
454         case '1':
455         case '2':
456         case '3':
457         case '4':
458         case '5':
459         case '6':
460         case '7':
461         case '8':
462         case '9':
463           if (deletions_allowed)
464           {
465             s1 = cur_tok;
466             s2 = cur_cmd;
467             s3 = cur_chr;
468             s4 = align_state;
469             align_state = 1000000L;
470             OK_to_interrupt = false;
471
472             if ((last > first + 1) && (buffer[first + 1] >= '0') && (buffer[first + 1] <= '9'))
473               c = (c * 10 + buffer[first + 1] - '0' * 11);
474             else
475               c = (c - 48);
476             
477             while (c > 0)
478             {
479               get_token();
480               decr(c);
481             }
482
483             cur_tok = s1;
484             cur_cmd = s2;
485             cur_chr = s3;
486             align_state = s4;
487             OK_to_interrupt = true;
488             help2("I have just deleted some text, as you asked.",
489                 "You can now delete more, or insert, or whatever.");
490             show_context();
491             goto continu;
492           }
493           break;
494
495 #ifdef DEBUG
496         case 'D':
497           {
498             debug_help();
499             goto continu;
500           }
501           break;
502 #endif
503
504         case 'E':
505           if (base_ptr > 0)
506           {
507             edit_name_start = str_start[input_stack[base_ptr].name_field];
508             edit_name_length = length(input_stack[base_ptr].name_field);
509             edit_line = line;
510             jump_out();
511           }
512           break;
513
514         case 'H':
515           {
516             if (use_err_help)
517             {
518               give_err_help();
519               use_err_help = false;
520             }
521             else
522             {
523               if (help_ptr == 0)
524                 help2("Sorry, I don't know how to help in this situation.",
525                     "Maybe you should try asking a human?");
526               do
527                 {
528                   decr(help_ptr);
529                   prints(help_line[help_ptr]);
530                   print_ln();
531                 }
532               while (!(help_ptr == 0));
533             }
534
535             help4("Sorry, I already gave what help I could...",
536                 "Maybe you should try asking a human?",
537                 "An error might have occurred before I noticed any problems.",
538                 "``If all else fails, read the instructions.''");
539             goto continu;
540           }
541           break;
542
543         case 'I':
544           {
545             begin_file_reading();
546
547             if (last > first + 1)
548             {
549               loc = first + 1;
550               buffer[first] = 32;
551             }
552             else
553             {
554               prompt_input("insert>");
555               loc = first;
556             }
557
558             first = last;
559             limit = last - 1;
560
561             return;
562           }
563           break;
564
565         case 'Q':
566         case 'R':
567         case 'S':
568           {
569             error_count = 0; 
570             interaction = 0 + c - 81; /* Q = 0, R = 1, S = 2, T = 3 */
571             prints("OK, entering ");
572
573             switch (c)
574             {
575               case 'Q':
576                 print_esc("batchmode");
577                 decr(selector);
578                 break;
579
580               case 'R':
581                 print_esc("nonstopmode");
582                 break;
583
584               case 'S':
585                 print_esc("scrollmode");
586                 break;
587             }
588
589             prints("...");
590             print_ln();
591             update_terminal();
592             return;
593           }
594           break;
595
596         case 'X':
597           {
598             interaction = 2;
599             jump_out();
600           }
601           break;
602
603         default:
604           break;
605       }           /* end of switch analysing response character */
606
607       {
608         prints("Type <return> to proceed, S to scroll future error messages,");
609         print_nl("R to run without stopping, Q to run quietly,");
610         print_nl("I to insert something, ");
611
612         if (base_ptr > 0)
613           prints("E to edit your file,");
614
615         if (deletions_allowed)
616           print_nl("1 or ... or 9 to ignore the next 1 to 9 tokens of input,");
617
618         print_nl("H for help, X to quit.");
619       }
620     }
621
622   incr(error_count);
623
624   if (error_count == 100)
625   {
626     print_nl("(That makes 100 errors; please try again.)");
627     history = 3;
628     jump_out();
629   }
630
631   if (interaction > batch_mode)
632     decr(selector);
633
634   if (use_err_help)
635   {
636     print_ln();
637     give_err_help();
638   }
639   else while (help_ptr > 0)
640   {
641     decr(help_ptr);
642     print_nl(help_line[help_ptr] == NULL ? "" : help_line[help_ptr]);
643   }
644
645   print_ln();
646
647   if (interaction > batch_mode)
648     incr(selector);
649   
650   print_ln();
651 }
652 /* sec 0093 */
653 void fatal_error(char * s)
654 {
655   normalize_selector();
656   print_err("Emergency stop");
657   help1(s);
658   succumb();
659 }
660 /* sec 0094 */
661 void overflow_(char * s, integer n)
662 {
663   normalize_selector();
664   print_err("TeX capacity exceeded, sorry [");
665   prints(s);
666   print_char('=');
667   print_int(n);
668   print_char(']');
669   help2("If you really absolutely need more capacity,",
670       "you can ask a wizard to enlarge me.");
671
672   if (!knuth_flag)
673   {
674     if (!strcmp(s, "pattern memory") && (n == trie_size))
675     {
676       sprintf(log_line, "\n  (Maybe use -h=... on command line in ini-TeX)\n");
677       show_line(log_line, 0);
678     }
679     else if (!strcmp(s, "exception dictionary") && (n == hyphen_prime))
680     {
681       sprintf(log_line, "\n  (Maybe use -e=... on command line in ini-TeX)\n");
682       show_line(log_line, 0);
683     }
684   }
685
686   succumb();
687 }
688 /* sec 0095 */
689 void confusion_(const char * s)
690 {
691   normalize_selector();
692
693   if (history < error_message_issued)
694   {
695     print_err("This can't happen (");
696     prints(s);
697     print_char(')');
698     help1("I'm broken. Please show this to someone who can fix can fix");
699   }
700   else
701   {
702     print_err("I can't go on meeting you like this");
703     help2("One of your faux pas seems to have wounded me deeply...",
704         "in fact, I'm barely conscious. Please fix it and try again.");
705   }
706
707   succumb();
708 }
709 /* sec 0037 */
710 boolean init_terminal (void)
711 {
712   int flag;
713
714   t_open_in();
715
716   if (last > first)
717   {
718     loc = first;
719
720     while ((loc < last) && (buffer[loc]== ' '))
721       incr(loc);    // step over initial white space
722
723     if (loc < last)
724       return true;
725   }
726
727 // failed to find input file name
728   while (true)
729   {
730     fputs("**", stdout);
731     update_terminal();
732     flag = input_ln(stdin, true);
733
734     if (!flag)
735     {
736       show_char('\n');
737       puts("! End of file on the terminal... why?\n");
738       return false;
739     }
740
741     loc = first;
742
743     while ((loc < last) && (buffer[loc]== ' '))
744       incr(loc);    // step over intial white space
745
746     if (loc < last)
747       return true;
748
749     sprintf(log_line, "%s\n", "Please type the name of your input file.");
750     show_line(log_line, 1);
751   }
752 }
753 /* sec 0043 */
754 str_number make_string (void)
755 {
756 #ifdef ALLOCATESTRING
757   if (str_ptr == current_max_strings)
758     str_start = realloc_str_start(increment_max_strings);
759
760   if (str_ptr == current_max_strings)
761   {
762     overflow("number of strings", current_max_strings - init_str_ptr); /* 97/Mar/9 */
763     return 0;
764   }
765 #else
766   if (str_ptr == max_strings)
767   {
768     overflow("number of strings", max_strings - init_str_ptr);
769     return 0;
770   }
771 #endif
772
773   incr(str_ptr);
774   str_start[str_ptr] = pool_ptr;
775
776   return (str_ptr - 1);
777 }
778 /* sec 0044 */
779 boolean str_eq_buf_ (str_number s, integer k)
780 {
781   pool_pointer j;
782   boolean result;
783
784   j = str_start[s];
785
786   while (j < str_start[s + 1])
787   {
788     if (str_pool[j] != buffer[k])
789     {
790       result = false;
791       goto not_found;
792     }
793
794     incr(j);
795     incr(k);
796   }
797
798   result = true;
799
800 not_found:
801   return result;
802 }
803 /* sec 0045 */
804 boolean str_eq_str_ (str_number s, str_number t)
805 {
806   pool_pointer j, k;
807   boolean result;
808
809   result = false;
810
811   if (length(s) != length(t))
812     goto not_found;
813
814   j = str_start[s];
815   k = str_start[t];
816
817   while (j < str_start[s + 1])
818   {
819     if (str_pool[j] != str_pool[k])
820       goto not_found;
821
822     incr(j);
823     incr(k);
824   }
825
826   result = true;
827
828 not_found:
829   return result;
830 }
831 /* sec 0066 */
832 void print_two_(integer n)
833
834   n = abs(n) % 100;
835   print_char('0' + (n / 10));
836   print_char('0' + (n % 10));
837
838 /* sec 0067 */
839 void print_hex_(integer n)
840 {
841   char k;
842
843   k = 0;
844   print_char('"');
845
846   do
847     {
848       dig[k] = (unsigned char) (n % 16);
849       n = n / 16;
850       incr(k);
851     }
852   while (!(n == 0));
853
854   print_the_digs(k);
855 }
856 /* sec 0069 */
857 void print_roman_int_(integer n)
858 {
859   pool_pointer j, k;
860   nonnegative_integer u, v;
861
862   j = str_start[260]; /*  m2d5c2l5x2v5i */
863   v = 1000;
864
865   while (true)
866   {
867     while (n >= v)
868     {
869       print_char(str_pool[j]);
870       n = n - v;
871     }
872
873     if (n <= 0)
874       return;
875
876     k = j + 2;
877     u = v / (str_pool[k - 1] - '0');
878
879     if (str_pool[k - 1] == 50)
880     {
881       k = k + 2;
882       u = u / (str_pool[k - 1] - '0');
883     }
884
885     if (n + u >= v)
886     {
887       print_char(str_pool[k]);
888       n = n + u;
889     }
890     else
891     {
892       j = j + 2;
893       v = v / (str_pool[j - 1] - '0');
894     }
895   }
896 }
897 /* sec 0070 */
898 void print_current_string (void)
899 {
900   pool_pointer j;
901
902   j = str_start[str_ptr];
903
904   while (j < pool_ptr)
905   {
906     print_char(str_pool[j]);
907     incr(j);
908   }
909 }
910
911 /* sec 0071 */
912 void term_input(void)
913
914   integer k;
915   int flag;
916   
917   if (!knuth_flag)
918     show_line("\n", 0);
919
920   update_terminal();
921   flag = input_ln(stdin, true);
922
923   if (!flag)
924   {
925     fatal_error("End of file on the terminal!");
926     return;
927   }
928
929   term_offset = 0;
930   decr(selector);     // shut off echo
931
932   if (last != first)
933     for (k = first; k <= last - 1; k++)
934       print(buffer[k]);
935
936   print_ln();
937   incr(selector);     // reset selector again
938 }
939 /* sec 0091 */
940 void int_error_ (integer n)
941 {
942   prints(" (");
943   print_int(n);
944   print_char(')');
945   error();
946 }
947 /* sec 0092 */
948 void normalize_selector (void)
949 {
950   if (log_opened)
951     selector = term_and_log;
952   else
953     selector = term_only;
954
955   if (job_name == 0)
956     open_log_file();
957
958   if (interaction == batch_mode)
959     decr(selector);
960 }
961 /* sec 0098 */
962 void pause_for_instructions (void)
963 {
964    if (OK_to_interrupt)
965    {
966     interaction = error_stop_mode;
967
968     if ((selector == log_only) || (selector == no_print))
969       incr(selector);
970
971     print_err("Interruption");
972     help3("You rang?",
973         "Try to insert some instructions for me (e.g.,`I\\showlists'),",
974         "unless you just want to quit by typing `X'.");
975     deletions_allowed = false;
976     error();
977     deletions_allowed = true;
978     interrupt = 0;
979   }
980 }
981 /* sec 0100 */
982 integer half_(integer x)
983 {
984   if (odd(x))
985     return ((x + 1) / 2);
986   else
987     return (x / 2);
988 }
989 /* sec 0102 */
990 scaled round_decimals_(small_number k)
991 {
992   integer a;
993
994   a = 0;
995
996   while (k > 0)
997   {
998     decr(k);
999     a = (a + dig[k] * 131072L) / 10; /* 2^17 */
1000   }
1001   
1002   return ((a + 1) / 2);
1003 }
1004 /* sec 0103 */
1005 void print_scaled_(scaled s)
1006 {
1007   scaled delta;
1008
1009   if (s < 0)
1010   {
1011     print_char('-');
1012     s = - (integer) s;
1013   }
1014
1015   print_int(s / 65536L);
1016   print_char('.');
1017   s = 10 * (s % 65536L) + 5;
1018   delta = 10;
1019
1020   do
1021     {
1022       if (delta > 65536L)
1023         s = s - 17232; /* 2^15 - 50000 - rounding */
1024
1025       print_char('0' + (s / 65536L));
1026       s = 10 * (s % 65536L);
1027       delta = delta * 10;
1028     }
1029   while (!(s <= delta));
1030 }
1031 /* sec 0105 */
1032 scaled mult_and_add_(integer n, scaled x, scaled y, scaled maxanswer)
1033 {
1034   if (n < 0)
1035   {
1036     x = - (integer) x;
1037     n = - (integer) n;
1038   }
1039
1040   if (n == 0)
1041     return y;
1042   else if (((x <= (maxanswer - y) / n) && (- (integer) x <= (maxanswer + y) / n)))
1043     return (n * x + y); 
1044   else
1045   {
1046     arith_error = true;
1047     return 0;
1048   }
1049 }
1050 /* sec 0106 */
1051 scaled x_over_n_(scaled x, integer n)
1052 {
1053   register scaled Result;
1054   boolean negative;
1055
1056   negative = false;
1057
1058   if (n == 0)
1059   {
1060     arith_error = true;
1061     Result = 0;
1062     tex_remainder = x;
1063   }
1064   else
1065   {
1066     if (n < 0)
1067     {
1068       x = - (integer) x;
1069       n = - (integer) n;
1070       negative = true;
1071     }
1072
1073     if (x >= 0)
1074     {
1075       Result = x / n;
1076       tex_remainder = x % n;
1077     }
1078     else
1079     {
1080       Result = - (integer) ((- (integer) x)/ n);
1081       tex_remainder = - (integer) ((- (integer) x)% n);
1082     }
1083   }
1084
1085   if (negative)
1086     tex_remainder = - (integer) tex_remainder;
1087
1088   return Result;
1089 }
1090 /* sec 0107 */
1091 scaled xn_over_d_(scaled x, integer n, integer d)
1092 {
1093   register scaled Result;
1094   boolean positive;
1095   nonnegative_integer t, u, v;
1096
1097   if (x >= 0)
1098     positive = true; 
1099   else
1100   {
1101     x = - (integer) x;
1102     positive = false;
1103   }
1104
1105   t = (x % 32767L) * n;
1106   u = (x / 32768L) * n + (t / 32768L);
1107   v = (u % d) * 32768L + (t % 32768L); 
1108
1109   if (u / d >= 32768L)
1110     arith_error = true; 
1111   else
1112     u = 32768L * (u / d) + (v / d);
1113
1114   if (positive)
1115   {
1116     Result = u;
1117     tex_remainder = v % d;
1118   }
1119   else
1120   {
1121     Result = - (integer) u;
1122     tex_remainder = - (integer)(v % d);
1123   }
1124
1125   return Result;
1126 }
1127 /* sec 0108 */
1128 halfword badness_(scaled t, scaled s)
1129 {
1130   integer r;
1131
1132   if (t == 0)
1133     return 0;
1134   else if (s <= 0)
1135     return 10000;
1136   else
1137   {
1138     if (t <= 7230584L)
1139       r = (t * 297) / s;
1140     else if (s >= 1663497L)
1141       r = t / (s / 297);
1142     else
1143       r = t;
1144
1145     if (r > 1290)
1146       return 10000; 
1147     else
1148       return (r * r * r + 131072L) / 262144L;  /* 2^17 */
1149   }
1150 }
1151 /* sec 0114 */
1152 #ifdef DEBUG
1153 void print_word_(memory_word w)
1154
1155   print_int(w.cint); 
1156   print_char(' ');
1157   print_scaled(w.cint); 
1158   print_char(' ');
1159   print_scaled(round(65536L * w.gr));
1160   print_ln();
1161   print_int(w.hh.lh);
1162   print_char('=');
1163   print_int(w.hh.b0);
1164   print_char(':');
1165   print_int(w.hh.b1);
1166   print_char(';');
1167   print_int(w.hh.rh);
1168   print_char(' ');
1169   print_int(w.qqqq.b0); 
1170   print_char(':');
1171   print_int(w.qqqq.b1); 
1172   print_char(':');
1173   print_int(w.qqqq.b2); 
1174   print_char(':');
1175   print_int(w.qqqq.b3);
1176
1177 /* need this version only if SHORTFONTINFO defined */
1178 void zprintfword(memory_word w)
1179 {
1180   print_int(w.cint);
1181   print_char(' ');
1182   print_scaled(w.cint);
1183   print_char(' ');
1184   print_scaled(round(65536L * w.gr));
1185   print_ln();
1186   print_int(w.hh.lh);
1187   print_char('=');
1188   print_int(w.hh.b0);
1189   print_char(':');
1190   print_int(w .hh.b1);
1191   print_char(';');
1192   print_int(w.hh.rh);
1193   print_char(' ');
1194   print_int(w.qqqq.b0);
1195   print_char(':');
1196   print_int(w.qqqq.b1);
1197   print_char(':');
1198   print_int(w.qqqq.b2);
1199   print_char(':');
1200   print_int(w.qqqq.b3);
1201 }
1202 #endif
1203 /* sec 0292 */
1204 void show_token_list_(integer p, integer q, integer l)
1205 {
1206   integer m, c;
1207   ASCII_code match_chr;
1208   ASCII_code n;
1209
1210   match_chr = '#';
1211   n = '0';
1212   tally = 0;
1213
1214   while ((p != 0) && (tally < l))
1215   {
1216     if (p == q)
1217     {
1218       first_count = tally;
1219       trick_count = tally + 1 + error_line - half_error_line;
1220
1221       if (trick_count < error_line)
1222         trick_count = error_line;
1223     }
1224
1225     if ((p < hi_mem_min) || (p > mem_end))
1226     {
1227       print_esc("CLOBBERED.");
1228       return;
1229     }
1230
1231     if (info(p) >= cs_token_flag)
1232       print_cs(info(p) - cs_token_flag);
1233     else
1234     {
1235       m = info(p) / 256;
1236       c = info(p) % 256;
1237
1238       if (info(p) < 0)
1239         print_esc("BAD.");
1240       else switch (m)
1241       {
1242         case left_brace:
1243         case right_brace:
1244         case math_shift:
1245         case tab_mark:
1246         case sup_mark:
1247         case sub_mark:
1248         case spacer:
1249         case letter:
1250         case other_char:
1251           print(c);
1252           break;
1253         
1254         case mac_param:
1255           print(c);
1256           print(c);
1257           break;
1258         
1259         case out_param:
1260           print(match_chr);
1261           
1262           if (c <= 9)
1263             print_char(c + '0');
1264           else
1265           {
1266             print_char('!');
1267             return;
1268           }
1269           break;
1270         
1271         case match:
1272           match_chr = (ASCII_code) c;
1273           print(c);
1274           incr(n);
1275           print_char(n);
1276           
1277           if (n > '9')
1278             return;
1279           break;
1280         
1281         case end_match:
1282           prints("->");
1283           break;
1284         
1285         default:
1286           print_esc("BAD.");
1287           break;
1288       }
1289     }
1290     p = link(p);
1291   }
1292
1293   if (p != 0)
1294     print_esc("ETC.");
1295 }
1296 /* sec 0306 */
1297 void runaway (void)
1298 {
1299   halfword p;
1300
1301   if (scanner_status > 1)
1302   {
1303     print_nl("Runaway ");
1304
1305     switch (scanner_status)
1306     {
1307       case defining:
1308         prints("definition");
1309         p = def_ref;
1310         break;
1311
1312       case matching:
1313         prints("argument");
1314         p = temp_head;
1315         break;
1316
1317       case aligning:
1318         prints("preamble");
1319         p = hold_head;
1320         break;
1321
1322       case absorbing:
1323         prints("text");
1324         p = def_ref;
1325         break;
1326     }
1327
1328     print_char('?');
1329     print_ln();
1330     show_token_list(link(p), 0, error_line - 10); 
1331   }
1332 }
1333 /* sec 0120 */
1334 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1335 /* first try list of available nodes (avail != NULL)                   */
1336 /* then see if can go upwards (mem_end < mem_max)                      */
1337 /* then see if can go downwards (hi_mem_min > lo_mem_max)              */
1338 /* if not, extend memory at the top and grab from there --- new        */
1339 /* else fail ! paragraph 120                                           */
1340 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1341 halfword get_avail (void)
1342 {
1343   pointer p;
1344
1345   p = avail;
1346
1347   if (p != 0)
1348     avail = link(avail);
1349   else if (mem_end < mem_max)
1350   {
1351     incr(mem_end);
1352     p = mem_end;
1353   }
1354   else
1355   {
1356     decr(hi_mem_min);
1357     p = hi_mem_min;
1358
1359     if (hi_mem_min <= lo_mem_max) /* have we run out in middle ? */
1360     {
1361       incr(hi_mem_min);
1362       mem = realloc_main (0, mem_top / 2);  /* zzzaa = zmem = mem */
1363
1364       if (mem == NULL)
1365         return 0;
1366
1367       if (mem_end >= mem_max)
1368       {
1369         runaway();
1370         overflow("main memory size", mem_max + 1 - mem_min);
1371         return 0;
1372       }
1373
1374       incr(mem_end);        /* then grab from new area */
1375       p = mem_end;          /* 1993/Dec/14 */
1376     }
1377   }
1378
1379   link(p) = 0;       /* link(p) = null !!! */
1380
1381 #ifdef STAT
1382   incr(dyn_used); 
1383 #endif /* STAT */
1384
1385   return p; 
1386
1387 /* sec 0123 */
1388 void flush_list_(pointer p)
1389
1390   pointer q, r;
1391
1392   if (p != 0)              /* null !!! */
1393   {
1394     r = p;
1395
1396     do
1397       {
1398         q = r;
1399         r = link(r);
1400 #ifdef STAT
1401         decr(dyn_used);
1402 #endif /* STAT */
1403       }
1404     while (!(r == 0));     /* r != null */
1405
1406     link(q) = avail;
1407     avail = p;
1408   }
1409 }
1410 /* sec 0125 */
1411 pointer get_node_(integer s)
1412 {
1413   pointer p;
1414   pointer q;
1415   integer r;
1416   integer t;
1417 restart:
1418
1419   p = rover;
1420
1421   do
1422     {
1423       q = p + node_size(p);
1424
1425       while (is_empty(q))
1426       {
1427         t = rlink(q);
1428
1429         if (q == rover)
1430           rover = t;
1431
1432         llink(t) = llink(q);
1433         rlink(llink(q)) = t;
1434         q = q + node_size(q);
1435       }
1436
1437       r = q - s;
1438
1439       if (r > toint(p + 1)) 
1440       {
1441         node_size(p) = r - p;
1442         rover = p;
1443         goto found;
1444       }
1445
1446       if (r == p)
1447         if (rlink(p) != p)
1448         {
1449           rover = rlink(p);
1450           t = llink(p);
1451           llink(rover) = t;
1452           rlink(t) = rover;
1453           goto found;
1454         }
1455
1456       node_size(p) = q - p;
1457       p = rlink(p);
1458     }
1459   while (!(p == rover));
1460
1461   if (s == 1073741824L)    /* 2^30 - special case - merge adjacent */
1462   {
1463     if (trace_flag)
1464       puts("Merged adjacent multi-word nodes\n");
1465
1466     return max_halfword;
1467   }
1468
1469 /*  maybe try downward epxansion first instead ? */
1470   if (lo_mem_max + 2 < hi_mem_min)
1471     if (lo_mem_max + 2 <= mem_bot + max_halfword)  /* silly ? flush 93/Dec/16 */
1472     {
1473       /* if (hi_mem_min - lo_mem_max >= 1998) */
1474       if (hi_mem_min - lo_mem_max >= (block_size + block_size - 2))
1475         /* t = lo_mem_max + 1000; */
1476         t = lo_mem_max + block_size;
1477       else
1478         t = lo_mem_max + 1 + (hi_mem_min - lo_mem_max) / 2;
1479
1480       p = llink(rover);
1481       q = lo_mem_max;
1482       rlink(p) = q;
1483       llink(rover) = q;
1484
1485       if (t > mem_bot + max_halfword)
1486         t = mem_bot + max_halfword;     /* silly ? flush 93/Dec/16 */
1487
1488       rlink(q) = rover;
1489       llink(q) = p;
1490       link(q) = empty_flag;
1491       node_size(q) = t - lo_mem_max; /* block size */
1492       lo_mem_max = t;
1493       link(lo_mem_max) = 0;
1494       info(lo_mem_max) = 0;
1495       rover = q;
1496       goto restart;
1497     }
1498
1499 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1500 /* we've run out of space in the middle for variable length blocks */
1501 /* try and add new block from below mem_bot *//* first check if space ! */
1502   if (mem_min - (block_size + 1) <= mem_start) /* extend lower memory downwards */
1503   {
1504     mem = realloc_main (mem_top/2 + block_size, 0);  /* zzzaa = zmem = mem */
1505
1506     if (mem == NULL)
1507     {
1508       return 0;
1509     }
1510   }
1511
1512   if (mem_min - (block_size + 1) <= mem_start) /* check again */
1513   {
1514     if (trace_flag)
1515     {
1516       sprintf(log_line, "mem_min %lld, mem_start %ld, block_size %d\n", mem_min, mem_start, block_size);
1517       show_line(log_line, 0);
1518     }
1519
1520     overflow("main memory size", mem_max + 1 - mem_min); /* darn: allocation failed ! */
1521     return 0;
1522   }
1523
1524   add_variable_space (block_size);
1525   goto restart; /* go try get_node again */
1526
1527 found:
1528   link(r) = 0;
1529
1530 #ifdef STAT
1531   var_used = var_used + s; 
1532 #endif /* STAT */
1533
1534   return r; 
1535
1536 /* sec 0130 */
1537 void free_node_(halfword p, halfword s)
1538
1539   pointer q;
1540
1541   node_size(p) = s;
1542   link(p) = empty_flag;
1543   q = llink(rover);
1544   llink(p) = q;
1545   rlink(p) = rover;
1546   llink(rover) = p;
1547   rlink(q) = p;
1548
1549 #ifdef STAT
1550   var_used = var_used - s; 
1551 #endif /* STAT */
1552 }
1553 /* sec 0136 */
1554 pointer new_null_box (void) 
1555 {
1556   pointer p;
1557
1558   p = get_node(box_node_size);
1559   type(p) = hlist_node;
1560   subtype(p) = min_quarterword;
1561   width(p) = 0;
1562   depth(p) = 0;
1563   height(p) = 0;
1564   shift_amount(p) = 0;
1565   list_ptr(p) = 0;
1566   glue_sign(p) = normal;
1567   glue_order(p) = normal;
1568   glue_set(p) = 0.0;
1569
1570   return p;
1571 }
1572 /* sec 0139 */
1573 pointer new_rule (void) 
1574 {
1575   pointer p;
1576
1577   p = get_node(rule_node_size);
1578   type(p) = rule_node;
1579   subtype(p) = 0;
1580   width(p) = null_flag;
1581   depth(p) = null_flag;
1582   height(p) = null_flag;
1583
1584   return p;
1585 }
1586 /* sec 0144 */
1587 pointer new_ligature_(quarterword f, quarterword c, pointer q)
1588 {
1589   pointer p;
1590
1591   p = get_node(small_node_size);
1592   type(p) = ligature_node;
1593   font(lig_char(p)) = f;
1594   character(lig_char(p)) = c;
1595   lig_ptr(p) = q;
1596   subtype(p) = 0;
1597
1598   return p;
1599 }
1600 /* sec 0144 */
1601 pointer new_lig_item_(quarterword c)
1602 {
1603   pointer p;
1604
1605   p = get_node(small_node_size);
1606   character(p) = c;
1607   lig_ptr(p) = 0;
1608
1609   return p;
1610 }
1611 /* sec 0145 */
1612 pointer new_disc (void) 
1613 {
1614   pointer p;
1615
1616   p = get_node(small_node_size);
1617   type(p) = disc_node;
1618   replace_count(p) = 0;
1619   pre_break(p) = 0;
1620   post_break(p) = 0;
1621
1622   return p;
1623 }
1624 /* sec 0147 */
1625 pointer new_math_(scaled w, small_number s)
1626 {
1627   pointer p;
1628
1629   p = get_node(small_node_size);
1630   type(p) = math_node;
1631   subtype(p) = s;
1632   width(p) = w;
1633
1634   return p;
1635 }
1636 /* sec 0151 */
1637 pointer new_spec_(pointer p)
1638 {
1639   pointer q;
1640
1641   q = get_node(glue_spec_size);
1642   mem[q] = mem[p];
1643   glue_ref_count(q) = 0;
1644   width(q) = width(p);
1645   stretch(q) = stretch(p);
1646   shrink(q) = shrink(p);
1647
1648   return q;
1649 }
1650 /* se 0152 */
1651 pointer new_param_glue_(small_number n)
1652 {
1653   pointer p;
1654   pointer q;
1655
1656   p = get_node(small_node_size);
1657   type(p) = glue_node;
1658   subtype(p) = n + 1;
1659   leader_ptr(p) = 0;
1660   q = glue_par(n);
1661   glue_ptr(p) = q;
1662   incr(glue_ref_count(q));
1663
1664   return p;
1665 }
1666 /* sec 0153 */
1667 pointer new_glue_(pointer q)
1668 {
1669   pointer p;
1670
1671   p = get_node(small_node_size);
1672   type(p) = glue_node;
1673   subtype(p) = normal;
1674   leader_ptr(p) = 0; 
1675   glue_ptr(p) = q;
1676   incr(glue_ref_count(q));
1677
1678   return p;
1679 }
1680 /* sec 0154 */
1681 pointer new_skip_param_(small_number n)
1682 {
1683   pointer p;
1684
1685   temp_ptr = new_spec(glue_par(n));
1686   p = new_glue(temp_ptr); 
1687   glue_ref_count(temp_ptr) = 0;
1688   subtype(p) = n + 1;
1689
1690   return p;
1691 }
1692 /* sec 0155 */
1693 pointer new_kern(scaled w)
1694 {
1695   pointer p;
1696
1697   p = get_node(small_node_size);
1698   type(p) = kern_node;
1699   subtype(p) = normal;
1700   width(p) = w;
1701
1702   return p;
1703 }
1704 /* sec 0158 */
1705 pointer new_penalty(integer m)
1706 {
1707   pointer p;
1708
1709   p = get_node(small_node_size);
1710   type(p) = penalty_node;
1711   subtype(p) = 0;
1712   penalty(p) = m;
1713
1714   return p;
1715 }
1716
1717 #ifdef DEBUG
1718 /* sec 0167 */
1719 void check_mem(boolean printlocs)
1720 {
1721   pointer p, q;
1722   boolean clobbered;
1723
1724   for (p = mem_min; p <= lo_mem_max; p++) freearr[p] = false;
1725   for (p = hi_mem_min; p <= mem_end; p++) freearr[p] = false;
1726   p = avail;
1727   q = 0;
1728   clobbered = false;
1729   while (p != 0) {
1730     if ((p > mem_end) || (p < hi_mem_min))
1731       clobbered = true;
1732     else if (freearr[p])
1733       clobbered = true;
1734
1735     if (clobbered)
1736     {
1737       print_nl("AVAIL list clobbered at ");
1738       print_int(q);
1739       goto done1;
1740     }
1741     freearr[p] = true;
1742     q = p;
1743     p = link(q);
1744   }
1745 done1:;
1746   p = rover;
1747   q = 0;
1748   clobbered = false;
1749   do {
1750       if ((p >= lo_mem_max) || (p < mem_min))
1751         clobbered = true;
1752       else if ((rlink(p) >= lo_mem_max) || (rlink(p) < mem_min))
1753         clobbered = true;
1754       else if (!(is_empty(p)) || (node_size(p) < 2) ||
1755           (p + node_size(p) > lo_mem_max) || (llink(rlink(p)) != p))
1756         clobbered = true;
1757       
1758       if (clobbered)
1759       {
1760         print_nl("Double-AVAIL list clobbered at ");
1761         print_int(q);
1762         goto done2;
1763       }
1764
1765       for (q = p; q <= p + node_size(p) - 1; q++)
1766       {
1767         if (freearr[q])
1768         {
1769           print_nl("Doubly free location at ");
1770           print_int(q);
1771           goto done2;
1772         }
1773         freearr[q]= true;
1774       }
1775       q = p;
1776       p = rlink(p);
1777   } while (!(p == rover));
1778 done2:;
1779   p = mem_min;
1780   while (p <= lo_mem_max) {
1781     if (is_empty(p))
1782     {
1783       print_nl("Bad flag at ");
1784       print_int(p);
1785     }
1786     while ((p <= lo_mem_max) && !freearr[p]) incr(p);
1787     while ((p <= lo_mem_max) && freearr[p]) incr(p);
1788   }
1789
1790   if (printlocs)
1791   {
1792     print_nl("New busy locs:");
1793
1794     for (p = mem_min; p <= lo_mem_max; p++)
1795       if (!freearr[p] && ((p > was_lo_max) || wasfree[p]))
1796       {
1797         print_char(' ');
1798         print_int(p);
1799       }
1800
1801     for (p = hi_mem_min; p <= mem_end; p++)
1802       if (!freearr[p] && ((p < was_hi_min) || (p > was_mem_end) || wasfree[p]))
1803       {
1804         print_char(' ');
1805         print_int(p);
1806       }
1807   }
1808
1809   for (p = mem_min; p <= lo_mem_max; p++) wasfree[p] = freearr[p];
1810   for (p = hi_mem_min; p <= mem_end; p++) wasfree[p] = freearr[p];
1811
1812   was_mem_end = mem_end;
1813   was_lo_max = lo_mem_max;
1814   was_hi_min = hi_mem_min;
1815 }
1816 #endif /* DEBUG */
1817
1818 #ifdef DEBUG
1819 /* sec 0172 */
1820 void search_mem_(halfword p)
1821 {
1822   integer q;
1823
1824   for (q = mem_min; q <= lo_mem_max; q++)
1825   {
1826     if (link(q) == p)
1827     {
1828       print_nl("LINK(");
1829       print_int(q);
1830       print_char(')');
1831     }
1832     if (info(q) == p)
1833     {
1834       print_nl("INFO(");
1835       print_int(q);
1836       print_char(')');
1837     }
1838   }
1839
1840   for (q = hi_mem_min; q <= mem_end; q++)
1841   {
1842     if (link(q) == p)
1843     {
1844       print_nl("LINK(");
1845       print_int(q);
1846       print_char(')');
1847     }
1848     if (info(q) == p)
1849     {
1850       print_nl("INFO(");
1851       print_int(q);
1852       print_char(')');
1853     }
1854   }
1855
1856   for (q = active_base; q <= box_base + 255; q++)
1857     if (equiv(q) == p)
1858     {
1859       print_nl("EQUIV(");
1860       print_int(q);
1861       print_char(')');
1862     }
1863
1864   if (save_ptr > 0)
1865     for (q = 0; q <= save_ptr - 1; q++)
1866     {
1867       if (equiv_field(save_stack[q]) == p)
1868       {
1869         print_nl("SAVE(");
1870         print_int(q);
1871         print_char(')');
1872       }
1873     }
1874
1875   for (q = 0; q <= hyphen_prime; q++)
1876     if (hyph_list[q] == p)
1877     {
1878       print_nl("HYPH(");
1879       print_int(q);
1880       print_char(')');
1881     }
1882 }
1883 #endif /* DEBUG */
1884 /* sec 0174 */
1885 void short_display_(integer p)
1886 {
1887   integer n; 
1888
1889   while (p != 0) /* want p != null here ! */
1890   {
1891      if (is_char_node(p))
1892      {
1893        if (p <= mem_end)
1894        {
1895          if (font(p) != font_in_short_display)
1896          {
1897            if ((font(p) > font_max))
1898              print_char('*');
1899            else
1900            {
1901              print_esc("");
1902              print(font_id_text(font(p)));
1903            }
1904
1905            print_char(' ');
1906            font_in_short_display = font(p);
1907          }
1908          print(character(p));
1909        }
1910      }
1911      else switch (mem[p].hh.b0)
1912      {
1913       case hlist_node:
1914       case vlist_node:
1915       case ins_node:
1916       case whatsit_node:
1917       case mark_node:
1918       case adjust_node:
1919       case unset_node:
1920         prints("[]");
1921         break;
1922       case rule_node:
1923         print_char('|');
1924         break;
1925       case glue_node:
1926         if (glue_ptr(p) != 0)
1927           print_char(' ');
1928         break;
1929       case math_node:
1930         print_char('$');
1931         break;
1932       case ligature_node:
1933         short_display(lig_ptr(p));
1934         break;
1935       case disc_node:
1936         short_display(pre_break(p));
1937         short_display(post_break(p));
1938         n = replace_count(p);
1939
1940         while (n > 0)
1941         {
1942           if (link(p) != 0)
1943             p = link(p);
1944
1945           decr(n);
1946         }
1947         break;
1948       default:
1949         break;
1950     }
1951     p = link(p);
1952   }
1953 }
1954 /* sec 0176 */
1955 void print_font_and_char (integer p)
1956 {
1957   if (p > mem_end)
1958     print_esc("CLOBBERED.");
1959   else
1960   {
1961     if ((font(p) > font_max))
1962       print_char('*');
1963     else
1964     {
1965       print_esc("");
1966       print(font_id_text(font(p)));
1967     }
1968
1969     print_char(' ');
1970     print(character(p));
1971   }
1972 }
1973 /* sec 0176 */
1974 void print_mark_ (integer p)
1975
1976   print_char('{');
1977
1978   if ((p < hi_mem_min) || (p > mem_end))
1979     print_esc("CLOBBERED.");
1980   else
1981     show_token_list(link(p), 0, max_print_line - 10);
1982
1983   print_char('}');
1984 }
1985 /* sec 0176 */
1986 void print_rule_dimen(scaled d)
1987 {
1988   if (is_running(d))
1989     print_char('*');
1990   else
1991     print_scaled(d);
1992 }
1993 /* sec 0177 */
1994 void print_glue_(scaled d, integer order, char * s)
1995 {
1996   print_scaled(d); 
1997
1998   if ((order < normal) || (order > filll))
1999     prints("foul");
2000   else if (order > 0)
2001   {
2002     prints("fil");
2003
2004     while (order > 1)
2005     {
2006       print_char('l');
2007       decr(order);
2008     }
2009   }
2010   else if (*s != '\0')
2011     prints(s);
2012 }
2013 /* sec 0178 */
2014 void print_spec_(integer p, char * s)
2015 {
2016   if ((p < mem_min) || (p >= lo_mem_max)) 
2017     print_char('*');
2018   else
2019   {
2020     print_scaled(width(p));
2021
2022     if (*s != '\0')
2023       prints(s);
2024
2025     if (stretch(p) != 0)
2026     {
2027       prints("plus");
2028       print_glue(stretch(p), stretch_order(p), s);
2029     }
2030
2031     if (shrink(p) != 0)
2032     {
2033       prints("minus");
2034       print_glue(shrink(p), shrink_order(p), s);
2035     }
2036   }
2037 }
2038 /* sec 0691 */
2039 void print_fam_and_char_(halfword p)
2040 {
2041   print_esc("fam");
2042   print_int(fam(p));
2043   print_char(' ');
2044   print(character(p));
2045 }
2046 /* sec 0691 */
2047 void print_delimiter_(halfword p)
2048 {
2049   integer a;
2050
2051   a = small_fam(p) * 256 + small_char(p);
2052   a = a * 0x1000 + large_fam(p) * 256 + large_char(p);
2053
2054   if (a < 0)
2055     print_int(a);
2056   else
2057     print_hex(a);
2058 }
2059 /* sec 0692 */
2060 void print_subsidiary_data_(halfword p, ASCII_code c)
2061 {
2062   if ((pool_ptr - str_start[str_ptr]) >= depth_threshold)
2063   {
2064     if (math_type(p) != 0)
2065       prints(" []");
2066   }
2067   else
2068   {
2069     append_char(c);
2070     temp_ptr = p;
2071
2072     switch (math_type(p))
2073     {
2074       case math_char:
2075         print_ln();
2076         print_current_string();
2077         print_fam_and_char(p);
2078         break;
2079
2080       case sub_box:
2081         show_info();
2082         break;
2083
2084       case sub_mlist:
2085         if (info(p) == 0)
2086         {
2087           print_ln();
2088           print_current_string();
2089           prints("{}");
2090         }
2091         else
2092           show_info();
2093         break;
2094
2095       default:
2096         break;
2097     }
2098
2099     decr(pool_ptr);
2100   }
2101 }
2102 /* sec 0694 */
2103 void print_style_(integer c)
2104 {
2105   switch (c / 2)
2106   {
2107     case 0:
2108       print_esc("displaystyle");
2109       break;
2110     case 1:
2111       print_esc("textstyle");
2112       break;
2113     case 2:
2114       print_esc("scriptstyle");
2115       break;
2116     case 3:
2117       print_esc("scriptscriptstyle");
2118       break;
2119     default:
2120       prints("Unknown style!");
2121       break;
2122   }
2123 }
2124 /* sec 0225 */
2125 void print_skip_param_(integer n)
2126 {
2127   switch(n)
2128   {
2129     case line_skip_code:
2130       print_esc("lineskip");
2131       break;
2132
2133     case baseline_skip_code:
2134       print_esc("baselineskip");
2135       break; 
2136
2137     case par_skip_code:
2138       print_esc("parskip");
2139       break;
2140
2141     case above_display_skip_code:
2142       print_esc("abovedisplayskip");
2143       break;
2144
2145     case below_display_skip_code:
2146       print_esc("belowdisplayskip");
2147       break;
2148
2149     case above_display_short_skip_code:
2150       print_esc("abovedisplayshortskip");
2151       break;
2152
2153     case below_display_short_skip_code:
2154       print_esc("belowdisplayshortskip");
2155       break;
2156
2157     case left_skip_code:
2158       print_esc("leftskip");
2159       break;
2160
2161     case right_skip_code:
2162       print_esc("rightskip");
2163       break;
2164
2165     case top_skip_code:
2166       print_esc("topskip");
2167       break;
2168
2169     case split_top_skip_code:
2170       print_esc("splittopskip");
2171       break;
2172
2173     case tab_skip_code:
2174       print_esc("tabskip");
2175       break;
2176
2177     case space_skip_code:
2178       print_esc("spaceskip");
2179       break;
2180
2181     case xspace_skip_code:
2182       print_esc("xspaceskip");
2183       break;
2184
2185     case par_fill_skip_code:
2186       print_esc("parfillskip");
2187       break;
2188
2189     case thin_mu_skip_code:
2190       print_esc("thinmuskip");
2191       break;
2192
2193     case med_mu_skip_code:
2194       print_esc("medmuskip");
2195       break; 
2196
2197     case thick_mu_skip_code:
2198       print_esc("thickmuskip");
2199       break;
2200
2201     default:
2202       prints("[unknown glue parameter!]");
2203       break;
2204   }
2205 }
2206 /* sec 0182 */
2207 void show_node_list_(integer p)
2208 {
2209   integer n;
2210   real g;
2211
2212   if (cur_length > depth_threshold)
2213   {
2214     if (p != 0)    /* fixed 94/Mar/23 BUG FIX NOTE: still not fixed in 3.14159 ! */
2215       prints(" []");
2216
2217     return; 
2218   }
2219
2220   n = 0; 
2221
2222   while (p != 0) {      /* want p != null - bkph 93/Dec/15 NOTE: still not fixed in 3.14159 ! */
2223     print_ln(); 
2224     print_current_string(); 
2225
2226     if (p > mem_end)
2227     {
2228       prints("Bad link, display aborted.");
2229       return;
2230     }
2231
2232     incr(n);
2233
2234     if (n > breadth_max)
2235     {
2236       prints("etc.");
2237       return;
2238     }
2239
2240     if (is_char_node(p))
2241       print_font_and_char(p);
2242     else switch (type(p))
2243     {
2244       case hlist_node:
2245       case vlist_node:
2246       case unset_node:
2247         {
2248           if (type(p) == hlist_node)
2249             print_esc("h");
2250           else if (type(p) == vlist_node)
2251             print_esc("v");
2252           else print_esc("unset");
2253
2254           prints("box(");
2255           print_scaled(height(p));
2256           print_char('+');
2257           print_scaled(depth(p));
2258           prints(")x");
2259           print_scaled(width(p));
2260
2261           if (type(p) == unset_node)
2262           {
2263             if (span_count(p) != 0)
2264             {
2265               prints(" (");
2266               print_int(span_count(p) + 1);
2267               prints(" columns)");
2268             }
2269
2270             if (glue_stretch(p) != 0)
2271             {
2272               prints(", stretch ");
2273               print_glue(glue_stretch(p), glue_order(p), "");
2274             }
2275
2276             if (glue_shrink(p) != 0)
2277             {
2278               prints(", shrink ");
2279               print_glue(glue_shrink(p), glue_sign(p), "");
2280             }
2281           }
2282           else
2283           {
2284             g = glue_set(p);
2285
2286             if ((g != 0.0) && (glue_sign(p) != 0))
2287             {
2288               prints(", glue set ");
2289
2290               if (glue_sign(p) == shrinking)
2291                 prints("- ");
2292
2293               if (fabs(g)> 20000.0)
2294               {
2295                 if (g > 0.0)
2296                   print_char('>');
2297                 else
2298                   prints("< -");
2299
2300                 print_glue(20000 * unity, glue_order(p), "");
2301               }
2302               else
2303                 print_glue(round(unity * g), glue_order(p), "");
2304             }
2305
2306             if (shift_amount(p) != 0)
2307             {
2308               prints(", shifted ");
2309               print_scaled(shift_amount(p));
2310             }
2311           }
2312
2313           {
2314             {
2315               str_pool[pool_ptr] = 46;
2316               incr(pool_ptr);
2317             }
2318             show_node_list(mem[p + 5].hh.rh);
2319             decr(pool_ptr);
2320           }
2321         }
2322         break;
2323
2324       case rule_node:
2325         {
2326           print_esc("rule(");
2327           print_rule_dimen(height(p));
2328           print_char('+');
2329           print_rule_dimen(depth(p));
2330           prints(")x");
2331           print_rule_dimen(width(p));
2332         }
2333         break;
2334
2335       case ins_node:
2336         {
2337           print_esc("insert");
2338           print_int(subtype(p));
2339           prints(", natural size ");
2340           print_scaled(height(p));
2341           prints("; split(");
2342           print_spec(split_top_ptr(p), "");
2343           print_char(',');
2344           print_scaled(depth(p));
2345           prints("); float cost ");
2346           print_int(float_cost(p));
2347           {
2348             {
2349               str_pool[pool_ptr] = 46;
2350               incr(pool_ptr);
2351             }
2352             show_node_list(mem[p + 4].hh.lh);
2353             decr(pool_ptr);
2354           }
2355         }
2356         break;
2357       case 8:
2358         switch (subtype(p))
2359         {
2360           case open_node:
2361             {
2362               print_write_whatsit(1279, p);   /* debug # (-1 to exit): */
2363               print_char('=');
2364               print_file_name(open_name(p), open_area(p), open_ext(p));
2365             }
2366             break;
2367
2368           case write_node:
2369             {
2370               print_write_whatsit(591, p);  /* write */
2371               print_mark(write_tokens(p));
2372             }
2373             break;
2374
2375           case close_node:
2376             print_write_whatsit(1280, p); /* closeout */
2377             break;
2378
2379           case special_node:
2380             {
2381               print_esc("special");
2382               print_mark(write_tokens(p));
2383             }
2384             break;
2385
2386           case language_node:
2387             {
2388               print_esc("setlanguage");
2389               print_int(what_lang(p));
2390               prints(" (hyphenmin ");
2391               print_int(what_lhm(p));
2392               print_char(',');
2393               print_int(what_rhm(p));
2394               print_char(')');
2395             }
2396             break;
2397
2398           default:
2399             prints("whatsit?");
2400             break;
2401         }
2402         break;
2403
2404       case glue_node:
2405         if (subtype(p) >= a_leaders)
2406         {
2407           print_esc("");
2408
2409           if (subtype(p) == c_leaders)
2410             print_char('c');
2411           else if (subtype(p) == x_leaders)
2412             print_char('x');
2413
2414           prints("leaders ");
2415
2416           print_spec(glue_ptr(p), "");
2417           {
2418             {
2419               str_pool[pool_ptr] = 46;
2420               incr(pool_ptr);
2421             }
2422             show_node_list(mem[p + 1].hh.rh);
2423             decr(pool_ptr);
2424           }
2425         }
2426         else
2427         {
2428           print_esc("glue");
2429
2430           if (subtype(p) != normal)
2431           {
2432             print_char('(');
2433
2434             if (subtype(p) < cond_math_glue)
2435               print_skip_param(subtype(p) - 1);
2436             else if (subtype(p) == cond_math_glue)
2437               print_esc("nonscript");
2438             else print_esc("mskip");
2439
2440             print_char(')');
2441           }
2442
2443           if (subtype(p) != cond_math_glue)
2444           {
2445             print_char(' ');
2446
2447             if (subtype(p) < cond_math_glue)
2448               print_spec(glue_ptr(p), "");
2449             else
2450               print_spec(glue_ptr(p), "mu");
2451           }
2452         }
2453         break;
2454
2455       case kern_node:
2456         if (subtype(p) != mu_glue)
2457         {
2458           print_esc("kern");
2459
2460           if (subtype(p) != normal)
2461             print_char(' ');
2462
2463           print_scaled(width(p));
2464
2465           if (subtype(p) == acc_kern)
2466             prints(" (for accent)");
2467         }
2468         else
2469         {
2470           print_esc("mkern");
2471           print_scaled(width(p));
2472           prints("mu");
2473         }
2474         break;
2475
2476       case math_node:
2477         {
2478           print_esc("math");
2479
2480           if (subtype(p) == before)
2481             prints("on");
2482           else
2483             prints("off");
2484
2485           if (width(p) != 0)
2486           {
2487             prints(", surrounded ");
2488             print_scaled(width(p));
2489           }
2490         }
2491         break;
2492
2493       case ligature_node:
2494         {
2495           print_font_and_char(lig_char(p));
2496           prints("(ligature ");
2497
2498           if (subtype(p) > 1)
2499             print_char('|');
2500
2501           font_in_short_display = font(lig_char(p)); 
2502           short_display(lig_ptr(p));
2503
2504           if (odd(subtype(p)))
2505             print_char('|');
2506
2507           print_char(')');
2508         }
2509         break;
2510
2511       case penalty_node:
2512         {
2513           print_esc("penalty ");
2514           print_int(penalty(p));
2515         }
2516         break;
2517
2518       case disc_node:
2519         {
2520           print_esc("discretionary");
2521
2522           if (replace_count(p) > 0)
2523           {
2524             prints(" replacing ");
2525             print_int(replace_count(p));
2526           }
2527
2528           {
2529             {
2530               str_pool[pool_ptr] = 46;
2531               incr(pool_ptr);
2532             }
2533             show_node_list(mem[p + 1].hh.lh);
2534             decr(pool_ptr);
2535           }
2536           {
2537             str_pool[pool_ptr]= 124;
2538             incr(pool_ptr);
2539           }
2540           show_node_list(mem[p + 1].hh.rh);
2541           decr(pool_ptr);
2542         }
2543         break;
2544
2545       case mark_node:
2546         {
2547           print_esc("mark");
2548           print_mark(mark_ptr(p));
2549         }
2550         break;
2551
2552       case adjust_node:
2553         {
2554           print_esc("vadjust");
2555           {
2556             {
2557               str_pool[pool_ptr] = 46;
2558               incr(pool_ptr);
2559             }
2560             show_node_list(mem[p + 1].cint);
2561             decr(pool_ptr);
2562           }
2563         }
2564         break;
2565
2566       case style_node:
2567         print_style(subtype(p));
2568         break;
2569
2570       case choice_node:
2571         {
2572           print_esc("mathchoice");
2573           append_char('D');
2574           show_node_list(display_mlist(p));
2575           decr(pool_ptr);
2576           append_char('T');
2577           show_node_list(text_mlist(p));
2578           decr(pool_ptr);
2579           append_char('S');
2580           show_node_list(script_mlist(p));
2581           decr(pool_ptr);
2582           append_char('s');
2583           show_node_list(script_script_mlist(p)); 
2584           decr(pool_ptr); 
2585         } 
2586         break;
2587
2588       case ord_noad:
2589       case op_noad:
2590       case bin_noad:
2591       case rel_noad:
2592       case open_noad:
2593       case close_noad:
2594       case punct_noad:
2595       case inner_noad:
2596       case radical_noad:
2597       case over_noad:
2598       case under_noad:
2599       case vcenter_noad:
2600       case accent_noad:
2601       case left_noad:
2602       case right_noad:
2603         {
2604           switch (type(p))
2605           {
2606             case ord_noad:
2607               print_esc("mathord");
2608               break;
2609
2610             case op_noad:
2611               print_esc("mathop");
2612               break;
2613
2614             case bin_noad:
2615               print_esc("mathbin");
2616               break;
2617
2618             case rel_noad:
2619               print_esc("mathrel");
2620               break;
2621
2622             case open_noad:
2623               print_esc("mathopen");
2624               break;
2625
2626             case close_noad:
2627               print_esc("mathclose");
2628               break;
2629
2630             case punct_noad:
2631               print_esc("mathpunct");
2632               break;
2633
2634             case inner_noad:
2635               print_esc("mathinner");
2636               break;
2637
2638             case over_noad:
2639               print_esc("overline");
2640               break;
2641
2642             case under_noad:
2643               print_esc("underline");
2644               break;
2645
2646             case vcenter_noad:
2647               print_esc("vcenter");
2648               break;
2649
2650             case radical_noad:
2651               {
2652                 print_esc("radical");
2653                 print_delimiter(left_delimiter(p));
2654               }
2655               break;
2656
2657             case accent_noad:
2658               {
2659                 print_esc("accent");
2660                 print_fam_and_char(accent_chr(p));
2661               }
2662               break;
2663
2664             case left_noad:
2665               {
2666                 print_esc("left");
2667                 print_delimiter(delimiter(p));
2668               }
2669               break;
2670
2671             case right_noad:
2672               {
2673                 print_esc("right");
2674                 print_delimiter(delimiter(p));
2675               }
2676               break;
2677           }
2678
2679           if (subtype(p) != normal)
2680             if (subtype(p) == limits)
2681               print_esc("limits");
2682             else
2683               print_esc("nolimits");
2684
2685           if (type(p) < left_noad)
2686             print_subsidiary_data(nucleus(p), '.');
2687
2688           print_subsidiary_data(supscr(p), '^');
2689           print_subsidiary_data(subscr(p), '_');
2690         }
2691         break;
2692
2693       case fraction_noad:
2694         {
2695           print_esc("fraction, thickness ");
2696
2697           if (thickness(p) == 1073741824L)  /* 2^30 */
2698             prints("= default");
2699           else
2700             print_scaled(thickness(p));
2701
2702           if ((small_fam(left_delimiter(p)) != 0) || (small_char(left_delimiter(p)) != 0) ||
2703               (large_fam(left_delimiter(p)) != 0) || (large_char(left_delimiter(p)) != 0))
2704           {
2705             prints(", left-delimiter ");
2706             print_delimiter(left_delimiter(p));
2707           }
2708
2709           if ((small_fam(right_delimiter(p)) != 0) || (small_char(right_delimiter(p)) != 0) ||
2710               (large_fam(right_delimiter(p)) != 0) || (large_char(right_delimiter(p)) != 0))
2711           {
2712             prints(", right-delimiter ");
2713             print_delimiter(right_delimiter(p));
2714           }
2715
2716           print_subsidiary_data(numerator(p), '\\');
2717           print_subsidiary_data(denominator(p), '/');
2718         }
2719         break;
2720
2721       default:
2722         prints("Unknown node type!");
2723         break;
2724     }
2725     p = link(p);
2726   }
2727 }