OSDN Git Service

updated sources.
[putex/putex.git] / src / texsourc / tex2.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 #pragma warning(disable:4244)       /* 96/Jan/10 */
25
26 /* following bit used to be end of tex1.c */
27
28 #ifdef STAT
29 /* sec 0284 */
30 void restore_trace_(halfword p, char * s)
31 {
32   begin_diagnostic();
33   print_char('{');
34   print_string(s);
35   print_char(' ');
36   show_eqtb(p);
37   print_char('}');
38   end_diagnostic(false);
39 }
40 #endif /* STAT */
41 /* sec 0281 */
42 void unsave (void)
43 {
44   halfword p;
45   quarterword l;
46   halfword t;
47
48   if (cur_level > level_one)
49   {
50     decr(cur_level);
51     while (true) {
52       decr(save_ptr);
53
54       if (save_type(save_ptr) == level_boundary)
55         goto lab30;
56
57       p = save_index(save_ptr);
58
59       if (save_type(save_ptr) == insert_token)
60       {
61         t = cur_tok;
62         cur_tok = p;
63         back_input();
64         cur_tok = t;
65       }
66       else
67       {
68         if (save_type(save_ptr) == restore_old_value)
69         {
70           l = save_level(save_ptr);
71           decr(save_ptr);
72         }
73         else
74           save_stack[save_ptr] = eqtb[undefined_control_sequence];
75         
76         if (p < int_base)
77           if (eq_level(p) == level_one)
78           {
79             eq_destroy(save_stack[save_ptr]);
80 #ifdef STAT
81             if (tracing_restores > 0)
82               restore_trace(p, "retaining");
83 #endif /* STAT */
84           }
85           else
86           {
87             eq_destroy(eqtb[p]);
88             eqtb[p] = save_stack[save_ptr];
89 #ifdef STAT
90             if (tracing_restores > 0)
91               restore_trace(p, "restoring");
92 #endif /* STAT */
93           }
94         else if (xeq_level[p] != level_one)
95         {
96           eqtb[p] = save_stack[save_ptr];
97           xeq_level[p] = l;     /* l may be used without having been ... */
98 #ifdef STAT
99           if (tracing_restores > 0)
100             restore_trace(p, "restoring");
101 #endif /* STAT */
102         }
103         else
104         {
105 #ifdef STAT
106           if (tracing_restores > 0)
107             restore_trace(p, "retaining");
108 #endif /* STAT */
109         }
110       }
111     }
112 lab30:
113     cur_group = save_level(save_ptr);
114     cur_boundary = save_index(save_ptr);
115   }
116   else
117   {
118     confusion("curlevel");
119     return;       // abort_flag set
120   }
121 }
122 /* This is where the old tex2.c used to start */
123 /* sec 0288 */
124 void prepare_mag (void) 
125 {
126   if ((mag_set > 0) && (mag != mag_set))
127   {
128     print_err("Incompatible magnification (");
129     print_int(mag);
130     print_string(");");
131     print_nl(" the previous value will be retained");
132     help2("I can handle only one magnification ratio per job. So I've",
133         "reverted to the magnification you used earlier on this run.");
134     int_error(mag_set);
135     geq_word_define(int_base + mag_code, mag_set);
136   } 
137   if ((mag <= 0) || (mag > 32768L))
138   {
139     print_err("Illegal magnification has been changed to 1000");
140     help1("The magnification ratio must be between 1 and 32768.");
141     int_error(mag);
142     geq_word_define(int_base + mag_code, 1000);
143   }
144   mag_set = mag;
145 }
146 /* sec 0295 */
147 void token_show_ (halfword p)
148 {
149   if (p != 0)
150     show_token_list(link(p), 0, 10000000L);
151 }
152 /* sec 0296 */
153 void print_meaning (void) 
154 {
155   print_cmd_chr(cur_cmd, cur_chr);
156
157   if (cur_cmd >= call)
158   {
159     print_char(':');
160     print_ln();
161     token_show(cur_chr);
162   } 
163   else if (cur_cmd == top_bot_mark)
164   {
165     print_char(':');
166     print_ln();
167     token_show(cur_mark[cur_chr]);
168   }
169 }
170 /* sec 0299 */
171 void show_cur_cmd_chr (void)
172
173   begin_diagnostic();
174   print_nl("{");
175   if (mode != shown_mode)
176   {
177     print_mode(mode);
178     print_string(": ");
179     shown_mode = mode;
180   }
181   print_cmd_chr(cur_cmd, cur_chr);
182   print_char('}');
183   end_diagnostic(false);
184 }
185 /* sec 0311 */
186 void show_context (void)
187 {
188   char old_setting;
189   integer nn;
190   bool bottomline;
191   integer i;
192   integer j;
193   integer l;
194   integer m;
195   integer n;
196   integer p;
197   integer q;
198
199   base_ptr = input_ptr;
200   input_stack[base_ptr] = cur_input;
201   nn = -1;
202   bottomline = false;
203   while (true) {
204     cur_input = input_stack[base_ptr];
205     if ((cur_input.state_field != 0))
206       if ((cur_input.name_field > 17) || (base_ptr == 0))
207         bottomline = true;
208     if ((base_ptr == input_ptr) || bottomline || (nn < error_context_lines))
209     {
210       if ((base_ptr == input_ptr) || (cur_input.state_field != token_list) ||
211           (cur_input.index_field != backed_up) || (cur_input.loc_field != 0))
212       {
213         tally = 0;
214         old_setting = selector;
215         if (cur_input.state_field != 0)
216         {
217           if (cur_input.name_field <= 17)
218             if ((cur_input.name_field == 0))
219               if (base_ptr == 0)
220                 print_nl("<*>");
221               else
222                 print_nl("<insert> ");
223             else
224             {
225               print_nl("<read ");
226               if (cur_input.name_field == 17)
227                 print_char('*');
228               else
229                 print_int(cur_input.name_field - 1);
230               print_char('>');
231             }
232           else {
233             if (c_style_flag)
234             {
235               print_ln();
236               /* show current input file name - ignore if from terminal */
237               if (cur_input.name_field > 17)  /* redundant ? */
238                 print(cur_input.name_field);
239               print_char('(');
240               print_int(line); /* line number */
241               print_char(')');
242               print_char(' ');
243               print_char(':');
244             }
245             else
246             {
247               print_nl("l.");        /* l. ? 573 ????? 98/Dec/8 check ! */
248               print_int(line);      /* line number */
249             }
250           }
251           print_char(' ');
252           {
253             l = tally;
254             tally = 0;
255             selector = pseudo;
256             trick_count = 1000000L;
257           }
258           if (buffer[cur_input.limit_field] == end_line_char)
259             j = cur_input.limit_field;
260           else
261             j = cur_input.limit_field + 1;
262           if (j > 0)
263             for (i = cur_input.start_field; i <= j - 1; i++)
264             {
265               if (i == cur_input.loc_field)
266               {
267                 first_count = tally;
268                 trick_count = tally + 1 + error_line - half_error_line;
269                 if (trick_count < error_line)
270                   trick_count = error_line;
271               }
272               print(buffer[i]);
273             }
274         }
275         else
276         {
277           switch (cur_input.index_field)
278           {
279             case parameter:
280               print_nl("<argument> ");
281               break;
282             case u_template:
283             case v_template:
284               print_nl("<template> ");
285               break;
286             case backed_up:
287               if (cur_input.loc_field == 0)
288                 print_nl("<recently read> ");
289               else
290                 print_nl("<to be read again> ");
291               break;
292             case inserted:
293               print_nl("<inserted text> ");
294               break;
295             case macro:
296               print_ln();
297               print_cs(cur_input.name_field);
298               break;
299             case output_text:
300               print_nl("<output> ");
301               break;
302             case every_par_text:
303               print_nl("<everypar> ");
304               break;
305             case every_math_text:
306               print_nl("<everymath> ");
307               break;
308             case every_display_text:
309               print_nl("<everydisplay> ");
310               break;
311             case every_hbox_text:
312               print_nl("<everyhbox> ");
313               break;
314             case every_vbox_text:
315               print_nl("<everyvbox> ");
316               break;
317             case every_job_text:
318               print_nl("<everyjob> ");
319               break;
320             case every_cr_text:
321               print_nl("<everycr> ");
322               break;
323             case mark_text:
324               print_nl("<mark> ");
325               break;
326             case write_text:
327               print_nl("<write> ");
328               break;
329             default:
330               print_nl("?");
331               break;
332           }
333           {
334             l = tally;
335             tally = 0;
336             selector = pseudo;
337             trick_count = 1000000L;
338           }
339           if (cur_input.index_field < macro)
340             show_token_list(cur_input.start_field, cur_input.loc_field, 100000L);
341           else
342             show_token_list(link(cur_input.start_field), cur_input.loc_field, 100000L);
343         }
344         selector = old_setting;
345         if (trick_count == 1000000L)
346         {
347           first_count = tally;
348           trick_count = tally + 1 + error_line - half_error_line;
349           if (trick_count < error_line)
350             trick_count = error_line;
351         }
352         
353         if (tally < trick_count)
354           m = tally - first_count;
355         else
356           m = trick_count - first_count;
357
358         if (l + first_count <= half_error_line)
359         {
360           p = 0;
361           n = l + first_count;
362         }
363         else
364         {
365           print_string("...");
366           p = l + first_count - half_error_line + 3;
367           n = half_error_line;
368         }
369
370         for (q = p; q <= first_count - 1; q++)
371           print_char(trick_buf[q % error_line]);
372         
373         print_ln();
374
375         for (q = 1; q <= n; q++)
376           print_char(' ');
377
378         if (m + n <= error_line)
379           p = first_count + m;
380         else
381           p = first_count +(error_line - n - 3);
382
383         for (q = first_count; q <= p - 1; q++)
384           print_char(trick_buf[q % error_line]);
385
386         if (m + n > error_line)
387           print_string("...");
388         incr(nn);
389       }
390     }
391     else if (nn == error_context_lines)
392     {
393       print_nl("...");
394       incr(nn); 
395     }
396     if (bottomline)
397       goto lab30;
398     decr(base_ptr);
399   }
400 lab30:
401   cur_input = input_stack[input_ptr];
402 }
403 #pragma optimize("g", off)          /* 98/Dec/10 experiment */
404 /* sec 0323 */
405 void begin_token_list_ (halfword p, quarterword t)
406 {
407   {
408     if (input_ptr > max_in_stack)
409     {
410       max_in_stack = input_ptr;
411 #ifdef ALLOCATEINPUTSTACK
412       if (input_ptr == current_stack_size)
413         input_stack = realloc_input_stack(increment_stack_size);
414       if (input_ptr == current_stack_size)
415       {    /* check again after allocation */
416         overflow("input stack size", current_stack_size);
417         return;     // abort_flag set
418       }
419 #else
420       if (input_ptr == stack_size)
421       { /* input stack - not dynamic */
422         overflow("input stack size", stack_size);
423         return;     // abort_flag set
424       }
425 #endif
426     }
427     input_stack[input_ptr] = cur_input;
428     incr(input_ptr);
429   }
430   cur_input.state_field = token_list;
431   cur_input.start_field = p;
432   cur_input.index_field = t;
433   if (t >= macro)
434   {
435     add_token_ref(p);
436     if (t == macro)
437       cur_input.limit_field = param_ptr;
438     else
439     {
440       cur_input.loc_field = link(p);
441       if (tracing_macros > 1)
442       {
443         begin_diagnostic(); 
444         print_nl("");
445         switch (t)
446         {
447           case mark_text:
448             print_esc("mark");
449             break;
450           case write_text:
451             print_esc("write");
452             break;
453           default:
454             print_cmd_chr(assign_toks, t + (hash_size + 1307));
455             break;
456         }
457         print_string("->");
458         token_show(p);
459         end_diagnostic(false);
460       }
461     }
462   }
463   else
464     cur_input.loc_field = p;
465 }
466 #pragma optimize("", on)          /* 98/Dec/10 experiment */
467 /* sec 0324 */
468 void end_token_list (void) 
469
470   if (cur_input.index_field >= backed_up)
471   {
472     if (cur_input.index_field <= inserted)
473       flush_list(cur_input.start_field); 
474     else
475     {
476       delete_token_ref(cur_input.start_field);
477       if (cur_input.index_field == macro)
478         while (param_ptr > cur_input.limit_field) {
479           decr(param_ptr);
480           flush_list(param_stack[param_ptr]);
481         }
482     }
483   }
484   else if (cur_input.index_field == u_template)
485     if (align_state > 500000L)
486       align_state = 0;
487     else {
488       fatal_error("(interwoven alignment preambles are not allowed)");
489       return;     // abort_flag set
490     }
491   {
492     decr(input_ptr);
493     cur_input = input_stack[input_ptr];
494   }
495   {
496     if (interrupt != 0)
497     {
498       pause_for_instructions();
499     }
500   }
501 }
502 /* sec 0325 */
503 void back_input (void)
504 {
505   halfword p;
506   while ((cur_input.state_field == 0) && (cur_input.loc_field == 0) &&
507       (cur_input.index_field != v_template)) {
508     end_token_list();
509   }
510   p = get_avail();
511   info(p) = cur_tok;
512   if (cur_tok < 768)
513     if (cur_tok < 512)
514       decr(align_state);
515     else
516       incr(align_state);
517   {
518     if (input_ptr > max_in_stack)
519     {
520       max_in_stack = input_ptr;
521 #ifdef ALLOCATEINPUTSTACK
522       if (input_ptr == current_stack_size)
523         input_stack = realloc_input_stack(increment_stack_size);
524       if (input_ptr == current_stack_size)
525       {  /* check again after allocation */
526         overflow("input stack size", current_stack_size);
527         return;     // abort_flag set
528       }
529 #else
530       if (input_ptr == stack_size)
531       { /* stack size - not dynamic */
532         overflow("input stack size", stack_size);
533         return;     // abort_flag set
534       }
535 #endif
536     }
537     input_stack[input_ptr] = cur_input;
538     incr(input_ptr);
539   }
540   cur_input.state_field = token_list;
541   cur_input.start_field = p;
542   cur_input.index_field = backed_up;
543   cur_input.loc_field = p;
544 }
545 /* sec 0327 */
546 void back_error (void)
547 {
548   OK_to_interrupt = false;
549   back_input();
550   OK_to_interrupt = true;
551   error();
552 }
553 /* sec 0327 */
554 void ins_error (void) 
555 {
556   OK_to_interrupt = false;
557   back_input();
558   cur_input.index_field = inserted;
559   OK_to_interrupt = true;
560   error();
561 }
562 /* sec 0328 */
563 void begin_file_reading (void)
564 {
565   if (in_open == max_in_open)
566   {
567     overflow("text input levels", max_in_open); /* text input levels - NOT DYNAMIC */
568     return;     // abort_flag set
569   }
570 #ifdef ALLOCATEBUFFER
571   if (first == current_buf_size)
572     buffer = realloc_buffer(increment_buf_size);
573   if (first == current_buf_size)
574   {   /* check again after allocation */
575     overflow("buffer size", current_buf_size);
576     return;     // abort_flag set
577   }
578 #else
579   if (first == buf_size)
580   {
581     overflow("buffer size", buf_size);  /* buffer size - not dynamic */
582     return;     // abort_flag set
583   }
584 #endif
585   incr(in_open);
586   if (in_open > high_in_open)     /* 1999 Jan 17 */
587     high_in_open = in_open;
588   {
589     if (input_ptr > max_in_stack)
590     {
591       max_in_stack = input_ptr;
592 #ifdef ALLOCATEINPUTSTACK
593       if (input_ptr == current_stack_size)
594         input_stack = realloc_input_stack(increment_stack_size);
595       if (input_ptr == current_stack_size)
596       {
597         overflow("input stack size", current_stack_size);  /* check again after allocation */
598         return;     // abort_flag set
599       }
600 #else
601       if (input_ptr == stack_size)
602       {
603         overflow("input stack size", stack_size);    /* input stack - not dynamic */
604         return;     // abort_flag set
605       }
606 #endif
607     }
608     input_stack[input_ptr] = cur_input;
609     incr(input_ptr);
610   }
611   cur_input.index_field = in_open;
612   line_stack[cur_input.index_field] = line;
613   cur_input.start_field = first;
614   cur_input.state_field = 1;
615   cur_input.name_field = 0;
616 }
617 /* sec 0329 */
618 void end_file_reading (void)
619 {
620   first = cur_input.start_field;
621   line = line_stack[cur_input.index_field];
622   if (cur_input.name_field > 17)
623     (void) a_close(input_file[cur_input.index_field]);
624   {
625     decr(input_ptr);
626     cur_input = input_stack[input_ptr];
627   }
628   decr(in_open);
629 }
630 /* called only form tex0.c */
631 /* sec 0330 */
632 void clear_for_error_prompt (void) 
633 {
634   while ((cur_input.state_field != 0) &&
635       (cur_input.name_field == 0) &&
636       (input_ptr > 0) &&
637       (cur_input.loc_field > cur_input.limit_field))
638     end_file_reading();
639   print_ln();
640 }
641 /* sec 0336 */
642 void check_outer_validity (void)
643 {
644   halfword p;
645   halfword q;
646
647   if (scanner_status != 0)
648   {
649     deletions_allowed = false;
650     if (cur_cs != 0)
651     {
652       if ((cur_input.state_field == 0) ||
653           (cur_input.name_field < 1) ||
654           (cur_input.name_field > 17))
655       {
656         p = get_avail();
657         info(p) = 4095 + cur_cs;
658         begin_token_list(p, 3);
659       }
660       cur_cmd = spacer;
661       cur_chr = ' ';
662     }
663
664     if (scanner_status > skipping)
665     {
666       runaway();
667       if (cur_cs == 0)
668         print_err("File ended");
669       else
670       {
671         cur_cs = 0;
672         print_err("Forbidden control sequence found");
673       }
674       print_string(" while scanning ");
675       p = get_avail();
676       switch (scanner_status)
677       {
678         case defining:
679           print_string("definition");
680           info(p) = 637;
681           break;
682         case matching:
683           print_string("use");
684           info(p) = par_token;
685           long_state = outer_call;
686           break;
687         case aligning:
688           print_string("preamble");
689           info(p) = 637;
690           q = p;
691           p = get_avail();
692           link(p) = q;
693 /*    mem[p].hh.v.LH = (hash_size + 4610);  */
694 /*    mem[p].hh.v.LH = (hash_size + 4095 + 515);  */
695           info(p) = (hash_size + hash_extra + 4095 + 515); /*96/Jan/10*/
696           align_state = -1000000L;
697           break;
698         case absorbing:
699           print_string("text");
700           info(p) = 637;
701           break;
702       }
703       begin_token_list(p, 4);
704       print_string(" of ");
705       sprint_cs(warning_index);
706       help4("I suspect you have forgotten a `}', causing me",
707           "to read past where you wanted me to stop.",
708           "I'll try to recover; but if the error is serious,",
709           "you'd better type `E' or `X' now and fix your file.");
710       error();
711     }
712     else
713     {
714       print_err("Incomplete ");
715       print_cmd_chr(if_test, cur_if);
716       print_string("; all text was ignored after line ");
717       print_int(skip_line);
718       help3("A forbidden control sequence occurred in skipped text.",
719           "This kind of error happens when you say `\\if...' and forget",
720           "the matching `\\fi'. I've inserted a `\\fi'; this might work.");
721       if (cur_cs != 0)
722         cur_cs = 0; 
723       else
724         help_line[2] = "The file ended while I was skipping conditional text.";
725 /*      cur_tok = (hash_size + 4613);  */
726 /*      cur_tok = (hash_size + 4095 + 518);  */
727       cur_tok = (hash_size + hash_extra + 4095 + 518); /* 96/Jan/10 */
728       ins_error();
729   }
730     deletions_allowed = true;
731   }
732 }
733 /*****************************************************************************/
734 /* get_next() moved from here to end for pragma optimize reasons 96/Sep/12 */
735 void get_next(void);
736 /*****************************************************************************/
737 /* sec 0363 */
738 void firm_up_the_line (void)
739 {
740   integer k;
741
742   cur_input.limit_field = last;
743   if (pausing > 0)
744     if (interaction > 1)
745     {
746       ;
747       print_ln();
748       if (cur_input.start_field < cur_input.limit_field)
749         for (k = cur_input.start_field; k <= cur_input.limit_field - 1; k++)
750           print(buffer[k]);
751       first = cur_input.limit_field;
752       {
753         ;
754         print_string("=>");
755         term_input("=>", 0);
756       }
757       if (last > first)
758       {
759         for (k = first; k <= last - 1; k++)
760           buffer[k + cur_input.start_field - first] = buffer[k];
761         cur_input.limit_field = cur_input.start_field + last - first;
762       }
763     }
764 }
765 /* sec 0365 */
766 void get_token (void)
767
768   no_new_control_sequence = false;
769   get_next();
770   no_new_control_sequence = true;
771   if (cur_cs == 0)
772     cur_tok = (cur_cmd * 256) + cur_chr;
773   else
774     cur_tok = 4095 + cur_cs;
775 }
776 /* sec 0389 */
777 void macro_call (void)
778 {
779   halfword r;
780   halfword p;
781   halfword q;
782   halfword s;
783   halfword t;
784   halfword u, v;
785   halfword rbraceptr;
786   small_number n;
787   halfword unbalance;
788   halfword m;
789   halfword refcount;
790   small_number savescannerstatus;
791   halfword savewarningindex;
792   ASCII_code match_chr;
793
794   savescannerstatus = scanner_status;
795   savewarningindex = warning_index;
796   warning_index = cur_cs;
797   refcount = cur_chr;
798   r = link(refcount);
799   n = 0;
800
801   if (tracing_macros > 0)
802   {
803     begin_diagnostic();
804     print_ln();
805     print_cs(warning_index);
806     token_show(refcount);
807     end_diagnostic(false);
808   }
809   if (info(r) != 3584)
810   {
811     scanner_status = matching;
812     unbalance = 0;
813     long_state = eq_type(cur_cs);
814     if (long_state >= outer_call)
815       long_state = long_state - 2;
816     do {
817       link(temp_head) = 0;
818       if ((info(r) > 3583) || (info(r) < 3328))
819         s = 0;
820       else
821       {
822         match_chr = info(r) - 3328;
823         s = link(r);
824         r = s;
825         p = temp_head;
826         m = 0;
827       }
828 lab22:
829       get_token();
830       if (cur_tok == info(r))
831       {
832         r = link(r);
833         if ((info(r) >= 3328) && (info(r) <= 3584))
834         {
835           if (cur_tok < 512)
836             decr(align_state);
837           goto lab40;
838         }
839         else
840           goto lab22;
841       }
842       if (s != r)
843         if (s == 0)
844         {
845           print_err("Use of ");
846           sprint_cs(warning_index);
847           print_string(" doesn't match its definition");
848           help4("If you say, e.g., `\\def\\a1{...}', then you must always",
849               "put `1' after `\\a', since control sequence names are",
850               "made up of letters only. The macro here has not been",
851               "followed by the required stuff, so I'm ignoring it.");
852           error();
853           goto lab10;
854         }
855         else
856         {
857           t = s;
858           do {
859             {
860               q = get_avail();
861               mem[p].hh.v.RH = q;
862               mem[q].hh.v.LH = mem[t].hh.v.LH;
863               p = q;
864             }
865             incr(m);
866             u = link(t);
867             v = s;
868             while (true) {
869               if (u == r)
870                 if (cur_tok != info(v))
871                   goto lab30;
872                 else
873                 {
874                   r = link(v);
875                   goto lab22;
876                 }
877               if (info(u) != info(v))
878                 goto lab30;
879               u = link(u);
880               v = link(v);
881             }
882 lab30:
883             t = link(t);
884           } while(!(t == r));
885           r = s;
886         }
887       if (cur_tok == par_token)
888         if (long_state != long_call)
889         {
890           if (long_state == call)
891           {
892             runaway();
893             print_err("Paragraph ended before ");
894             sprint_cs(warning_index);
895             print_string("was complete");
896             help3("I suspect you've forgotten a `}', causing me to apply this",
897                 "control sequence to too much text. How can we recover?",
898                 "My plan is to forget the whole thing and hope for the best.");
899             back_error();
900           }
901           pstack[n] = link(temp_head);
902           align_state = align_state - unbalance;
903           for (m = 0; m <= n; m++)
904             flush_list(pstack[m]);
905           goto lab10;
906         }
907       if (cur_tok < 768)
908         if (cur_tok < 512)
909         {
910           unbalance = 1;
911           while (true) {
912             {
913               {
914                 q = avail;
915                 if (q == 0)
916                   q = get_avail();
917                 else
918                 {
919                   avail = mem[q].hh.v.RH;
920                   mem[q].hh.v.RH = 0;
921 #ifdef STAT
922                   incr(dyn_used);
923 #endif /* STAT */
924                 }
925               }
926               mem[p].hh.v.RH = q;
927               mem[q].hh.v.LH = cur_tok;
928               p = q;
929             }
930             get_token();
931             if (cur_tok == par_token)
932               if (long_state != long_call)
933               {
934                 if (long_state == call)
935                 {
936                   runaway();
937                   print_err("Paragraph ended before ");
938                   sprint_cs(warning_index);
939                   print_string(" was complete");
940                   help3("I suspect you've forgotten a `}', causing me to apply this",
941                       "control sequence to too much text. How can we recover?",
942                       "My plan is to forget the whole thing and hope for the best.");
943                   back_error();
944                 }
945                 pstack[n] = link(temp_head);
946                 align_state = align_state - unbalance;
947                 for (m = 0; m <= n; m++)
948                   flush_list(pstack[m]);
949                 goto lab10;
950               }
951             if (cur_tok < 768)
952               if (cur_tok < 512)
953                 incr(unbalance); 
954               else
955               {
956                 decr(unbalance);
957                 if (unbalance == 0)
958                   goto lab31;
959               }
960           }
961 lab31:
962           rbraceptr = p;
963           {
964             q = get_avail();
965             mem[p].hh.v.RH = q;
966             mem[q].hh.v.LH = cur_tok;
967             p = q;
968           }
969         }
970         else
971         {
972           back_input();
973           print_err("Argument of ");
974           sprint_cs(warning_index);
975           print_string(" has an extra }");
976           help6("I've run across a `}' that doesn't seem to match anything.",
977               "For example, `\\def\\a#1{...}' and `\\a}' would produce",
978               "this error. If you simply proceed now, the `\\par' that",
979               "I've just inserted will cause me to report a runaway",
980               "argument that might be the root of the problem. But if",
981               "your `}' was spurious, just type `2' and it will go away.");
982           incr(align_state);
983           long_state = call;
984           cur_tok = par_token;
985           ins_error();
986           goto lab22;
987         }
988       else
989       {
990         if (cur_tok == 2592)
991           if (info(r) <= 3584)
992             if (info(r) >= 3328)
993               goto lab22;
994         {
995           q = get_avail();
996           mem[p].hh.v.RH = q;   /* p may be used without having ... */
997           mem[q].hh.v.LH = cur_tok;
998           p = q;
999         }
1000       }
1001       incr(m);          /* m may be used without having been ... */
1002       if (info(r) > 3584)
1003         goto lab22;
1004       if (info(r) < 3328)
1005         goto lab22;
1006 lab40:
1007       if (s != 0)
1008       {
1009         if ((m == 1) && (info(p) < 768) && (p != temp_head))
1010         {
1011           link(rbraceptr) = 0; /* rbraceptr may be used without ... */
1012           free_avail(p);
1013           p = link(temp_head);
1014           pstack[n]= link(p);
1015           free_avail(p);
1016         }
1017         else
1018           pstack[n] = link(temp_head);
1019         incr(n);
1020         if (tracing_macros > 0)
1021         {
1022           begin_diagnostic();
1023           //print_nl(match_chr); /* matchchar may be used without ... */
1024           print_nl(""); print(match_chr);
1025           print_int(n);
1026           print_string("<-");
1027           show_token_list(pstack[n - 1], 0, 1000);
1028           end_diagnostic(false);
1029         }
1030       }
1031     } while(!(info(r) == 3584));
1032   }
1033
1034   while((cur_input.state_field == token_list) && (cur_input.loc_field == 0) &&
1035       (cur_input.index_field != v_template))
1036     end_token_list();
1037   begin_token_list(refcount, macro);
1038   cur_input.name_field = warning_index;
1039   cur_input.loc_field = link(r);
1040   if (n > 0)
1041   {
1042     if (param_ptr + n > max_param_stack)
1043     {
1044       max_param_stack = param_ptr + n;
1045 #ifdef ALLOCATEPARAMSTACK
1046       if (max_param_stack > current_param_size)
1047         param_stack = realloc_param_stack(increment_param_size);
1048       if (max_param_stack > current_param_size)
1049       { /* check again after allocation */
1050         overflow("parameter stack size", current_param_size);
1051         return;     // abort_flag set
1052       }
1053 #else
1054       if (max_param_stack > param_size)
1055       {
1056         overflow("parameter stack size", param_size); /* parameter stack - not dynamic */
1057         return;     // abort_flag set
1058       }
1059 #endif
1060     }
1061     for (m = 0; m <= n - 1; m++)
1062       param_stack[param_ptr + m] = pstack[m];
1063     param_ptr = param_ptr + n;
1064   }
1065 lab10:
1066   scanner_status = savescannerstatus;
1067   warning_index = savewarningindex;
1068 }
1069 /* sec 0379 */
1070 void insert_relax (void) 
1071 {
1072   cur_tok = 4095 + cur_cs;
1073   back_input();
1074 /*  cur_tok = (hash_size + 4616);  */
1075 /*  cur_tok = (hash_size + 4095 + 521);  */
1076   cur_tok = (hash_size + hash_extra + 4095 + 521);  /* 96/Jan/10 */
1077   back_input();
1078   cur_input.index_field = inserted;
1079 }
1080 /* sec 0366 */
1081 void expand (void)
1082 {
1083   halfword t;
1084   halfword p, q, r;
1085   integer j;
1086   integer cvbackup;
1087   small_number cvlbackup, radixbackup, cobackup;
1088   halfword backupbackup;
1089   small_number savescannerstatus;
1090
1091   cvbackup = cur_val;
1092   cvlbackup = cur_val_level;
1093   radixbackup = radix;
1094   cobackup = cur_order;
1095   backupbackup = link(backup_head);
1096   if (cur_cmd < call)
1097   {
1098     if (tracing_commands > 1)
1099       show_cur_cmd_chr();
1100     switch (cur_cmd)
1101     {
1102       case top_bot_mark:
1103         if (cur_mark[cur_chr] != 0)
1104           begin_token_list(cur_mark[cur_chr], mark_text);
1105         break;
1106       case expand_after:
1107         get_token();
1108         t = cur_tok;
1109         get_token();
1110         if (cur_cmd > max_command)
1111           expand();
1112         else
1113           back_input();
1114         cur_tok = t;
1115         back_input();
1116         break;
1117       case no_expand:
1118         savescannerstatus = scanner_status;
1119         scanner_status = normal;
1120         get_token();
1121         scanner_status = savescannerstatus;
1122         t = cur_tok;
1123         back_input();
1124         if (t >= 4095)   /* if t>=cs_token_flag then */
1125         {
1126 /*   begin p:=get_avail; info(p):=cs_token_flag+frozen_dont_expand; */
1127           p = get_avail();
1128 /*    mem[p].hh.v.LH = (hash_size + 4618);  */
1129 /*    mem[p].hh.v.LH = (hash_size + 4095 + 523); */
1130           mem[p].hh.v.LH = (hash_size + hash_extra + 4095 + 523); /*96/Jan/10*/
1131           mem[p].hh.v.RH = cur_input.loc_field;
1132           cur_input.start_field = p;
1133           cur_input.loc_field = p;
1134         }
1135         break;
1136       case cs_name:
1137         r = get_avail();
1138         p = r;
1139         do {
1140           get_x_token();
1141           if (cur_cs == 0)
1142           {
1143             q = get_avail();
1144             mem[p].hh.v.RH = q;
1145             mem[q].hh.v.LH = cur_tok;
1146             p = q;
1147           }
1148         } while(!(cur_cs != 0));
1149         if (cur_cmd != end_cs_name)
1150         {
1151           print_err("Missing ");
1152           print_esc("endcsname");
1153           print_string(" inserted");
1154           help2("The control sequence marked <to be read again> should",
1155               "not appear between \\csname and \\endcsname.");
1156           back_error();
1157         }
1158         j = first;
1159         p = link(r);
1160         while (p != 0) {  /* while p<>null do l.7742 */
1161           if (j >= max_buf_stack)
1162           {
1163             max_buf_stack = j + 1;
1164 #ifdef ALLOCATEBUFFER
1165             if (max_buf_stack == current_buf_size)
1166               buffer = realloc_buffer (increment_buf_size);
1167             if (max_buf_stack == current_buf_size)
1168             {  /* check again after allocation */
1169               overflow("buffer size", current_buf_size);
1170               return;     // abort_flag set
1171             }
1172 #else
1173             if (max_buf_stack == buf_size)
1174             {
1175               overflow("buffer size", buf_size); /* buffer size - not dynamic */
1176               return;     // abort_flag set
1177             }
1178 #endif
1179           }
1180           buffer[j] = info(p) % 256;
1181           incr(j);
1182           p = link(p);
1183         }
1184         if (j > first + 1)
1185         {
1186           no_new_control_sequence = false;
1187           cur_cs = id_lookup(first, j - first);
1188           no_new_control_sequence = true;
1189         }
1190         else if (j == first)
1191           cur_cs = null_cs;
1192         else
1193           cur_cs = single_base + buffer[first];
1194         flush_list(r);
1195         if (eq_type(cur_cs) == undefined_cs)
1196         {
1197           eq_define(cur_cs, relax, 256);
1198         }
1199         cur_tok = cur_cs + 4095;
1200         back_input();
1201         break;
1202       case convert:
1203         conv_toks();
1204         break;
1205       case the:
1206         ins_the_toks();
1207         break;
1208       case if_test:
1209         conditional();
1210         break;
1211       case fi_or_else:
1212         if (cur_chr > if_limit)
1213           if (if_limit == 1)
1214             insert_relax();
1215           else
1216           {
1217             print_err("Extra ");
1218             print_cmd_chr(fi_or_else, cur_chr);
1219             help1("I'm ignoring this; it doesn't match any \\if.");
1220             error();
1221           }
1222         else
1223         {
1224           while(cur_chr != 2)
1225             pass_text();
1226           {
1227             p = cond_ptr;
1228             if_line = mem[p + 1].cint;
1229             cur_if = mem[p].hh.b1;
1230             if_limit = mem[p].hh.b0;
1231             cond_ptr = mem[p].hh.v.RH;
1232             free_node(p, 2);
1233           }
1234         }
1235         break;
1236       case input:
1237         if (cur_chr > 0)
1238           force_eof = true;
1239         else if (name_in_progress)
1240           insert_relax();
1241         else start_input();
1242         break;
1243       default:
1244         print_err("Undefined control sequence");
1245         help5("The control sequence at the end of the top line",
1246             "of your error message was never \\def'ed. If you have",
1247             "misspelled it (e.g., `\\hobx'), type `I' and the correct",
1248             "spelling (e.g., `I\\hbox'). Otherwise just continue,",
1249             "and I'll forget about whatever was undefined.");
1250         error();
1251         break;
1252     }
1253   }
1254   else if (cur_cmd < end_template)
1255   {
1256     macro_call();
1257   }
1258   else
1259   {
1260 /*    cur_tok = (hash_size + 4615);  */
1261 /*    cur_tok = (hash_size + 4095 + 520);  */
1262     cur_tok = (hash_size + hash_extra + 4095 + 520); /* 96/Jan/10 */
1263     back_input();
1264   }
1265   cur_val = cvbackup;
1266   cur_val_level = cvlbackup;
1267   radix = radixbackup;
1268   cur_order = cobackup;
1269   link(backup_head) = backupbackup;
1270 }
1271 /* sec 0380 */
1272 void get_x_token (void)
1273 {
1274 lab20:
1275   get_next();
1276   if (cur_cmd <= max_command)
1277     goto lab30;
1278   if (cur_cmd >= call)
1279     if (cur_cmd < end_template)
1280       macro_call();
1281     else {
1282 /*      cur_cs = (hash_size + 520);  */
1283       cur_cs = (hash_size + hash_extra + 520);  /* 96/Jan/10 */
1284       cur_cmd = endv;
1285       goto lab30;
1286     }
1287   else
1288     expand();
1289   goto lab20;
1290 lab30:
1291   if (cur_cs == 0)
1292     cur_tok = (cur_cmd * 256) + cur_chr;
1293   else
1294     cur_tok = 4095 + cur_cs;
1295 }
1296 /* sec 0381 */
1297 void x_token (void)
1298 {
1299   while (cur_cmd > max_command) {
1300     expand();
1301     get_next();
1302   }
1303   if (cur_cs == 0)
1304     cur_tok = (cur_cmd * 256) + cur_chr;
1305   else
1306     cur_tok = 4095 + cur_cs;
1307 }
1308 /* sec 0403 */
1309 void scan_left_brace (void)
1310 {
1311   do {
1312       get_x_token();
1313   } while(!((cur_cmd != spacer) && (cur_cmd != relax)));
1314
1315   if (cur_cmd != left_brace)
1316   {
1317     print_err("Missing { inserted");
1318     help4("A left brace was mandatory here, so I've put one in.",
1319         "You might want to delete and/or insert some corrections",
1320         "so that I will find a matching right brace soon.",
1321         "(If you're confused by all this, try typing `I}' now.)");
1322     back_error();
1323     cur_tok = 379;
1324     cur_cmd = left_brace;
1325     cur_chr = '{';
1326     incr(align_state);
1327   }
1328 }
1329 /* sec 0405 */
1330 void scan_optional_equals (void)
1331 {
1332   do {
1333       get_x_token();
1334   } while(!(cur_cmd != spacer));
1335
1336   if (cur_tok != 3133)
1337     back_input();
1338 }
1339 /* sec 0407 */
1340 bool scan_keyword_(char * s)
1341 {
1342   register bool Result;
1343   halfword p;
1344   halfword q;
1345   char * k;
1346
1347   p = backup_head;
1348   link(p) = 0;
1349   k = s;
1350
1351   while (*k) {
1352     get_x_token(); 
1353     if ((cur_cs == 0) && ((cur_chr == (*k)) || (cur_chr == (*k) - 32)))
1354     {
1355       {
1356         q = get_avail();
1357         mem[p].hh.v.RH = q;
1358         mem[q].hh.v.LH = cur_tok;
1359         p = q;
1360       }
1361       incr(k);
1362     }
1363     else if ((cur_cmd != spacer) || (p != backup_head))
1364     {
1365       back_input();
1366       if (p != backup_head)
1367         begin_token_list(link(backup_head), 3);
1368       Result = false;
1369       return(Result);
1370     }
1371   }
1372   flush_list(link(backup_head));
1373   Result = true;
1374   return Result;
1375 }
1376 /* sec 0408 */
1377 void mu_error (void)
1378 {
1379   print_err("Incompatible glue units");
1380   help1("I'm going to assume that 1mu=1pt when they're mixed.");
1381   error();
1382 }
1383 /* sec 0433 */
1384 void scan_eight_bit_int (void)
1385 {
1386   scan_int();
1387   if ((cur_val < 0) || (cur_val > 255))
1388   {
1389     print_err("Bad register code");
1390     help2("A register number must be between 0 and 255.",
1391         "I changed this one to zero.");
1392     int_error(cur_val);
1393     cur_val = 0;
1394   }
1395 }
1396 /* sec 0434 */
1397 void scan_char_num (void)
1398 {
1399   scan_int();
1400   if ((cur_val < 0) || (cur_val > 255))
1401   {
1402     print_err("Bad character code");
1403     help2("A character number must be between 0 and 255.",
1404         "I changed this one to zero.");
1405     int_error(cur_val);
1406     cur_val = 0;
1407   }
1408 }
1409 /* sec 0435 */
1410 void scan_four_bit_int (void)
1411 {
1412   scan_int();
1413   if ((cur_val < 0) || (cur_val > 15))
1414   {
1415     print_err("Bad number");
1416     help2("Since I expected to read a number between 0 and 15,",
1417         "I changed this one to zero.");
1418     int_error(cur_val);
1419     cur_val = 0;
1420   }
1421 }
1422 /* sec 0436 */
1423 void scan_fifteen_bit_int (void) 
1424 {
1425   scan_int();
1426   if ((cur_val < 0) || (cur_val > 32767))
1427   {
1428     print_err("Bad mathchar");
1429     help2("A mathchar number must be between 0 and 32767.",
1430         "I changed this one to zero.");
1431     int_error(cur_val);
1432     cur_val = 0;
1433   }
1434 }
1435 /* sec 0437 */
1436 void scan_twenty_seven_bit_int (void)
1437 {
1438   scan_int();
1439   if ((cur_val < 0) || (cur_val > 134217727L)) /* 2^27 - 1 */
1440   {
1441     print_err("Bad delimiter code");
1442     help2("A numeric delimiter code must be between 0 and 2^{27}-1.",
1443         "I changed this one to zero.");
1444     int_error(cur_val);
1445     cur_val = 0;
1446   }
1447 }
1448 /* sec 0577 */
1449 void scan_font_ident (void) 
1450 {
1451   internal_font_number f;
1452   halfword m;
1453
1454   do {
1455       get_x_token();
1456   } while (!(cur_cmd != spacer));
1457
1458   if (cur_cmd == def_font)
1459     f = cur_font;
1460   else if (cur_cmd == set_font)
1461     f = cur_chr; 
1462   else if (cur_cmd == def_family)
1463   {
1464     m = cur_chr;
1465     scan_four_bit_int();
1466     f = equiv(m + cur_val);
1467   }
1468   else
1469   {
1470     print_err("Missing font identifier");
1471     help2("I was looking for a control sequence whose",
1472         "current meaning has been defined by \\font.");
1473     back_error();
1474     f = 0;
1475   }
1476   cur_val = f;
1477 }
1478 /* sec 0578 */
1479 void find_font_dimen_(bool writing)
1480 {
1481   internal_font_number f;
1482   integer n;
1483
1484   scan_int();
1485   n = cur_val;
1486   scan_font_ident();
1487   f = cur_val;
1488 /*  if (n <= 0)*/            /* change 98/Oct/5 */
1489   if (n < 0 || (n == 0 && font_dimen_zero == 0))
1490     cur_val = fmem_ptr;
1491   else
1492   {
1493 /* else  begin if writing and(n<=space_shrink_code)and@|
1494     (n>=space_code)and(font_glue[f]<>null) then
1495     begin delete_glue_ref(font_glue[f]); l.11225 */
1496     if (writing && (n <= 4) && (n >= 2) && (font_glue[f]!= 0)) 
1497     {
1498       delete_glue_ref(font_glue[f]);
1499       font_glue[f]= 0;  /* font_glue[f]:=null */
1500     }
1501     if (n > font_params[f])
1502       if (f < font_ptr)
1503         cur_val = fmem_ptr;
1504     else
1505     {
1506       do {
1507 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1508  #ifdef ALLOCATEFONT
1509         if (fmem_ptr == current_font_mem_size)
1510         { /* 93/Nov/28 ??? */
1511           font_info = realloc_font_info(increment_font_mem_size);
1512         }
1513         if (fmem_ptr == current_font_mem_size)
1514         {    /* 94/Jan/24 */
1515           overflow("font memory", current_font_mem_size); /* font memory */
1516           return;     // abort_flag set
1517         }
1518 #else
1519 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1520         if (fmem_ptr == font_mem_size)
1521         {
1522           overflow("font memory", font_mem_size); /* font memory */
1523           return;     // abort_flag set
1524         }
1525 #endif
1526         font_info[fmem_ptr].cint = 0;
1527         incr(fmem_ptr);
1528         incr(font_params[f]);
1529       } while(!(n == font_params[f]));
1530       cur_val = fmem_ptr - 1;
1531     }
1532 /*  else cur_val = n + param_base[f];   */      /* 98/Oct/5 */
1533   else if (n > 0)
1534     cur_val = n + param_base[f];    /* 98/Oct/5 */
1535   else cur_val = &font_check[f] - &font_info[0]; /* 98/Oct/5 */
1536 /*  checksum =  (((font_check[f].b0) << 8 | font_check[f].b1) << 8 |
1537         font_check[f].b2) << 8 | font_check[f].b3; */
1538   } 
1539 /* compiler error: '-' : incompatible types - from 'union fmemoryword *' to 'struct fourunsignedchars *' */
1540   if (cur_val == fmem_ptr)
1541   {
1542     print_err("Font ");
1543 /*    print_esc(hash[(hash_size + 524) + f].v.RH); */
1544     //print_esc(hash[(hash_size + hash_extra + 524) + f].v.RH); /*96/Jan/10*/
1545     print_esc(""); print(hash[(hash_size + hash_extra + 524) + f].v.RH);
1546     print_string(" has only ");
1547     print_int(font_params[f]);
1548     print_string(" fontdimen parameters");
1549     help2("To increase the number of font parameters, you must",
1550       "use \\fontdimen immediately after the \\font is loaded.");
1551     error();
1552   }
1553 }
1554 /* NOTE: the above use of /fontdimen0 to access the checksum is a kludge */
1555 /* In future would be better to do this by allocating one more slot for */
1556 /* for parameters when a font is read rather than carry checksum separately */
1557 /* The above gets the value byte order reversed ... 98/Oct/5 */
1558 /* sec 0413 */
1559 void scan_something_internal_(small_number level, bool negative)
1560 {
1561   halfword m;
1562   integer p;
1563   m = cur_chr;
1564
1565   switch (cur_cmd)
1566   {
1567     case def_code:
1568       scan_char_num();
1569       if (m == math_code_base)
1570       {
1571         cur_val = math_code(cur_val);
1572         cur_val_level = 0;
1573       }
1574       else if (m < math_code_base)
1575       {
1576         cur_val = equiv(m + cur_val);
1577         cur_val_level = 0;
1578       }
1579       else
1580       {
1581         cur_val = eqtb[m + cur_val].cint;
1582         cur_val_level = 0;
1583       }
1584       break;
1585   case toks_register:
1586   case assign_toks:
1587   case def_family:
1588   case set_font:
1589   case def_font:
1590     if (level != 5)
1591     {
1592       print_err("Missing number, treated as zero");
1593       help3("A number should have been here; I inserted `0'.",
1594           "(If you can't figure out why I needed to see a number,",
1595           "look up `weird error' in the index to The TeXbook.)");
1596       back_error();
1597       {
1598         cur_val = 0;
1599         cur_val_level = 1;
1600       }
1601     }
1602     else if (cur_cmd <= assign_toks)
1603     {
1604       if (cur_cmd < assign_toks)
1605       {
1606         scan_eight_bit_int();
1607         m = toks_base + cur_val;
1608       }
1609       {
1610         cur_val = eqtb[m].hh.v.RH;
1611         cur_val_level = 5;
1612       }
1613     } 
1614     else
1615     {
1616       back_input();
1617       scan_font_ident();
1618       {
1619 /*  cur_val = (hash_size + 524) + cur_val;  */
1620         cur_val = (hash_size + hash_extra + 524) + cur_val; /* 96/Jan/10 */
1621         cur_val_level = 4;
1622       }
1623     }
1624     break;
1625   case assign_int:
1626     {
1627       cur_val = eqtb[m].cint;
1628       cur_val_level = 0;
1629     }
1630     break;
1631   case assign_dimen:
1632     {
1633       cur_val = eqtb[m].cint;
1634       cur_val_level = 1;
1635     }
1636     break; 
1637   case assign_glue:
1638     {
1639       cur_val = eqtb[m].hh.v.RH;
1640       cur_val_level = 2;
1641     }
1642     break;
1643   case assign_mu_glue:
1644     {
1645       cur_val = eqtb[m].hh.v.RH;
1646       cur_val_level = 3;
1647     }
1648     break;
1649   case set_aux:
1650     if (abs(mode)!= m)
1651     {
1652       print_err("Improper ");
1653       print_cmd_chr(set_aux, m);
1654       help4("You can refer to \\spacefactor only in horizontal mode;",
1655           "you can refer to \\prevdepth only in vertical mode; and",
1656           "neither of these is meaningful inside \\write. So",
1657           "I'm forgetting what you said and using zero instead.");
1658       error();
1659       if (level != 5)
1660       {
1661         cur_val = 0;
1662         cur_val_level = 1;
1663       }
1664       else
1665       {
1666         cur_val = 0;
1667         cur_val_level = 0;
1668       }
1669     }
1670     else if (m == 1)
1671     {
1672       cur_val = cur_list.aux_field.cint;
1673       cur_val_level = 1;
1674     } 
1675     else
1676     {
1677       cur_val = space_factor;
1678       cur_val_level = 0;
1679     }
1680     break;
1681   case set_prev_graf:
1682     if (mode == 0)
1683     {
1684       cur_val = 0;
1685       cur_val_level = 0;
1686     }
1687     else
1688     {
1689       nest[nest_ptr] = cur_list;
1690       p = nest_ptr;
1691       while (abs(nest[p].mode_field)!= 1)
1692         decr(p);
1693       {
1694         cur_val = nest[p].pg_field;
1695         cur_val_level = 0;
1696       }
1697     }
1698     break;
1699   case set_page_int:
1700     {
1701       if (m == 0)
1702         cur_val = dead_cycles; 
1703       else
1704         cur_val = insert_penalties;
1705       cur_val_level = 0;
1706     }
1707     break;
1708   case set_page_dimen:
1709     {
1710       if ((page_contents == 0) && (! output_active))
1711         if (m == 0)
1712           cur_val = 1073741823L;  /* 2^30 - 1 */
1713         else
1714           cur_val = 0;
1715       else
1716         cur_val = page_so_far[m];
1717       cur_val_level = 1;
1718     }
1719     break;
1720   case set_shape:
1721     {
1722       if (par_shape_ptr == 0)
1723         cur_val = 0; 
1724       else
1725         cur_val = mem[par_shape_ptr].hh.v.LH;
1726       cur_val_level = 0;
1727     }
1728     break;
1729   case set_box_dimen:
1730     {
1731       scan_eight_bit_int();
1732       if (eqtb[box_base + cur_val].hh.v.RH == 0)
1733         cur_val = 0;
1734       else
1735         cur_val = mem[eqtb[(hash_size + 1578) + cur_val].hh.v.RH + m].cint;
1736       cur_val_level = 1;
1737     }
1738     break;
1739   case char_given:
1740   case math_given:
1741     {
1742       cur_val = cur_chr;
1743       cur_val_level = 0;
1744     }
1745     break;
1746   case assign_font_dimen:
1747     {
1748       find_font_dimen(false);
1749       font_info[fmem_ptr].cint = 0;
1750       {
1751         cur_val = font_info[cur_val].cint;
1752         cur_val_level = 1;
1753       }
1754     }
1755     break;
1756   case assign_font_int:
1757     {
1758       scan_font_ident();
1759       if (m == 0)
1760       {
1761         cur_val = hyphen_char[cur_val];
1762         cur_val_level = 0;
1763       }
1764       else
1765       {
1766         cur_val = skew_char[cur_val];
1767         cur_val_level = 0;
1768       }
1769     }
1770     break;
1771   case tex_register:
1772     {
1773       scan_eight_bit_int();
1774       switch(m)
1775       {
1776         case 0:
1777           cur_val = eqtb[(hash_size + 3218) + cur_val].cint;
1778           break;
1779         case 1:
1780           cur_val = eqtb[(hash_size + 3751) + cur_val].cint;
1781           break;
1782         case 2:
1783           cur_val = eqtb[(hash_size + 800) + cur_val].hh.v.RH;
1784           break;
1785         case 3:
1786           cur_val = eqtb[(hash_size + 1056) + cur_val].hh.v.RH;
1787           break;
1788       }
1789       cur_val_level = m;
1790     }
1791     break;
1792   case last_item:
1793     if (cur_chr > 2)
1794     {
1795       if (cur_chr == 3)
1796         cur_val = line;
1797       else
1798         cur_val = last_badness;
1799       cur_val_level = 0;
1800     }
1801     else
1802     {
1803       if (cur_chr == 2)
1804         cur_val = 0;
1805       else
1806         cur_val = 0;
1807       cur_val_level = cur_chr;
1808       if (!(tail >= hi_mem_min) && (mode != 0))
1809         switch(cur_chr)
1810         {
1811           case 0:
1812             if (mem[tail].hh.b0 == 12)
1813               cur_val = mem[tail + 1].cint;
1814             break;
1815           case 1:
1816             if (mem[tail].hh.b0 == 11)
1817               cur_val = mem[tail + 1].cint;
1818             break;
1819           case 2:
1820             if (mem[tail].hh.b0 == 10)
1821             {
1822               cur_val = mem[tail + 1].hh.v.LH;
1823               if (mem[tail].hh.b1 == 99)
1824                 cur_val_level = 3;
1825             }
1826             break;
1827         }
1828       else if ((mode == 1) && (tail == cur_list.head_field))
1829         switch (cur_chr)
1830         {
1831           case 0:
1832             cur_val = last_penalty;
1833             break;
1834           case 1:
1835             cur_val = last_kern;
1836             break;
1837           case 2:
1838 /*  if (last_glue != 262143L) */ /* NO! */
1839             if (last_glue != empty_flag)
1840               cur_val = last_glue;
1841             break;
1842         }
1843     }
1844     break;
1845   default:
1846     {
1847       print_err("You can't use `");
1848       print_cmd_chr(cur_cmd, cur_chr);
1849       print_string("' after ");
1850       print_esc("the");
1851       help1("I'm forgetting what you said and using zero instead.");
1852       error();
1853       if (level != 5)
1854       {
1855         cur_val = 0;
1856         cur_val_level = 1;
1857       }
1858       else
1859       {
1860         cur_val = 0;
1861         cur_val_level = 0;
1862       }
1863     }
1864     break;
1865   }
1866   while (cur_val_level > level) {
1867     if (cur_val_level == 2)
1868       cur_val = mem[cur_val + 1].cint;
1869     else if (cur_val_level == 3)
1870     {
1871       mu_error();
1872     }
1873     decr(cur_val_level);
1874   }
1875   if (negative)
1876     if (cur_val_level >= 2)
1877     {
1878       cur_val = new_spec(cur_val);
1879       {
1880         mem[cur_val + 1].cint = - (integer) mem[cur_val + 1].cint;
1881         mem[cur_val + 2].cint = - (integer) mem[cur_val + 2].cint;
1882         mem[cur_val + 3].cint = - (integer) mem[cur_val + 3].cint;
1883       }
1884     }
1885     else cur_val = - (integer) cur_val;
1886   else if ((cur_val_level >= 2) && (cur_val_level <= 3))
1887     incr(mem[cur_val].hh.v.RH);
1888 }
1889
1890 /*****************************************************************************/
1891
1892 /* Moved here to avoid question about pragma optimize 96/Sep/12 */
1893 /* sec 0341 */
1894 void get_next (void)
1895 {
1896   integer k;
1897   halfword t;
1898 /*  char cat; */    /* make this an int ? */
1899   int cat;      /* make this an int ? 95/Jan/7 */
1900   ASCII_code c, cc;
1901   char d;
1902
1903 lab20:
1904   cur_cs = 0; 
1905   if (cur_input.state_field != token_list)
1906   {
1907 lab25:
1908     if (cur_input.loc_field <= cur_input.limit_field)
1909     {
1910       cur_chr = buffer[cur_input.loc_field];
1911       incr(cur_input.loc_field);
1912 lab21:
1913       cur_cmd = cat_code(cur_chr);
1914       switch (cur_input.state_field + cur_cmd)
1915       {
1916         case any_state_plus(ignore):
1917         case skip_blanks + spacer:
1918         case new_line + spacer:
1919           goto lab25;
1920           break;
1921         case any_state_plus(escape):
1922           {
1923             if (cur_input.loc_field > cur_input.limit_field)
1924               cur_cs = null_cs;
1925             else
1926             {
1927 lab26:
1928               k = cur_input.loc_field;
1929               cur_chr = buffer[k];
1930               cat = cat_code(cur_chr);
1931               incr(k);
1932               if (cat == letter)
1933                 cur_input.state_field = skip_blanks;
1934               else if (cat == spacer)
1935                 cur_input.state_field = skip_blanks;
1936               else
1937                 cur_input.state_field = mid_line;
1938
1939               if ((cat == letter) && (k <= cur_input.limit_field))
1940               {
1941                 do {
1942                   cur_chr = buffer[k];
1943                   cat = cat_code(cur_chr);
1944                   incr(k);
1945                 } while(!((cat != letter) || (k > cur_input.limit_field)));
1946                 {
1947                   if (buffer[k]== cur_chr)
1948                     if (cat == sup_mark)
1949                       if (k < cur_input.limit_field)
1950                       {
1951                         c = buffer[k + 1];
1952                         if (c < 128)
1953                         {
1954                           d = 2;
1955                           if ((((c >= 48) && (c <= 57)) ||
1956                                 ((c >= 97) && (c <= 102))))
1957                             if (k + 2 <= cur_input.limit_field)
1958                             {
1959                               cc = buffer[k + 2];
1960                               if ((((cc >= 48) && (cc <= 57)) ||
1961                                     ((cc >= 97) && (cc <= 102))))
1962                                 incr(d);
1963                             }
1964                           if (d > 2)
1965                           {
1966                             if (c <= 57)
1967                               cur_chr = c - 48;
1968                             else
1969                               cur_chr = c - 87;
1970                             if (cc <= 57)
1971                               cur_chr = 16 * cur_chr + cc - 48;
1972                             else
1973                               cur_chr = 16 * cur_chr + cc - 87;
1974                             buffer[k - 1] = cur_chr;
1975                           }
1976                           else if (c < 64)
1977                             buffer[k - 1] = c + 64;
1978                           else
1979                             buffer[k - 1] = c - 64;
1980                           cur_input.limit_field = cur_input.limit_field - d;
1981                           first = first - d;
1982                           while (k <= cur_input.limit_field) {
1983                             buffer[k] = buffer[k + d];
1984                             incr(k);
1985                           }
1986                           goto lab26;
1987                         }
1988                       }
1989                 }
1990                 if (cat != letter)
1991                   decr(k);
1992                 if (k > cur_input.loc_field + 1)
1993                 {
1994                   cur_cs = id_lookup(cur_input.loc_field, k - cur_input.loc_field);
1995                   cur_input.loc_field = k;
1996                   goto lab40;
1997                 }
1998               }
1999               else
2000               {
2001                 if (buffer[k] == cur_chr)
2002                   if (cat == sup_mark)
2003                     if (k < cur_input.limit_field)
2004                     {
2005                       c = buffer[k + 1];
2006                       if (c < 128)             /* ? */
2007                       {
2008                         d = 2;
2009                         if ((((c >= 48) && (c <= 57)) ||
2010                               ((c >= 97) && (c <= 102))))
2011                           if (k + 2 <= cur_input.limit_field)
2012                           {
2013                             cc = buffer[k + 2];
2014                             if ((((cc >= 48) && (cc <= 57)) ||
2015                                   ((cc >= 97) && (cc <= 102))))
2016                               incr(d);
2017                           }
2018                         if (d > 2)
2019                         {
2020                           if (c <= 57)
2021                             cur_chr = c - 48;
2022                           else
2023                             cur_chr = c - 87;
2024                           if (cc <= 57)          /* cc may be used without ... */
2025                             cur_chr = 16 * cur_chr + cc - 48;
2026                           else
2027                             cur_chr = 16 * cur_chr + cc - 87;
2028                           buffer[k - 1] = cur_chr;
2029                         }
2030                         else if (c < 64)
2031                           buffer[k - 1] = c + 64;
2032                         else
2033                           buffer[k - 1] = c - 64;
2034                         cur_input.limit_field = cur_input.limit_field - d;
2035                         first = first - d;
2036                         while (k <= cur_input.limit_field) {
2037                           buffer[k] = buffer[k + d];
2038                           incr(k);
2039                         }
2040                         goto lab26;
2041                       }
2042                     }
2043               }
2044               cur_cs = single_base + buffer[cur_input.loc_field];
2045               incr(cur_input.loc_field);
2046             }
2047 lab40:
2048             cur_cmd = eq_type(cur_cs);
2049             cur_chr = equiv(cur_cs);
2050             
2051             if (cur_cmd >= outer_call)
2052             {
2053               check_outer_validity();
2054             }
2055           }
2056           break;
2057         case any_state_plus(active_char):
2058           {
2059             cur_cs = cur_chr + active_base;
2060             cur_cmd = eq_type(cur_cs);
2061             cur_chr = equiv(cur_cs);
2062             cur_input.state_field = mid_line;
2063             
2064             if (cur_cmd >= outer_call)
2065             {
2066               check_outer_validity();
2067             }
2068           }
2069           break;
2070         case any_state_plus(sup_mark):
2071           {
2072             if (cur_chr == buffer[cur_input.loc_field])
2073               if (cur_input.loc_field < cur_input.limit_field)
2074               {
2075                 c = buffer[cur_input.loc_field + 1];
2076                 if (c < 128)
2077                 {
2078                   cur_input.loc_field = cur_input.loc_field + 2;
2079                   if ((((c >= 48) && (c <= 57)) ||
2080                         ((c >= 97) && (c <= 102))))
2081                     if (cur_input.loc_field <= cur_input.limit_field)
2082                     {
2083                       cc = buffer[cur_input.loc_field];
2084                       if ((((cc >= 48) && (cc <= 57)) ||
2085                             ((cc >= 97) && (cc <= 102))))
2086                       {
2087                         incr(cur_input.loc_field);
2088                         if (c <= 57)
2089                           cur_chr = c - 48;
2090                         else
2091                           cur_chr = c - 87;
2092                         if (cc <= 57)
2093                           cur_chr = 16 * cur_chr + cc - 48;
2094                         else
2095                           cur_chr = 16 * cur_chr + cc - 87;
2096                         goto lab21;
2097                       }
2098                     }
2099                   if (c < 64)
2100                     cur_chr = c + 64;
2101                   else
2102                     cur_chr = c - 64;
2103                   goto lab21;
2104                 }
2105               }
2106             cur_input.state_field = mid_line;
2107           }
2108           break;
2109         case any_state_plus(invalid_char):
2110           {
2111             print_err("Text line contains an invalid character");
2112             help2("A funny symbol that I can't read has just been input.",
2113                 "Continue, and I'll forget that it ever happened.");
2114             deletions_allowed = false;
2115             error();
2116             deletions_allowed = true;
2117             goto lab20;
2118           }
2119           break;
2120         case mid_line + spacer:
2121           {
2122             cur_input.state_field = skip_blanks;
2123             cur_chr = ' ';
2124           }
2125           break;
2126         case mid_line + car_ret:
2127           {
2128             cur_input.loc_field = cur_input.limit_field + 1;
2129             cur_cmd = spacer;
2130             cur_chr = ' ';
2131           }
2132           break;
2133         case skip_blanks + car_ret:
2134         case any_state_plus(comment):
2135           {
2136             cur_input.loc_field = cur_input.limit_field + 1;
2137             goto lab25;
2138           }
2139           break;
2140         case new_line + car_ret:
2141           {
2142             cur_input.loc_field = cur_input.limit_field + 1;
2143             cur_cs = par_loc;
2144             cur_cmd = eq_type(cur_cs);
2145             cur_chr = equiv(cur_cs);
2146             
2147             if (cur_cmd >= outer_call)
2148             {
2149               check_outer_validity();
2150             }
2151           }
2152           break;
2153         case mid_line + left_brace:
2154           incr(align_state);
2155           break;
2156         case skip_blanks + left_brace:
2157         case new_line + left_brace:
2158           {
2159             cur_input.state_field = mid_line;
2160             incr(align_state);
2161           }
2162           break;
2163         case mid_line + right_brace:
2164           decr(align_state);
2165           break;
2166         case skip_blanks + right_brace:
2167         case new_line + right_brace:
2168           {
2169             cur_input.state_field = 1;
2170             decr(align_state);
2171           }
2172           break;
2173         case add_delims_to(skip_blanks):
2174         case add_delims_to(new_line):
2175           cur_input.state_field = 1;
2176           break;
2177         default:
2178           break;
2179       }
2180     }
2181     else
2182     {
2183       cur_input.state_field = new_line;
2184
2185       if (cur_input.name_field > 17)
2186       {
2187         incr(line);
2188         first = cur_input.start_field;
2189         if (!force_eof)
2190         {
2191           if (input_ln(input_file[cur_input.index_field], true))
2192           {
2193             firm_up_the_line();
2194           }
2195           else
2196             force_eof = true;
2197         }
2198
2199         if (force_eof)
2200         {
2201           print_char(')');
2202           decr(open_parens);
2203 #ifndef _WINDOWS
2204           fflush(stdout);
2205 #endif
2206           force_eof = false;
2207           end_file_reading();
2208           check_outer_validity();
2209           goto lab20;
2210         }
2211         if ((end_line_char < 0) || (end_line_char > 255))
2212           decr(cur_input.limit_field);
2213         else
2214           buffer[cur_input.limit_field] = end_line_char;
2215         first = cur_input.limit_field + 1;
2216         cur_input.loc_field = cur_input.start_field;
2217       }
2218       else
2219       {
2220         if (!(cur_input.name_field == 0))
2221         {
2222           cur_cmd = 0;
2223           cur_chr = 0;
2224           return;
2225         }
2226         if (input_ptr > 0)
2227         {
2228           end_file_reading();
2229           goto lab20;
2230         }
2231         if (selector < log_only)
2232           open_log_file();
2233         if (interaction > nonstop_mode)
2234         {
2235           if ((end_line_char < 0) || (end_line_char > 255))
2236             incr(cur_input.limit_field);
2237           if (cur_input.limit_field == cur_input.start_field)
2238             print_nl("(Please type a command or say `\\end')");
2239           print_ln();
2240           first = cur_input.start_field;
2241           {
2242             ;
2243             print_string("*");
2244             term_input("*", 0);
2245           }
2246           cur_input.limit_field = last;
2247           if ((end_line_char < 0) || (end_line_char > 255))
2248             decr(cur_input.limit_field);
2249           else
2250             buffer[cur_input.limit_field]= end_line_char;
2251           first = cur_input.limit_field + 1;
2252           cur_input.loc_field = cur_input.start_field;
2253         }
2254         else
2255         {
2256           fatal_error("*** (job aborted, no legal \\end found)");
2257           return;     // abort_flag set
2258         }
2259       }
2260       {
2261         if (interrupt != 0)
2262         {
2263           pause_for_instructions();
2264         }
2265       }
2266       goto lab25;
2267     }
2268   }
2269   else if (cur_input.loc_field != 0)
2270   {
2271     t = info(cur_input.loc_field);
2272     cur_input.loc_field = link(cur_input.loc_field);
2273     if (t >= 4095)
2274     {
2275       cur_cs = t - 4095;
2276       cur_cmd = eq_type(cur_cs);
2277       cur_chr = equiv(cur_cs);
2278       if (cur_cmd >= outer_call)
2279         if (cur_cmd == dont_expand)
2280         {
2281           cur_cs = info(cur_input.loc_field) - 4095;
2282           cur_input.loc_field = 0;
2283           cur_cmd = eq_type(cur_cs);
2284           cur_chr = equiv(cur_cs);
2285
2286           if (cur_cmd > max_command)
2287           {
2288             cur_cmd = relax;
2289             cur_chr = 257;
2290           }
2291         }
2292         else
2293         {
2294           check_outer_validity();
2295         }
2296     }
2297     else
2298     {
2299       cur_cmd = t / 256;
2300       cur_chr = t % 256;
2301       switch (cur_cmd)
2302       {
2303         case left_brace:
2304           incr(align_state);
2305           break;
2306         case right_brace:
2307           decr(align_state);
2308           break;
2309         case out_param:
2310           {
2311             begin_token_list(param_stack[cur_input.limit_field + cur_chr - 1], parameter);
2312             goto lab20;
2313           }
2314           break;
2315         default:
2316           break;
2317       }
2318     }
2319   }
2320   else
2321   {
2322     end_token_list();
2323     goto lab20;
2324   }
2325   if (cur_cmd <= car_ret)
2326     if (cur_cmd >= tab_mark)
2327       if (align_state == 0)
2328       {
2329         if ((scanner_status == aligning) && (cur_align == 0))
2330         {
2331           fatal_error("(interwoven alignment preambles are not allowed)");
2332           return;     // abort_flag set
2333         }
2334         cur_cmd = extra_info(cur_align);
2335         extra_info(cur_align) = cur_chr;
2336         if (cur_cmd == omit)
2337           begin_token_list(omit_template, v_template);
2338         else
2339           begin_token_list(v_part(cur_align), v_template);
2340         align_state = 1000000L;
2341         goto lab20;
2342       }
2343 }
2344 #pragma optimize ("", on)             /* 96/Sep/12 */