OSDN Git Service

removed c-std.h and dirio.h.
[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   register bool Result;
848   int flag;
849
850   t_open_in();
851
852   if (last > first)
853   {
854     cur_input.loc_field = first;
855
856     while((cur_input.loc_field < last) && (buffer[cur_input.loc_field]== ' '))
857       incr(cur_input.loc_field);    // step over initial white space
858
859     if (cur_input.loc_field < last)
860     {
861       Result = true;
862       return Result;    // there is an input file name
863     }
864   }
865
866 // failed to find input file name
867   while (true)
868   {
869 #ifdef _WINDOWS
870     flag = ConsoleInput("**", "Please type a file name or a control sequence\r\n(or ^z to exit)", (char *) &buffer[first]);
871     last = first + strlen((char *) &buffer[first]); /* -1 ? */
872 //    may need to be more elaborate see input_line in texmf.c
873 #else
874     (void) fputs("**", stdout);
875     fflush(stdout);
876     flag = input_ln(stdin, true);
877 #endif
878
879     if (!flag)
880     {
881       show_char('\n');
882       show_line("! End of file on the terminal... why?\n", 1);
883       Result = false;
884       return Result;
885     }
886
887     cur_input.loc_field = first;
888
889     while ((cur_input.loc_field < last) && (buffer[cur_input.loc_field]== ' '))
890       incr(cur_input.loc_field);    // step over intial white space
891
892     if (cur_input.loc_field < last)
893     {
894       Result = true;
895       return Result;    // there is an input file name
896     }
897
898     sprintf(log_line, "%s\n", "Please type the name of your input file.");
899     show_line(log_line, 1);
900   }
901 }
902 /* sec 0043 */
903 // Make string from str_start[str_ptr] to pool_ptr
904 str_number make_string (void)
905 {
906 #ifdef ALLOCATESTRING
907   if (str_ptr == current_max_strings)
908     str_start = realloc_str_start(increment_max_strings);
909
910   if (str_ptr == current_max_strings)
911   {
912     overflow("number of strings", current_max_strings - init_str_ptr); /* 97/Mar/9 */
913     return 0;     // abort_flag set
914   }
915 #else
916   if (str_ptr == max_strings)
917   {
918     overflow("number of strings", max_strings - init_str_ptr);
919     return 0;     // abort_flag set
920   }
921 #endif
922   incr(str_ptr);
923   str_start[str_ptr] = pool_ptr;
924
925   return (str_ptr - 1);
926 }
927 /* sec 0044 */
928 bool str_eq_buf_ (str_number s, integer k)
929 {
930   register bool Result;
931   pool_pointer j;
932   bool result;
933
934   j = str_start[s];
935
936   while (j < str_start[s + 1])
937   {
938     if (str_pool[j] != buffer[k])
939     {
940       result = false;
941       goto lab45;
942     }
943
944     incr(j);
945     incr(k);
946   }
947   result = true;
948 lab45:
949   Result = result;
950   return Result;
951 }
952 /* sec 0045 */
953 bool str_eq_str_ (str_number s, str_number t)
954 {
955   register bool Result;
956   pool_pointer j, k;
957   bool result;
958
959   result = false;
960
961   if (length(s) != length(t))
962     goto lab45;
963
964   j = str_start[s];
965   k = str_start[t];
966
967   while (j < str_start[s + 1])
968   {
969     if (str_pool[j] != str_pool[k])
970       goto lab45;
971
972     incr(j);
973     incr(k);
974   }
975   result = true;
976 lab45:
977   Result = result;
978   return Result;
979 }
980 /* sec 0066 */
981 void print_two_(integer n)
982
983   n = abs(n) % 100;
984   print_char('0' + (n / 10));
985   print_char('0' + (n % 10));
986
987 /* sec 0067 */
988 void print_hex_(integer n)
989 {
990   char k;
991
992   k = 0;
993   print_char('"');
994
995   do
996     {
997       dig[k] = (unsigned char) (n % 16);
998       n = n / 16;
999       incr(k);
1000     }
1001   while (!(n == 0));
1002
1003   print_the_digs(k);
1004 }
1005 /* sec 0069 */
1006 void print_roman_int_(integer n)
1007 {
1008   pool_pointer j, k;
1009   nonnegative_integer u, v;
1010
1011   j = str_start[260]; /*  m2d5c2l5x2v5i */
1012   v = 1000;
1013
1014   while (true)
1015   {
1016     while (n >= v)
1017     {
1018       print_char(str_pool[j]);
1019       n = n - v;
1020     }
1021
1022     if (n <= 0)
1023       return;
1024
1025     k = j + 2;
1026     u = v / (str_pool[k - 1] - '0');
1027
1028     if (str_pool[k - 1] == 50)
1029     {
1030       k = k + 2;
1031       u = u / (str_pool[k - 1] - '0');
1032     }
1033
1034     if (n + u >= v)
1035     {
1036       print_char(str_pool[k]);
1037       n = n + u;
1038     }
1039     else
1040     {
1041       j = j + 2;
1042       v = v / (str_pool[j - 1] - '0');
1043     }
1044   }
1045 }
1046 /* sec 0070 */
1047 void print_current_string (void)
1048 {
1049   pool_pointer j;
1050
1051   j = str_start[str_ptr];
1052
1053   while (j < pool_ptr)
1054   {
1055     print_char(str_pool[j]);
1056     incr(j);
1057   }
1058 }
1059
1060 int stringlength (int str_ptr)
1061 {
1062   return (str_start[str_ptr + 1] - str_start[str_ptr]) + 2;
1063 }
1064
1065 char * add_string (char *s, char * str_string)
1066 {
1067   int n;
1068
1069   n = strlen(str_string);
1070   memcpy(s, &str_string, n);
1071   s += n;
1072   strcpy(s, "\r\n");
1073   s += 2;
1074   return s;
1075 }
1076
1077 int addextrahelp = 1;
1078
1079 // make one long \r\n separated string out of help lines 
1080 // str_pool is packed_ASCII_code *
1081
1082 char * make_up_help_string (int nhelplines)
1083 {
1084   char * helpstring, *s;
1085   int k, nlen = 0;
1086   
1087 //  get length of help for this specific message
1088   for (k = nhelplines - 1; k >= 0; k--)
1089   {
1090     nlen += strlen(help_line[k]);
1091   }
1092
1093   nlen += 2; // for blank line separator: "\r\n"
1094
1095   if (addextrahelp)
1096   {
1097     nlen += stringlength(265);
1098     nlen += stringlength(266);
1099     nlen += stringlength(267);
1100
1101     if (base_ptr > 0)
1102       nlen += stringlength(268);
1103
1104     if (deletions_allowed)
1105       nlen += stringlength(269);
1106
1107     nlen += stringlength(270);
1108   }
1109
1110   helpstring = (char *) malloc(nlen + 1); // +1 = '\0'
1111   s = helpstring;
1112
1113   for (k = nhelplines-1; k >= 0; k--)
1114   {
1115     s = add_string(s, help_line[k]);
1116   }
1117
1118   if (addextrahelp)
1119   {
1120     strcpy(s, "\r\n");
1121     s += 2;
1122     s = add_string(s, "Type <return> to proceed, S to scroll future error messages,");
1123     s = add_string(s, "R to run without stopping, Q to run quietly,");
1124     s = add_string(s, "I to insert something, ");
1125
1126     if (base_ptr > 0)
1127       s = add_string(s, "E to edit your file, ");
1128
1129     if (deletions_allowed)
1130       s = add_string(s, "1 or ... or 9 to ignore the next 1 to 9 tokens of input,");
1131
1132     s = add_string(s, "H for help, X to quit.");
1133   }
1134
1135   return helpstring;
1136 }
1137
1138 char * make_up_query_string (int promptstr)
1139 {
1140   char *querystr;
1141   int nstart, nnext, n;
1142   char *s;
1143
1144   nstart = str_start[ promptstr];
1145   nnext = str_start[ promptstr + 1];
1146   n = nnext - nstart;
1147   querystr = (char *) malloc(n + 1);
1148   s = querystr;
1149   memcpy(s, &str_pool[nstart], n);  
1150   s += n;
1151   *s = '\0';
1152
1153   return querystr;
1154 }
1155
1156 // abort_flag set if input_line / ConsoleInput returns non-zero
1157 // should set interrupt instead ???
1158 // called from tex0.c, tex2.c, tex3.c
1159 /* sec 0071 */
1160 // void term_input(void)
1161 void term_input (char * term_str, int term_help_lines)
1162
1163   integer k;
1164   int flag;
1165   char * helpstring = NULL;
1166 #ifdef _WINDOWS
1167   char * querystring = NULL;
1168 #endif
1169 //  if (nhelplines != 0) {
1170 //    helpstring = make_up_help_string (nhelplines);
1171 //    printf(helpstring);
1172 //    free(helpstring);
1173 //  }
1174   show_line("\n", 0);    // force it to show what may be buffered up ???
1175   helpstring = NULL;
1176
1177 #ifdef _WINDOWS
1178   if (term_str != NULL)
1179     querystring = term_str;
1180
1181   if (term_help_lines != NULL)
1182     helpstring = make_up_help_string(term_help_lines);
1183
1184   if (helpstring == NULL && querystring != NULL)
1185   {
1186     if (strcmp(querystring, ": ") == 0)
1187       helpstring = xstrdup("Please type another file name (or ^z to exit):");
1188     else if (strcmp(querystring, "=>") == 0)    // from firm_up_the_line
1189       helpstring = xstrdup("Please type <enter> to accept this line\r\nor type a replacement line");
1190     else if (strcmp(querystring, "insert>") == 0) // from error() after "I"
1191       helpstring = xstrdup("Please type something to insert here");
1192     else if (strcmp(querystring, "") == 0)      // from read_toks
1193       helpstring = xstrdup("Please type a control sequence");
1194     else if (strcmp(querystring, "= ") == 0)    // from read_toks
1195       helpstring = xstrdup("Please type a token");
1196     else if (strcmp(querystring, "*") == 0)   // get_next
1197       helpstring = xstrdup("Please type a control sequence\r\n(or ^z to exit)");
1198   }
1199
1200   flag = ConsoleInput(querystring, helpstring, (char *) &buffer[first]);  // ???
1201 //  flag == 0 means trouble --- EOF on terminal
1202   if (querystring != NULL)
1203     free(querystring);
1204
1205   if (helpstring != NULL)
1206     free(helpstring);
1207
1208   helpstring = querystring = NULL;
1209
1210   last = first + strlen((char *) &buffer[first]); /* -1 ? */
1211 //  flag = (last > first);
1212 //  may need to be more elaborate see input_line in texmf.c ???
1213 //  sprintf(log_line, "first %d last %d flag %d - %s",
1214 //      first, last, flag, (char *) &buffer[first]);
1215 //  winerror(log_line);
1216 #else
1217   fflush(stdout);
1218   flag = input_ln(stdin, true);
1219 #endif
1220   if (!flag)
1221   {
1222     fatal_error("End of file on the terminal!");
1223     return;         // abort_flag set
1224   }
1225   term_offset = 0;
1226 #ifdef _WINDOWS
1227 // echo what was typed into Console buffer also
1228   if (last != first)
1229     for (k = first; k <= last - 1; k++)
1230       print(buffer[k]);
1231   print_ln();
1232 #else
1233   decr(selector);     // shut off echo
1234
1235   if (last != first)
1236     for (k = first; k <= last - 1; k++)
1237       print(buffer[k]);
1238
1239   print_ln();
1240   incr(selector);     // reset selector again
1241 #endif
1242 }
1243 /* sec 0091 */
1244 void int_error_ (integer n)
1245 {
1246   print_string(" (");
1247   print_int(n);
1248   print_char(')');
1249   error();
1250 }
1251 /* sec 0092 */
1252 void normalize_selector (void)
1253 {
1254   if (log_opened)
1255     selector = term_and_log;
1256   else
1257     selector = term_only;
1258
1259   if (job_name == 0)
1260     open_log_file();
1261
1262   if (interaction == batch_mode)
1263     decr(selector);
1264 }
1265 /* sec 0098 */
1266 void pause_for_instructions (void)
1267 {
1268    if (OK_to_interrupt)
1269    {
1270     interaction = error_stop_mode;
1271
1272     if ((selector == log_only) || (selector == no_print))
1273       incr(selector);
1274
1275     print_err("Interruption");
1276     help3("You rang?",
1277         "Try to insert some instructions for me (e.g.,`I\\showlists'),",
1278         "unless you just want to quit by typing `X'.");
1279     deletions_allowed = false;
1280     error();
1281     deletions_allowed = true;
1282     interrupt = 0;
1283   }
1284 }
1285 /* sec 0100 */
1286 integer half_(integer x)
1287 {
1288   if (odd(x))
1289     return ((x + 1) / 2);
1290   else
1291     return (x / 2);
1292 }
1293 /* sec 0102 */
1294 scaled round_decimals_(small_number k)
1295 {
1296   integer a;
1297
1298   a = 0;
1299
1300   while (k > 0)
1301   {
1302     decr(k);
1303     a = (a + dig[k] * 131072L) / 10; /* 2^17 */
1304   }
1305   
1306   return ((a + 1) / 2);
1307 }
1308 /* sec 0103 */
1309 /* This has some minor speedup changes - no real advantage probably ... */
1310 void print_scaled_(scaled s)
1311 {
1312   scaled delta;
1313
1314   if (s < 0)
1315   {
1316     print_char('-');
1317     s = - (integer) s;
1318   }
1319
1320   print_int(s / 65536L);
1321   print_char('.');
1322   s = 10 * (s % 65536L) + 5;
1323   delta = 10;
1324
1325   do
1326     {
1327       if (delta > 65536L)
1328         s = s - 17232; /* 2^15 - 50000 - rounding */
1329       print_char('0' + (s / 65536L));
1330       s = 10 * (s % 65536L);
1331       delta = delta * 10;
1332     }
1333   while (!(s <= delta));
1334 }
1335 /* sec 0105 */
1336 scaled mult_and_add_(integer n, scaled x, scaled y, scaled maxanswer)
1337 {
1338   if (n < 0)
1339   {
1340     x = - (integer) x;
1341     n = - (integer) n;
1342   }
1343
1344   if (n == 0)
1345     return y;
1346   else if (((x <= (maxanswer - y) / n) && (- (integer) x <= (maxanswer + y) / n)))
1347     return (n * x + y); 
1348   else
1349   {
1350     arith_error = true;
1351     return 0;
1352   }
1353 }
1354 /* sec 0106 */
1355 scaled x_over_n_(scaled x, integer n)
1356 {
1357   register scaled Result;
1358   bool negative;
1359
1360   negative = false;
1361
1362   if (n == 0)
1363   {
1364     arith_error = true;
1365     Result = 0;
1366     tex_remainder = x;
1367   }
1368   else
1369   {
1370     if (n < 0)
1371     {
1372       x = - (integer) x;
1373       n = - (integer) n;
1374       negative = true;
1375     }
1376
1377     if (x >= 0)
1378     {
1379       Result = x / n;
1380       tex_remainder = x % n;
1381     }
1382     else
1383     {
1384       Result = - (integer) ((- (integer) x)/ n);
1385       tex_remainder = - (integer) ((- (integer) x)% n);
1386     }
1387   }
1388
1389   if (negative)
1390     tex_remainder = - (integer) tex_remainder;
1391
1392   return Result;
1393 }
1394 /* sec 0107 */
1395 scaled xn_over_d_(scaled x, integer n, integer d)
1396 {
1397   register scaled Result;
1398   bool positive;
1399   nonnegative_integer t, u, v;
1400
1401   if (x >= 0)
1402     positive = true; 
1403   else
1404   {
1405     x = - (integer) x;
1406     positive = false;
1407   }
1408
1409   t =(x % 32767L) * n;
1410   u =(x / 32768L)* n +(t / 32768L);
1411   v =(u % d)* 32768L +(t % 32768L); 
1412
1413   if (u / d >= 32768L)
1414     arith_error = true; 
1415   else
1416     u = 32768L * (u / d) + (v / d);
1417
1418   if (positive)
1419   {
1420     Result = u;
1421     tex_remainder = v % d;
1422   }
1423   else
1424   {
1425     Result = - (integer) u;
1426     tex_remainder = - (integer)(v % d);
1427   }
1428
1429   return Result;
1430 }
1431 /* sec 0108 */
1432 halfword badness_(scaled t, scaled s)
1433 {
1434   integer r;
1435
1436   if (t == 0)
1437     return 0;
1438   else if (s <= 0)
1439     return 10000;
1440   else
1441   {
1442     if (t <= 7230584L)
1443       r = (t * 297) / s;
1444     else if (s >= 1663497L)
1445       r = t / (s / 297);
1446     else
1447       r = t;
1448
1449     if (r > 1290)
1450       return 10000; 
1451     else
1452       return (r * r * r + 131072L) / 262144L;  /* 2^17 */
1453   }
1454 }
1455 /* sec 0114 */
1456 #ifdef DEBUG
1457 void print_word_(memory_word w)
1458
1459   print_int(w.cint); 
1460   print_char(' ');
1461   print_scaled(w.cint); 
1462   print_char(' ');
1463   print_scaled(round(65536L * w.gr));
1464   print_ln();
1465   print_int(w.hh.v.LH);
1466   print_char('=');
1467   print_int(w.hh.b0);
1468   print_char(':');
1469   print_int(w.hh.b1);
1470   print_char(';');
1471   print_int(w.hh.v.RH);
1472   print_char(' ');
1473   print_int(w.qqqq.b0); 
1474   print_char(':');
1475   print_int(w.qqqq.b1); 
1476   print_char(':');
1477   print_int(w.qqqq.b2); 
1478   print_char(':');
1479   print_int(w.qqqq.b3);
1480
1481 /* need this version only if SHORTFONTINFO defined */
1482 void zprintfword(fmemoryword w)
1483 {
1484   print_int(w.cint);
1485   print_char(' ');
1486   print_scaled(w.cint);
1487   print_char(' ');
1488   print_scaled(round(65536L * w.gr));
1489   print_ln();
1490   print_int(w.hh.v.LH);
1491   print_char('=');
1492   print_int(w.hh.b0);
1493   print_char(':');
1494   print_int(w .hh.b1);
1495   print_char(';');
1496   print_int(w.hh.v.RH);
1497   print_char(' ');
1498   print_int(w.qqqq.b0);
1499   print_char(':');
1500   print_int(w.qqqq.b1);
1501   print_char(':');
1502   print_int(w.qqqq.b2);
1503   print_char(':');
1504   print_int(w.qqqq.b3);
1505 }
1506 #endif
1507 /* sec 0292 */
1508 void show_token_list_(integer p, integer q, integer l)
1509 {
1510   integer m, c;
1511   ASCII_code match_chr;
1512   ASCII_code n;
1513
1514   match_chr = '#';
1515   n = '0';
1516   tally = 0;
1517
1518   while ((p != 0) && (tally < l))
1519   {
1520     if (p == q)
1521     {
1522       first_count = tally;
1523       trick_count = tally + 1 + error_line - half_error_line;
1524
1525       if (trick_count < error_line)
1526         trick_count = error_line;
1527     }
1528
1529     if ((p < hi_mem_min) || (p > mem_end))
1530     {
1531       print_esc("CLOBBERED.");
1532       return;
1533     }
1534
1535     if (info(p) >= cs_token_flag)
1536       print_cs(info(p) - cs_token_flag);
1537     else
1538     {
1539       m = info(p) / 256;
1540       c = info(p) % 256;
1541
1542       if (info(p) < 0)
1543         print_esc("BAD.");
1544       else
1545         switch (m)
1546         {
1547           case left_brace:
1548           case right_brace:
1549           case math_shift:
1550           case tab_mark:
1551           case sup_mark:
1552           case sub_mark:
1553           case spacer:
1554           case letter:
1555           case other_char:
1556             print(c);
1557             break;
1558
1559           case mac_param:
1560             print(c);
1561             print(c);
1562             break;
1563
1564           case out_param:
1565             print(match_chr);
1566
1567             if (c <= 9)
1568               print_char(c + '0');
1569             else
1570             {
1571               print_char('!');
1572               return;
1573             }
1574             break;
1575
1576           case match:
1577             match_chr = (ASCII_code) c;
1578             print(c);
1579             incr(n);
1580             print_char(n);
1581
1582             if (n > '9')
1583               return;
1584             break;
1585
1586           case end_match:
1587             print_string("->");
1588             break;
1589
1590           default:
1591             print_esc("BAD.");
1592             break;
1593         }
1594     }
1595     p = link(p);
1596   }
1597
1598   if (p != 0)
1599     print_esc("ETC.");
1600 }
1601 /* sec 0306 */
1602 void runaway (void)
1603 {
1604   halfword p;
1605
1606   if (scanner_status > 1)
1607   {
1608     print_nl("Runaway ");
1609
1610     switch (scanner_status)
1611     {
1612       case defining:
1613         print_string("definition");
1614         p = def_ref;
1615         break;
1616
1617       case matching:
1618         print_string("argument");
1619         p = temp_head;
1620         break;
1621
1622       case aligning:
1623         print_string("preamble");
1624         p = hold_head;
1625         break;
1626
1627       case absorbing:
1628         print_string("text");
1629         p = def_ref;
1630         break;
1631     }
1632
1633     print_char('?');
1634     print_ln();
1635     show_token_list(link(p), 0, error_line - 10); 
1636   }
1637 }
1638 /* sec 0120 */
1639 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1640 /* first try list of available nodes (avail != NULL)                   */
1641 /* then see if can go upwards (mem_end < mem_max)                      */
1642 /* then see if can go downwards (hi_mem_min > lo_mem_max)              */
1643 /* if not, extend memory at the top and grab from there --- new        */
1644 /* else fail ! paragraph 120                                           */
1645 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1646 halfword get_avail (void)
1647 {
1648   halfword p;
1649
1650   p = avail;
1651
1652   if (p != 0)
1653     avail = link(avail);
1654   else if (mem_end < mem_max)
1655   {
1656     incr(mem_end);
1657     p = mem_end;
1658   }
1659   else
1660   {
1661     decr(hi_mem_min);
1662     p = hi_mem_min;
1663
1664     if (hi_mem_min <= lo_mem_max) /* have we run out in middle ? */
1665     {
1666       incr(hi_mem_min);
1667       mem = realloc_main (0, mem_top / 2);  /* zzzaa = zmem = mem */
1668
1669       if (mem == NULL)
1670         return 0;
1671
1672       if (mem_end >= mem_max)
1673       {
1674         runaway();
1675         overflow("main memory size", mem_max + 1 - mem_min);
1676         return 0;           // abort_flag set
1677       }
1678       incr(mem_end);        /* then grab from new area */
1679       p = mem_end;          /* 1993/Dec/14 */
1680     }
1681   }
1682
1683   link(p) = 0;       /* link(p) = null !!! */
1684
1685 #ifdef STAT
1686   incr(dyn_used); 
1687 #endif /* STAT */
1688
1689   return p; 
1690
1691 /* sec 0123 */
1692 void flush_list_(halfword p)          /* paragraph 123 */
1693
1694   halfword q, r;
1695
1696   if (p != 0)              /* null !!! */
1697   {
1698     r = p;
1699
1700     do
1701       {
1702         q = r;
1703         r = link(r);
1704 #ifdef STAT
1705         decr(dyn_used);
1706 #endif /* STAT */
1707       }
1708     while (!(r == 0));     /* r != null */
1709
1710     link(q) = avail;
1711     avail = p;
1712   }
1713 }
1714 /* sec 0125 */
1715 halfword get_node_(integer s)
1716 {
1717   register halfword Result;
1718   halfword p;
1719   halfword q;
1720   integer r;
1721   integer t;
1722 lab20:
1723
1724   p = rover;
1725
1726   do
1727     {
1728       q = p + node_size(p);
1729
1730       while ((mem[q].hh.v.RH == empty_flag))
1731       {
1732         t = rlink(q);
1733
1734         if (q == rover)
1735           rover = t;
1736
1737         llink(t) = llink(q);
1738         rlink(llink(q)) = t;
1739         q = q + node_size(q);
1740       }
1741
1742       r = q - s;
1743
1744       if (r > toint(p + 1)) 
1745       {
1746         node_size(p) = r - p;
1747         rover = p;
1748         goto lab40;
1749       }
1750
1751       if (r == p)
1752         if (rlink(p) != p)
1753         {
1754           rover = rlink(p);
1755           t = llink(p);
1756           llink(rover) = t;
1757           rlink(t) = rover;
1758           goto lab40;
1759         }
1760
1761       node_size(p) = q - p;
1762       p = rlink(p);
1763     }
1764   while (!(p == rover));
1765
1766   if (s == 1073741824L)    /* 2^30 - special case - merge adjacent */
1767   {
1768     Result = max_halfword;
1769
1770     if (trace_flag)
1771       show_line("Merged adjacent multi-word nodes\n", 0);
1772
1773     return Result;
1774   }
1775
1776 /*  maybe try downward epxansion first instead ? */
1777   if (lo_mem_max + 2 < hi_mem_min)
1778     if (lo_mem_max + 2 <= mem_bot + max_halfword)  /* silly ? flush 93/Dec/16 */
1779     {
1780       /* if (hi_mem_min - lo_mem_max >= 1998) */
1781       if (hi_mem_min - lo_mem_max >= (block_size + block_size - 2))
1782         /* t = lo_mem_max + 1000; */
1783         t = lo_mem_max + block_size;
1784       else
1785         t = lo_mem_max + 1 + (hi_mem_min - lo_mem_max) / 2;
1786
1787       p = llink(rover);
1788       q = lo_mem_max;
1789       rlink(p) = q;
1790       llink(rover) = q;
1791
1792       if (t > mem_bot + max_halfword)
1793         t = mem_bot + max_halfword;     /* silly ? flush 93/Dec/16 */
1794
1795       rlink(q) = rover;
1796       llink(q) = p;
1797       link(q) = empty_flag;
1798       node_size(q) = t - lo_mem_max; /* block size */
1799       lo_mem_max = t;
1800       link(lo_mem_max) = 0;
1801       info(lo_mem_max) = 0;
1802       rover = q;
1803       goto lab20;
1804     }
1805
1806 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1807 /* we've run out of space in the middle for variable length blocks */
1808 /* try and add new block from below mem_bot *//* first check if space ! */
1809   if (mem_min - (block_size + 1) <= mem_start) /* extend lower memory downwards */
1810   {
1811     mem = realloc_main (mem_top/2 + block_size, 0);  /* zzzaa = zmem = mem */
1812
1813     if (mem == NULL)
1814     {
1815       return 0;
1816     }
1817   }
1818
1819   if (mem_min - (block_size + 1) <= mem_start) /* check again */
1820   {
1821     if (trace_flag)
1822     {
1823       sprintf(log_line, "mem_min %d, mem_start %d, block_size %d\n", mem_min, mem_start, block_size);
1824       show_line(log_line, 0);
1825     }
1826
1827     overflow("main memory size", mem_max + 1 - mem_min); /* darn: allocation failed ! */
1828     return 0;     // abort_flag set
1829   }
1830 /* avoid function call in following ? */
1831   add_variable_space (block_size); /* now to be found in itex.c */
1832   goto lab20;         /* go try get_node again */
1833
1834 lab40:
1835   link(r) = 0;
1836
1837 #ifdef STAT
1838   var_used = var_used + s; 
1839 #endif /* STAT */
1840
1841   Result = r; 
1842   return Result; 
1843
1844 /* sec 0130 */
1845 void free_node_(halfword p, halfword s)
1846
1847   halfword q;
1848
1849   node_size(p) = s;
1850   link(p) = empty_flag;
1851   q = llink(rover);
1852   llink(p) = q;
1853   rlink(p) = rover;
1854   llink(rover) = p;
1855   rlink(q) = p;
1856 #ifdef STAT
1857   var_used = var_used - s; 
1858 #endif /* STAT */
1859 }
1860 /* sec 0136 */
1861 halfword new_null_box (void) 
1862 {
1863   halfword p;
1864
1865   p = get_node(box_node_size);
1866   type(p) = hlist_node;
1867   subtype(p) = min_quarterword;
1868   width(p) = 0;
1869   depth(p) = 0;
1870   height(p) = 0;
1871   shift_amount(p) = 0;
1872   list_ptr(p) = 0;
1873   glue_sign(p) = normal;
1874   glue_order(p) = normal;
1875   glue_set(p) = 0.0;
1876
1877   return p;
1878 }
1879 /* sec 0139 */
1880 halfword new_rule (void) 
1881 {
1882   halfword p;
1883
1884   p = get_node(rule_node_size);
1885   type(p) = rule_node;
1886   subtype(p) = 0;
1887   width(p) = null_flag;
1888   depth(p) = null_flag;
1889   height(p) = null_flag;
1890
1891   return p;
1892 }
1893 /* sec 0144 */
1894 halfword new_ligature_(quarterword f, quarterword c, halfword q)
1895 {
1896   halfword p;
1897
1898   p = get_node(small_node_size);
1899   type(p) = ligature_node;
1900   font(lig_char(p)) = f;
1901   character(lig_char(p)) = c;
1902   lig_ptr(p) = q;
1903   subtype(p) = 0;
1904
1905   return p;
1906 }
1907 /* sec 0144 */
1908 halfword new_lig_item_(quarterword c)
1909 {
1910   halfword p;
1911
1912   p = get_node(small_node_size);
1913   character(p) = c;
1914   lig_ptr(p) = 0;
1915
1916   return p;
1917 }
1918 /* sec 0145 */
1919 halfword new_disc (void) 
1920 {
1921   halfword p;
1922
1923   p = get_node(small_node_size);
1924   type(p) = disc_node;
1925   replace_count(p) = 0;
1926   pre_break(p) = 0;
1927   post_break(p) = 0;
1928
1929   return p;
1930 }
1931 /* sec 0147 */
1932 halfword new_math_(scaled w, small_number s)
1933 {
1934   halfword p;
1935
1936   p = get_node(small_node_size);
1937   type(p) = math_node;
1938   subtype(p) = s;
1939   width(p) = w;
1940
1941   return p;
1942 }
1943 /* sec 0151 */
1944 halfword new_spec_(halfword p)
1945 {
1946   halfword q;
1947
1948   q = get_node(glue_spec_size);
1949   mem[q] = mem[p];
1950   glue_ref_count(q) = 0;
1951   width(q) = width(p);
1952   stretch(q) = stretch(p);
1953   shrink(q) = shrink(p);
1954
1955   return q;
1956 }
1957 /* se 0152 */
1958 halfword new_param_glue_(small_number n)
1959 {
1960   halfword p;
1961   halfword q;
1962
1963   p = get_node(small_node_size);
1964   type(p) = glue_node;
1965   subtype(p) = n + 1;
1966   leader_ptr(p) = 0;
1967   q = glue_par(n);
1968   glue_ptr(p) = q;
1969   incr(glue_ref_count(q));
1970
1971   return p;
1972 }
1973 /* sec 0153 */
1974 halfword new_glue_(halfword q)
1975 {
1976   halfword p;
1977
1978   p = get_node(small_node_size);
1979   type(p) = glue_node;
1980   subtype(p) = normal;
1981   leader_ptr(p) = 0; 
1982   glue_ptr(p) = q;
1983   incr(glue_ref_count(q));
1984
1985   return p;
1986 }
1987 /* sec 0154 */
1988 halfword new_skip_param_(small_number n)
1989 {
1990   halfword p;
1991
1992   temp_ptr = new_spec(glue_par(n));
1993   p = new_glue(temp_ptr); 
1994   glue_ref_count(temp_ptr) = 0;
1995   subtype(p) = n + 1;
1996
1997   return p;
1998 }
1999 /* sec 0155 */
2000 halfword new_kern_(scaled w)
2001 {
2002   halfword p;
2003
2004   p = get_node(small_node_size);
2005   type(p) = kern_node;
2006   subtype(p) = normal;
2007   width(p) = w;
2008
2009   return p;
2010 }
2011 /* sec 0158 */
2012 halfword new_penalty_(integer m)
2013 {
2014   halfword p;
2015
2016   p = get_node(small_node_size);
2017   type(p) = penalty_node;
2018   subtype(p) = 0;
2019   penalty(p) = m;
2020
2021   return p;
2022 }
2023
2024 #ifdef DEBUG
2025 /* sec 0167 */
2026 void check_mem_(bool printlocs)
2027 {
2028   halfword p, q;
2029   bool clobbered;
2030
2031   for (p = mem_min; p <= lo_mem_max; p++) freearr[p] = false;
2032   for (p = hi_mem_min; p <= mem_end; p++) freearr[p] = false;
2033   p = avail;
2034   q = 0;
2035   clobbered = false;
2036   while (p != 0) {
2037     if ((p > mem_end) || (p < hi_mem_min))
2038       clobbered = true;
2039     else if (freearr[p])
2040       clobbered = true;
2041
2042     if (clobbered)
2043     {
2044       print_nl("AVAIL list clobbered at ");
2045       print_int(q);
2046       goto lab31;
2047     }
2048     freearr[p] = true;
2049     q = p;
2050     p = link(q);
2051   }
2052 lab31:;
2053   p = rover;
2054   q = 0;
2055   clobbered = false;
2056   do {
2057       if ((p >= lo_mem_max) || (p < mem_min))
2058         clobbered = true;
2059       else if ((rlink(p) >= lo_mem_max) || (rlink(p) < mem_min))
2060         clobbered = true;
2061       else if (!(is_empty(p)) || (node_size(p) < 2) ||
2062           (p + node_size(p) > lo_mem_max) || (llink(rlink(p)) != p))
2063         clobbered = true;
2064       
2065       if (clobbered)
2066       {
2067         print_nl("Double-AVAIL list clobbered at ");
2068         print_int(q);
2069         goto lab32;
2070       }
2071
2072       for (q = p; q <= p + node_size(p) - 1; q++)
2073       {
2074         if (freearr[q])
2075         {
2076           print_nl("Doubly free location at ");
2077           print_int(q);
2078           goto lab32;
2079         }
2080         freearr[q]= true;
2081       }
2082       q = p;
2083       p = rlink(p);
2084   } while (!(p == rover));
2085 lab32:;
2086   p = mem_min;
2087   while (p <= lo_mem_max) {
2088     if (is_empty(p))
2089     {
2090       print_nl("Bad flag at ");
2091       print_int(p);
2092     }
2093     while ((p <= lo_mem_max) && !freearr[p]) incr(p);
2094     while ((p <= lo_mem_max) && freearr[p]) incr(p);
2095   }
2096
2097   if (printlocs)
2098   {
2099     print_nl("New busy locs:");
2100
2101     for (p = mem_min; p <= lo_mem_max; p++)
2102       if (!freearr[p] && ((p > was_lo_max) || wasfree[p]))
2103       {
2104         print_char(' ');
2105         print_int(p);
2106       }
2107
2108     for (p = hi_mem_min; p <= mem_end; p++)
2109       if (!freearr[p] && ((p < was_hi_min) || (p > was_mem_end) || wasfree[p]))
2110       {
2111         print_char(' ');
2112         print_int(p);
2113       }
2114   }
2115
2116   for (p = mem_min; p <= lo_mem_max; p++) wasfree[p] = freearr[p];
2117   for (p = hi_mem_min; p <= mem_end; p++) wasfree[p] = freearr[p];
2118
2119   was_mem_end = mem_end;
2120   was_lo_max = lo_mem_max;
2121   was_hi_min = hi_mem_min;
2122 }
2123 #endif /* DEBUG */
2124
2125 #ifdef DEBUG
2126 /* sec 0172 */
2127 void search_mem_(halfword p)
2128 {
2129   integer q;
2130
2131   for (q = mem_min; q <= lo_mem_max; q++)
2132   {
2133     if (link(q) == p)
2134     {
2135       print_nl("LINK(");
2136       print_int(q);
2137       print_char(')');
2138     }
2139     if (info(q) == p)
2140     {
2141       print_nl("INFO(");
2142       print_int(q);
2143       print_char(')');
2144     }
2145   }
2146
2147   for (q = hi_mem_min; q <= mem_end; q++)
2148   {
2149     if (link(q) == p)
2150     {
2151       print_nl("LINK(");
2152       print_int(q);
2153       print_char(')');
2154     }
2155     if (info(q) == p)
2156     {
2157       print_nl("INFO(");
2158       print_int(q);
2159       print_char(')');
2160     }
2161   }
2162
2163   for (q = active_base; q <= box_base + 255; q++)
2164     if (equiv(q) == p)
2165     {
2166       print_nl("EQUIV(");
2167       print_int(q);
2168       print_char(')');
2169     }
2170
2171   if (save_ptr > 0)
2172     for (q = 0; q <= save_ptr - 1; q++)
2173     {
2174       if (equiv_field(save_stack[q]) == p)
2175       {
2176         print_nl("SAVE(");
2177         print_int(q);
2178         print_char(')');
2179       }
2180     }
2181
2182   for (q = 0; q <= hyphen_prime; q++)
2183     if (hyph_list[q] == p)
2184     {
2185       print_nl("HYPH(");
2186       print_int(q);
2187       print_char(')');
2188     }
2189 }
2190 #endif /* DEBUG */
2191 /* sec 0174 */
2192 void short_display_(integer p)
2193 {
2194   integer n; 
2195
2196   while (p != 0) {      /* want p != null here bkph 93/Dec/15 !!! NOTE: still not fixed in 3.14159 ! */
2197      if (is_char_node(p))
2198      {
2199        if (p <= mem_end)
2200        {
2201          if (font(p) != font_in_short_display)
2202          {
2203            if ((font(p) > font_max))
2204              print_char('*');
2205            else
2206            {
2207              print_esc("");
2208              print(font_id_text(font(p)));
2209            }
2210            print_char(' ');
2211            font_in_short_display = font(p);
2212          }
2213          print(character(p));
2214        }
2215      }
2216      else switch (mem[p].hh.b0)
2217      {
2218       case hlist_node:
2219       case vlist_node:
2220       case ins_node:
2221       case whatsit_node:
2222       case mark_node:
2223       case adjust_node:
2224       case unset_node:
2225         print_string("[]");
2226         break;
2227       case rule_node:
2228         print_char('|');
2229         break;
2230       case glue_node:
2231         if (glue_ptr(p) != 0)
2232           print_char(' ');
2233         break;
2234       case math_node:
2235         print_char('$');
2236         break;
2237       case ligature_node:
2238         short_display(lig_ptr(p));
2239         break;
2240       case disc_node:
2241         short_display(pre_break(p));
2242         short_display(post_break(p));
2243         n = replace_count(p);
2244
2245         while (n > 0) {
2246           if (link(p) != 0) /* if link(p)<>null then */
2247             p = link(p);
2248           decr(n);
2249         }
2250         break;
2251       default:
2252         break;
2253     }
2254     p = link(p);
2255   }
2256 }
2257 /* sec 0176 */
2258 void print_font_and_char_ (integer p)
2259 {
2260   if (p > mem_end)
2261     print_esc("CLOBBERED.");
2262   else
2263   {
2264     if ((font(p) > font_max))
2265       print_char('*');
2266     else
2267     {
2268       print_esc("");
2269       print(font_id_text(font(p)));
2270     }
2271
2272     print_char(' ');
2273     print(character(p));
2274   }
2275 }
2276 /* sec 0176 */
2277 void print_mark_ (integer p)
2278
2279   print_char('{');
2280
2281   if ((p < hi_mem_min)||(p > mem_end))
2282     print_esc("CLOBBERED.");
2283   else
2284     show_token_list(link(p), 0, max_print_line - 10);
2285
2286   print_char('}');
2287 }
2288 /* sec 0176 */
2289 void print_rule_dimen_ (scaled d)
2290 {
2291   if ((d == -1073741824L)) /* - 2^30 */
2292     print_char('*');
2293   else
2294     print_scaled(d);
2295 }
2296 /* sec 0177 */
2297 void print_glue_(scaled d, integer order, char * s)
2298 {
2299   print_scaled(d); 
2300
2301   if ((order < normal) || (order > filll))
2302     print_string("foul");
2303   else if (order > 0)
2304   {
2305     print_string("fil");
2306
2307     while (order > 1) {
2308       print_char('l');
2309       decr(order);
2310     }
2311   } else if (*s != '\0')
2312     print_string(s);
2313 }
2314 /* sec 0178 */
2315 void print_spec_(integer p, char * s)
2316 {
2317   if ((p < mem_min)||(p >= lo_mem_max)) 
2318     print_char('*');
2319   else
2320   {
2321     print_scaled(width(p));
2322
2323     if (*s != '\0')
2324       print_string(s);
2325
2326     if (stretch(p) != 0)
2327     {
2328       print_string("plus");
2329       print_glue(stretch(p), stretch_order(p), s);
2330     }
2331
2332     if (shrink(p) != 0)
2333     {
2334       print_string("minus");
2335       print_glue(shrink(p), shrink_order(p), s);
2336     }
2337   }
2338 }
2339 /* sec 0691 */
2340 void print_fam_and_char_(halfword p)
2341 {
2342   print_esc("fam");
2343   print_int(fam(p));
2344   print_char(' ');
2345   print(character(p));
2346 }
2347 /* sec 0691 */
2348 void print_delimiter_(halfword p)
2349 {
2350   integer a;
2351
2352   a = small_fam(p) * 256 + small_char(p);
2353   a = a * 4096 + large_fam(p) * 256 + large_char(p);
2354
2355   if (a < 0)
2356     print_int(a);
2357   else
2358     print_hex(a);
2359 }
2360 /* sec 0692 */
2361 void print_subsidiary_data_(halfword p, ASCII_code c)
2362 {
2363   if ((pool_ptr - str_start[str_ptr]) >= depth_threshold)
2364   {
2365     if (math_type(p) != 0)
2366       print_string(" []");
2367   }
2368   else
2369   {
2370     append_char(c);
2371     temp_ptr = p;
2372
2373     switch (math_type(p))
2374     {
2375       case math_char:
2376         print_ln();
2377         print_current_string();
2378         print_fam_and_char(p);
2379         break;
2380
2381       case sub_box:
2382         show_info();
2383         break;
2384
2385       case sub_mlist:
2386         if (info(p) == 0)
2387         {
2388           print_ln();
2389           print_current_string();
2390           print_string("{}");
2391         }
2392         else
2393           show_info();
2394         break;
2395
2396       default:
2397         break;
2398     }
2399
2400     decr(pool_ptr);
2401   }
2402 }
2403 /* sec 0694 */
2404 void print_style_(integer c)
2405 {
2406   switch (c / 2)
2407   {
2408     case 0:
2409       print_esc("displaystyle");
2410       break;
2411     case 1:
2412       print_esc("textstyle");
2413       break;
2414     case 2:
2415       print_esc("scriptstyle");
2416       break;
2417     case 3:
2418       print_esc("scriptscriptstyle");
2419       break;
2420     default:
2421       print_string("Unknown style!");
2422       break;
2423   }
2424 }
2425 /* sec 0225 */
2426 void print_skip_param_(integer n)
2427 {
2428   switch(n)
2429   {
2430     case line_skip_code:
2431       print_esc("lineskip");
2432       break;
2433
2434     case baseline_skip_code:
2435       print_esc("baselineskip");
2436       break; 
2437
2438     case par_skip_code:
2439       print_esc("parskip");
2440       break;
2441
2442     case above_display_skip_code:
2443       print_esc("abovedisplayskip");
2444       break;
2445
2446     case below_display_skip_code:
2447       print_esc("belowdisplayskip");
2448       break;
2449
2450     case above_display_short_skip_code:
2451       print_esc("abovedisplayshortskip");
2452       break;
2453
2454     case below_display_short_skip_code:
2455       print_esc("belowdisplayshortskip");
2456       break;
2457
2458     case left_skip_code:
2459       print_esc("leftskip");
2460       break;
2461
2462     case right_skip_code:
2463       print_esc("rightskip");
2464       break;
2465
2466     case top_skip_code:
2467       print_esc("topskip");
2468       break;
2469
2470     case split_top_skip_code:
2471       print_esc("splittopskip");
2472       break;
2473
2474     case tab_skip_code:
2475       print_esc("tabskip");
2476       break;
2477
2478     case space_skip_code:
2479       print_esc("spaceskip");
2480       break;
2481
2482     case xspace_skip_code:
2483       print_esc("xspaceskip");
2484       break;
2485
2486     case par_fill_skip_code:
2487       print_esc("parfillskip");
2488       break;
2489
2490     case thin_mu_skip_code:
2491       print_esc("thinmuskip");
2492       break;
2493
2494     case med_mu_skip_code:
2495       print_esc("medmuskip");
2496       break; 
2497
2498     case thick_mu_skip_code:
2499       print_esc("thickmuskip");
2500       break;
2501
2502     default:
2503       print_string("[unknown glue parameter!]");
2504       break;
2505   }
2506 }
2507 /* sec 0182 */
2508 void show_node_list_(integer p)
2509 {
2510   integer n;
2511   real g;
2512
2513   if (cur_length > depth_threshold)
2514   {
2515 /*  if (p > 0) */  /* was p>null !!! line 3662 in tex.web */
2516     if (p != 0)    /* fixed 94/Mar/23 BUG FIX NOTE: still not fixed in 3.14159 ! */
2517     print_string(" []");
2518     return; 
2519   }
2520
2521   n = 0; 
2522
2523   while (p != 0) {      /* want p != null - bkph 93/Dec/15 NOTE: still not fixed in 3.14159 ! */
2524     print_ln(); 
2525     print_current_string(); 
2526
2527     if (p > mem_end)
2528     {
2529       print_string("Bad link, display aborted.");
2530       return;
2531     }
2532
2533     incr(n);
2534
2535     if (n > breadth_max)
2536     {
2537       print_string("etc.");
2538       return;
2539     }
2540
2541     if ((p >= hi_mem_min))
2542       print_font_and_char(p);
2543     else switch (type(p))
2544     {
2545       case hlist_node:
2546       case vlist_node:
2547       case unset_node:
2548         {
2549           if (type(p) == hlist_node)
2550             print_esc("h");
2551           else if (type(p) == vlist_node)
2552             print_esc("v");
2553           else print_esc("unset");
2554
2555           print_string("box(");
2556           print_scaled(height(p));
2557           print_char('+');
2558           print_scaled(depth(p));
2559           print_string(")x");
2560           print_scaled(width(p));
2561
2562           if (type(p) == unset_node)
2563           {
2564             if (span_count(p) != 0)
2565             {
2566               print_string(" (");
2567               print_int(span_count(p) + 1);
2568               print_string(" columns)");
2569             }
2570
2571             if (glue_stretch(p) != 0)
2572             {
2573               print_string(", stretch ");
2574               print_glue(glue_stretch(p), glue_order(p), "");
2575             }
2576
2577             if (glue_shrink(p) != 0)
2578             {
2579               print_string(", shrink ");
2580               print_glue(glue_shrink(p), glue_sign(p), "");
2581             }
2582           }
2583           else
2584           {
2585             g = glue_set(p);
2586
2587             if ((g != 0.0) && (glue_sign(p) != 0))
2588             {
2589               print_string(", glue set ");
2590
2591               if (glue_sign(p) == shrinking)
2592                 print_string("- ");
2593
2594               if (fabs(g)> 20000.0)
2595               {
2596                 if (g > 0.0)
2597                   print_char('>');
2598                 else
2599                   print_string("< -");
2600
2601                 print_glue(20000 * 65536L, glue_order(p), "");
2602               }
2603               else
2604                 print_glue(round(65536L * g), glue_order(p), "");
2605             }
2606
2607             if (shift_amount(p) != 0)
2608             {
2609               print_string(", shifted ");
2610               print_scaled(shift_amount(p));
2611             }
2612           }
2613
2614           {
2615             {
2616               str_pool[pool_ptr] = 46;
2617               incr(pool_ptr);
2618             }
2619             show_node_list(mem[p + 5].hh.v.RH);
2620             decr(pool_ptr);
2621           }
2622         }
2623         break;
2624
2625       case rule_node:
2626         {
2627           print_esc("rule(");
2628           print_rule_dimen(height(p));
2629           print_char('+');
2630           print_rule_dimen(depth(p));
2631           print_string(")x");
2632           print_rule_dimen(width(p));
2633         }
2634         break;
2635
2636       case ins_node:
2637         {
2638           print_esc("insert");
2639           print_int(subtype(p));
2640           print_string(", natural size ");
2641           print_scaled(height(p));
2642           print_string("; split(");
2643           print_spec(split_top_ptr(p), "");
2644           print_char(',');
2645           print_scaled(depth(p));
2646           print_string("); float cost ");
2647           print_int(float_cost(p));
2648           {
2649             {
2650               str_pool[pool_ptr] = 46;
2651               incr(pool_ptr);
2652             }
2653             show_node_list(mem[p + 4].hh.v.LH);
2654             decr(pool_ptr);
2655           }
2656         }
2657         break;
2658       case 8:
2659         switch (subtype(p))
2660         {
2661           case open_node:
2662             {
2663               print_write_whatsit(1279, p);   /* debug # (-1 to exit): */
2664               print_char('=');
2665               print_file_name(open_name(p), open_area(p), open_ext(p));
2666             }
2667             break;
2668
2669           case write_node:
2670             {
2671               print_write_whatsit(591, p);  /* write */
2672               print_mark(write_tokens(p));
2673             }
2674             break;
2675
2676           case close_node:
2677             print_write_whatsit(1280, p); /* closeout */
2678             break;
2679
2680           case special_node:
2681             {
2682               print_esc("special");
2683               print_mark(write_tokens(p));
2684             }
2685             break;
2686
2687           case language_node:
2688             {
2689               print_esc("setlanguage");
2690               print_int(what_lang(p));
2691               print_string(" (hyphenmin ");
2692               print_int(what_lhm(p));
2693               print_char(',');
2694               print_int(what_rhm(p));
2695               print_char(')');
2696             }
2697             break;
2698
2699           default:
2700             print_string("whatsit?");
2701             break;
2702         }
2703         break;
2704
2705       case glue_node:
2706         if (subtype(p) >= a_leaders)
2707         {
2708           print_esc("");
2709
2710           if (subtype(p) == c_leaders)
2711             print_char('c');
2712           else if (subtype(p) == x_leaders)
2713             print_char('x');
2714
2715           print_string("leaders ");
2716
2717           print_spec(glue_ptr(p), "");
2718           {
2719             {
2720               str_pool[pool_ptr] = 46;
2721               incr(pool_ptr);
2722             }
2723             show_node_list(mem[p + 1].hh.v.RH);
2724             decr(pool_ptr);
2725           }
2726         }
2727         else
2728         {
2729           print_esc("glue");
2730
2731           if (subtype(p) != normal)
2732           {
2733             print_char('(');
2734
2735             if (subtype(p) < cond_math_glue)
2736               print_skip_param(subtype(p) - 1);
2737             else if (subtype(p) == cond_math_glue)
2738               print_esc("nonscript");
2739             else print_esc("mskip");
2740
2741             print_char(')');
2742           }
2743
2744           if (subtype(p) != cond_math_glue)
2745           {
2746             print_char(' ');
2747
2748             if (subtype(p) < cond_math_glue)
2749               print_spec(glue_ptr(p), "");
2750             else
2751               print_spec(glue_ptr(p), "mu");
2752           }
2753         }
2754         break;
2755
2756       case kern_node:
2757         if (subtype(p) != mu_glue)
2758         {
2759           print_esc("kern");
2760
2761           if (subtype(p) != normal)
2762             print_char(' ');
2763
2764           print_scaled(width(p));
2765
2766           if (subtype(p) == acc_kern)
2767             print_string(" (for accent)");
2768         }
2769         else
2770         {
2771           print_esc("mkern");
2772           print_scaled(width(p));
2773           print_string("mu");
2774         }
2775         break;
2776
2777       case math_node:
2778         {
2779           print_esc("math");
2780
2781           if (subtype(p) == before)
2782             print_string("on");
2783           else
2784             print_string("off");
2785
2786           if (width(p) != 0)
2787           {
2788             print_string(", surrounded ");
2789             print_scaled(width(p));
2790           }
2791         }
2792         break;
2793
2794       case ligature_node:
2795         {
2796           print_font_and_char(lig_char(p));
2797           print_string("(ligature ");
2798
2799           if (subtype(p) > 1)
2800             print_char('|');
2801
2802           font_in_short_display = font(lig_char(p)); 
2803           short_display(lig_ptr(p));
2804
2805           if (odd(subtype(p)))
2806             print_char('|');
2807
2808           print_char(')');
2809         }
2810         break;
2811
2812       case penalty_node:
2813         {
2814           print_esc("penalty ");
2815           print_int(penalty(p));
2816         }
2817         break;
2818
2819       case disc_node:
2820         {
2821           print_esc("discretionary");
2822
2823           if (replace_count(p) > 0)
2824           {
2825             print_string(" replacing ");
2826             print_int(replace_count(p));
2827           }
2828
2829           {
2830             {
2831               str_pool[pool_ptr] = 46;
2832               incr(pool_ptr);
2833             }
2834             show_node_list(mem[p + 1].hh.v.LH);
2835             decr(pool_ptr);
2836           }
2837           {
2838             str_pool[pool_ptr]= 124;
2839             incr(pool_ptr);
2840           }
2841           show_node_list(mem[p + 1].hh.v.RH);
2842           decr(pool_ptr);
2843         }
2844         break;
2845
2846       case mark_node:
2847         {
2848           print_esc("mark");
2849           print_mark(mark_ptr(p));
2850         }
2851         break;
2852
2853       case adjust_node:
2854         {
2855           print_esc("vadjust");
2856           {
2857             {
2858               str_pool[pool_ptr] = 46;
2859               incr(pool_ptr);
2860             }
2861             show_node_list(mem[p + 1].cint);
2862             decr(pool_ptr);
2863           }
2864         }
2865         break;
2866
2867       case style_node:
2868         print_style(subtype(p));
2869         break;
2870
2871       case choice_node:
2872         {
2873           print_esc("mathchoice");
2874           append_char('D');
2875           show_node_list(display_mlist(p));
2876           decr(pool_ptr);
2877           append_char('T');
2878           show_node_list(text_mlist(p));
2879           decr(pool_ptr);
2880           append_char('S');
2881           show_node_list(script_mlist(p));
2882           decr(pool_ptr);
2883           append_char('s');
2884           show_node_list(script_script_mlist(p)); 
2885           decr(pool_ptr); 
2886         } 
2887         break;
2888
2889       case ord_noad:
2890       case op_noad:
2891       case bin_noad:
2892       case rel_noad:
2893       case open_noad:
2894       case close_noad:
2895       case punct_noad:
2896       case inner_noad:
2897       case radical_noad:
2898       case over_noad:
2899       case under_noad:
2900       case vcenter_noad:
2901       case accent_noad:
2902       case left_noad:
2903       case right_noad:
2904         {
2905           switch (type(p))
2906           {
2907             case ord_noad:
2908               print_esc("mathord");
2909               break;
2910
2911             case op_noad:
2912               print_esc("mathop");
2913               break;
2914
2915             case bin_noad:
2916               print_esc("mathbin");
2917               break;
2918
2919             case rel_noad:
2920               print_esc("mathrel");
2921               break;
2922
2923             case open_noad:
2924               print_esc("mathopen");
2925               break;
2926
2927             case close_noad:
2928               print_esc("mathclose");
2929               break;
2930
2931             case punct_noad:
2932               print_esc("mathpunct");
2933               break;
2934
2935             case inner_noad:
2936               print_esc("mathinner");
2937               break;
2938
2939             case over_noad:
2940               print_esc("overline");
2941               break;
2942
2943             case under_noad:
2944               print_esc("underline");
2945               break;
2946
2947             case vcenter_noad:
2948               print_esc("vcenter");
2949               break;
2950
2951             case radical_noad:
2952               {
2953                 print_esc("radical");
2954                 print_delimiter(left_delimiter(p));
2955               }
2956               break;
2957
2958             case accent_noad:
2959               {
2960                 print_esc("accent");
2961                 print_fam_and_char(accent_chr(p));
2962               }
2963               break;
2964
2965             case left_noad:
2966               {
2967                 print_esc("left");
2968                 print_delimiter(delimiter(p));
2969               }
2970               break;
2971
2972             case right_noad:
2973               {
2974                 print_esc("right");
2975                 print_delimiter(delimiter(p));
2976               }
2977               break;
2978           }
2979
2980           if (subtype(p) != normal)
2981             if (subtype(p) == limits)
2982               print_esc("limits");
2983             else
2984               print_esc("nolimits");
2985
2986           if (type(p) < left_noad)
2987             print_subsidiary_data(nucleus(p), '.');
2988
2989           print_subsidiary_data(supscr(p), '^');
2990           print_subsidiary_data(subscr(p), '_');
2991         }
2992         break;
2993
2994       case fraction_noad:
2995         {
2996           print_esc("fraction, thickness ");
2997
2998           if (thickness(p) == 1073741824L)  /* 2^30 */
2999             print_string("= default");
3000           else
3001             print_scaled(thickness(p));
3002
3003           if ((small_fam(left_delimiter(p)) != 0) || (small_char(left_delimiter(p)) != 0) ||
3004               (large_fam(left_delimiter(p)) != 0) || (large_char(left_delimiter(p)) != 0))
3005           {
3006             print_string(", left-delimiter ");
3007             print_delimiter(left_delimiter(p));
3008           }
3009
3010           if ((small_fam(right_delimiter(p)) != 0) || (small_char(right_delimiter(p)) != 0) ||
3011               (large_fam(right_delimiter(p)) != 0)||(large_char(right_delimiter(p)) != 0))
3012           {
3013             print_string(", right-delimiter ");
3014             print_delimiter(right_delimiter(p));
3015           }
3016
3017           print_subsidiary_data(numerator(p), '\\');
3018           print_subsidiary_data(denominator(p), '/');
3019         }
3020         break;
3021
3022       default:
3023         print_string("Unknown node type!");
3024         break;
3025     }
3026     p = link(p);
3027   }
3028 }