OSDN Git Service

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