OSDN Git Service

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