OSDN Git Service

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