OSDN Git Service

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