OSDN Git Service

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