OSDN Git Service

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