OSDN Git Service

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