OSDN Git Service

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