OSDN Git Service

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