OSDN Git Service

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