1
4
5# include "luametatex.h"
6
7input_state_info lmt_input_state = {
8 .input_stack = NULL,
9 .input_stack_data = {
10 .minimum = min_stack_size,
11 .maximum = max_stack_size,
12 .size = siz_stack_size,
13 .step = stp_stack_size,
14 .allocated = 0,
15 .itemsize = sizeof(in_state_record),
16 .top = 0,
17 .ptr = 0,
18 .initial = memory_data_unset,
19 .offset = 0,
20 },
21 .in_stack = NULL,
22 .in_stack_data = {
23 .minimum = min_in_open,
24 .maximum = max_in_open,
25 .size = siz_in_open,
26 .step = stp_in_open,
27 .allocated = 0,
28 .itemsize = sizeof(input_stack_record),
29 .top = 0,
30 .ptr = 0,
31 .initial = memory_data_unset,
32 .offset = 0,
33 },
34 .parameter_stack = NULL,
35 .parameter_stack_data = {
36 .minimum = min_parameter_size,
37 .maximum = max_parameter_size,
38 .size = siz_parameter_size,
39 .step = stp_parameter_size,
40 .allocated = 0,
41 .itemsize = sizeof(halfword),
42 .top = 0,
43 .ptr = 0,
44 .initial = memory_data_unset,
45 .offset = 0,
46 },
47 .cur_input = { 0 },
48 .input_line = 0,
49 .scanner_status = 0,
50 .def_ref = 0,
51 .align_state = 0,
52 .base_ptr = 0,
53 .warning_index = 0,
54 .open_files = 0,
55 .padding = 0,
56} ;
57
58input_file_state_info input_file_state = {
59 .forced_file = 0,
60 .forced_line = 0,
61 .mode = 0,
62 .line = 0,
63};
64
65
69
70# define reserved_input_stack_slots 2
71# define reserved_in_stack_slots 2
72
73# define reserved_parameter_stack_slots (2 * max_match_count)
74
75void tex_initialize_input_state(void)
76{
77 {
78 int size = lmt_input_state.input_stack_data.minimum;
79 lmt_input_state.input_stack = aux_allocate_clear_array(sizeof(in_state_record), size, reserved_input_stack_slots);
80 if (lmt_input_state.input_stack) {
81 lmt_input_state.input_stack_data.allocated = size;
82 } else {
83 tex_overflow_error("input", size);
84 }
85 }
86 {
87 int size = lmt_input_state.in_stack_data.minimum;
88 lmt_input_state.in_stack = aux_allocate_clear_array(sizeof(input_stack_record), size, reserved_in_stack_slots);
89 if (lmt_input_state.in_stack) {
90 lmt_input_state.in_stack_data.allocated = size;
91 } else {
92 tex_overflow_error("file", size);
93 }
94 }
95 {
96 int size = lmt_input_state.parameter_stack_data.minimum;
97 lmt_input_state.parameter_stack = aux_allocate_clear_array(sizeof(halfword), size, reserved_parameter_stack_slots);
98 if (lmt_input_state.parameter_stack) {
99 lmt_input_state.parameter_stack_data.allocated = size;
100 } else {
101 tex_overflow_error("parameter", size);
102 }
103 }
104}
105
106static bool tex_aux_room_on_input_stack(void)
107{
108 int top = lmt_input_state.input_stack_data.ptr;
109 if (top > lmt_input_state.input_stack_data.top) {
110 lmt_input_state.input_stack_data.top = top;
111 if (top > lmt_input_state.input_stack_data.allocated) {
112 in_state_record *tmp = NULL;
113 top = lmt_input_state.input_stack_data.allocated + lmt_input_state.input_stack_data.step;
114 if (top > lmt_input_state.input_stack_data.size) {
115 top = lmt_input_state.input_stack_data.size;
116 }
117 if (top > lmt_input_state.input_stack_data.allocated) {
118 lmt_input_state.input_stack_data.allocated = top;
119 tmp = aux_reallocate_array(lmt_input_state.input_stack, sizeof(in_state_record), top, reserved_input_stack_slots);
120 lmt_input_state.input_stack = tmp;
121 }
122 lmt_run_memory_callback("input", tmp ? 1 : 0);
123 if (! tmp) {
124 tex_overflow_error("input", top);
125 return false;
126 }
127 }
128 }
129 return true;
130}
131
132static bool tex_aux_room_on_in_stack(void)
133{
134 int top = lmt_input_state.in_stack_data.ptr;
135 if (top > lmt_input_state.in_stack_data.top) {
136 lmt_input_state.in_stack_data.top = top;
137 if (top > lmt_input_state.in_stack_data.allocated) {
138 input_stack_record *tmp = NULL;
139 top = lmt_input_state.in_stack_data.allocated + lmt_input_state.in_stack_data.step;
140 if (top > lmt_input_state.in_stack_data.size) {
141 top = lmt_input_state.in_stack_data.size;
142 }
143 if (top > lmt_input_state.in_stack_data.allocated) {
144 lmt_input_state.in_stack_data.allocated = top;
145 tmp = aux_reallocate_array(lmt_input_state.in_stack, sizeof(input_stack_record), top, reserved_in_stack_slots);
146 lmt_input_state.in_stack = tmp;
147 }
148 lmt_run_memory_callback("file", tmp ? 1 : 0);
149 if (! tmp) {
150 tex_overflow_error("file", top);
151 return false;
152 }
153 }
154 }
155 return true;
156}
157
158static bool tex_aux_room_on_parameter_stack(void)
159{
160 int top = lmt_input_state.parameter_stack_data.ptr;
161 if (top > lmt_input_state.parameter_stack_data.top) {
162 lmt_input_state.parameter_stack_data.top = top;
163 if (top > lmt_input_state.parameter_stack_data.allocated) {
164 halfword *tmp = NULL;
165 top = lmt_input_state.parameter_stack_data.allocated + lmt_input_state.parameter_stack_data.step;
166 if (top > lmt_input_state.parameter_stack_data.size) {
167 top = lmt_input_state.parameter_stack_data.size;
168 }
169 if (top > lmt_input_state.parameter_stack_data.allocated) {
170 lmt_input_state.parameter_stack_data.allocated = top;
171 tmp = aux_reallocate_array(lmt_input_state.parameter_stack, sizeof(halfword), top, reserved_parameter_stack_slots);
172 lmt_input_state.parameter_stack = tmp;
173 }
174 lmt_run_memory_callback("parameter", tmp ? 1 : 0);
175 if (! tmp) {
176 tex_overflow_error("parameter", top);
177 return false;
178 }
179 }
180 }
181 return true;
182}
183
184void tex_copy_to_parameter_stack(halfword *pstack, int n)
185{
186 if (tex_aux_room_on_parameter_stack()) {
187if (n == 1) {
188 lmt_input_state.parameter_stack[lmt_input_state.parameter_stack_data.ptr++] = pstack[0];
189
190
191
192} else {
193 memcpy(&lmt_input_state.parameter_stack[lmt_input_state.parameter_stack_data.ptr], pstack, n * sizeof(halfword));
194 lmt_input_state.parameter_stack_data.ptr += n;
195}
196 }
197}
198
199
221
222void tex_show_validity(void)
223{
224 halfword p = null;
225 switch (lmt_input_state.scanner_status) {
226 case scanner_is_defining:
227 p = lmt_input_state.def_ref;
228 break;
229 case scanner_is_matching:
230 case scanner_is_tolerant:
231 p = tex_expand_match_token_head();
232 break;
233 case scanner_is_aligning:
234 p = tex_alignment_hold_token_head();
235 break;
236 case scanner_is_absorbing:
237 p = lmt_input_state.def_ref;
238 break;
239 }
240 if (p) {
241 tex_print_ln();
242 tex_token_show(p);
243 tex_print_ln();
244 }
245}
246
247void tex_show_runaway(void)
248{
249 if (lmt_input_state.scanner_status > scanner_is_skipping) {
250 tex_print_nlp();
251 switch (lmt_input_state.scanner_status) {
252 case scanner_is_defining:
253 tex_print_str("We ran into troubles when scanning a definition.");
254 break;
255 case scanner_is_matching:
256 tex_print_str("We ran into troubles scanning an argument.");
257 break;
258 case scanner_is_tolerant:
259 return;
260 case scanner_is_aligning:
261 tex_print_str("We ran into troubles scanning an alignment preamle.");
262 break;
263 case scanner_is_absorbing:
264 tex_print_str("We ran into troubles absorbing something.");
265 break;
266 default:
267 return;
268 }
269 tex_print_nlp();
270 tex_show_validity();
271 }
272}
273
274
311
312static void tex_aux_print_indent(void)
313{
314 for (int q = 1; q <= lmt_error_state.context_indent; q++) {
315 tex_print_char(' ');
316 }
317}
318
319static void tex_aux_print_current_input_state(void)
320{
321 int macro = 0;
322 tex_print_str("<");
323 if (lmt_input_state.cur_input.state == token_list_state) {
324 switch (lmt_input_state.cur_input.token_type) {
325 case parameter_text:
326 tex_print_str("argument");
327 break;
328 case template_pre_text:
329 tex_print_str("templatepre");
330 break;
331 case template_post_text:
332 tex_print_str("templatepost");
333 break;
334 case associated_text:
335 tex_print_str("associated");
336 break;
337 case backed_up_text:
338 tex_print_str(lmt_input_state.cur_input.loc ? "to be read again" : "recently read");
339 break;
340 case inserted_text:
341 tex_print_str("inserted text");
342 break;
343 case macro_text:
344 tex_print_str("macro");
345 macro = lmt_input_state.cur_input.name;
346 break;
347 case output_text:
348 tex_print_str("output");
349 break;
350 case every_par_text:
351 tex_print_str("everypar");
352 break;
353 case every_math_text:
354 tex_print_str("everymath");
355 break;
356 case every_display_text:
357 tex_print_str("everydisplay");
358 break;
359 case every_hbox_text:
360 tex_print_str("everyhbox");
361 break;
362 case every_vbox_text:
363 tex_print_str("everyvbox");
364 break;
365 case every_math_atom_text:
366 tex_print_str("everymathatom");
367 break;
368 case every_job_text:
369 tex_print_str("everyjob");
370 break;
371 case every_cr_text:
372 tex_print_str("everycr");
373 break;
374 case every_tab_text:
375 tex_print_str("everytab");
376 break;
377 case end_of_group_text:
378 tex_print_str("endofgroup");
379 break;
380 case mark_text:
381 tex_print_str("mark");
382 break;
383 case token_text:
384 tex_print_str("token");
385 break;
386 case loop_text:
387 tex_print_str("loop");
388 break;
389 case every_eof_text:
390 tex_print_str("everyeof");
391 break;
392 case every_before_par_text:
393 tex_print_str("everybeforepar");
394 break;
395 case end_paragraph_text:
396 tex_print_str("endpar");
397 break;
398 case end_file_text:
399 tex_print_str("endfile");
400 break;
401 case write_text:
402 tex_print_str("write");
403 break;
404 case local_text:
405 tex_print_str("local");
406 break;
407 case local_loop_text:
408 tex_print_str("localloop");
409 break;
410 default:
411 tex_print_str("unknown");
412 break;
413 }
414 } else {
415 switch (lmt_input_state.cur_input.name) {
416 case io_initial_input_code:
417 tex_print_str("initial input");
418 break;
419 case io_lua_input_code:
420 tex_print_str("lua input");
421 break;
422 case io_token_input_code:
423 tex_print_str("token input");
424 break;
425 case io_token_eof_input_code:
426 tex_print_str("token eof input");
427 break;
428 case io_tex_macro_code:
429 case io_file_input_code:
430 default:
431 {
432
433 tex_print_str("line ");
434 tex_print_int(lmt_input_state.cur_input.index);
435 tex_print_char('.');
436 tex_print_int(lmt_input_state.cur_input.index == lmt_input_state.in_stack_data.ptr ? lmt_input_state.input_line : lmt_input_state.in_stack[lmt_input_state.cur_input.index + 1].line);
437 }
438 break;
439 }
440 }
441 tex_print_str("> ");
442 if (macro) {
443 tex_print_cs_checked(macro);
444 }
445}
446
447
475
476void tex_set_trick_count(void)
477{
478 lmt_print_state.first_count = lmt_print_state.tally;
479 lmt_print_state.trick_count = lmt_print_state.tally + 1 + lmt_error_state.line_limits.size - lmt_error_state.half_line_limits.size;
480 if (lmt_print_state.trick_count < lmt_error_state.line_limits.size) {
481 lmt_print_state.trick_count = lmt_error_state.line_limits.size;
482 }
483}
484
485
492
493static void tex_aux_print_valid_utf8(int q)
494{
495 int l = lmt_error_state.line_limits.size;
496 int c = (int) lmt_print_state.trick_buffer[q % l];
497 if (c < 128) {
498 tex_print_char(c);
499 } else if (c < 194) {
500
501 } else if (c < 224) {
502 tex_print_char(c);
503 tex_print_char(lmt_print_state.trick_buffer[(q + 1) % l]);
504 } else if (c < 240) {
505 tex_print_char(c);
506 tex_print_char(lmt_print_state.trick_buffer[(q + 1) % l]);
507 tex_print_char(lmt_print_state.trick_buffer[(q + 2) % l]);
508 } else if (c < 245) {
509 tex_print_char(c);
510 tex_print_char(lmt_print_state.trick_buffer[(q + 1) % l]);
511 tex_print_char(lmt_print_state.trick_buffer[(q + 2) % l]);
512 tex_print_char(lmt_print_state.trick_buffer[(q + 3) % l]);
513 } else {
514
515 }
516}
517
518void tex_show_context(void)
519{
520 int context_lines = -1;
521 bool bottom_line = false;
522 lmt_input_state.base_ptr = lmt_input_state.input_stack_data.ptr;
523 lmt_input_state.input_stack[lmt_input_state.base_ptr] = lmt_input_state.cur_input;
524 while (1) {
525
526 lmt_input_state.cur_input = lmt_input_state.input_stack[lmt_input_state.base_ptr];
527 if ((lmt_input_state.cur_input.state != token_list_state) && (io_file_input(lmt_input_state.cur_input.name) || (lmt_input_state.base_ptr == 0))) {
528 bottom_line = true;
529 }
530 if ((lmt_input_state.base_ptr == lmt_input_state.input_stack_data.ptr) || bottom_line || (context_lines < error_context_lines_par)) {
531
532 if ((lmt_input_state.base_ptr == lmt_input_state.input_stack_data.ptr) || (lmt_input_state.cur_input.state != token_list_state) || (lmt_input_state.cur_input.token_type != backed_up_text) || (lmt_input_state.cur_input.loc)) {
533
548 bool skip = false;
549 tex_print_nlp();
550 tex_aux_print_current_input_state();
551
555 {
556 int saved_selector = lmt_print_state.selector;
557 lmt_print_state.tally = 0;
558 lmt_print_state.selector = pseudo_selector_code;
559 lmt_print_state.trick_count = 1000000;
560 if (lmt_input_state.cur_input.state == token_list_state) {
561 halfword head = lmt_input_state.cur_input.token_type < macro_text ? lmt_input_state.cur_input.start : token_link(lmt_input_state.cur_input.start);
562 tex_show_token_list_context(head, lmt_input_state.cur_input.loc);
563 } else if (lmt_input_state.cur_input.name == io_lua_input_code) {
564 skip = true;
565 } else {
566
567 int j = lmt_input_state.cur_input.limit;
568 if (lmt_fileio_state.io_buffer[lmt_input_state.cur_input.limit] != end_line_char_par) {
569 ++j;
570 }
571 if (j > 0) {
572 for (int i = lmt_input_state.cur_input.start; i <= j - 1; i++) {
573 if (i == lmt_input_state.cur_input.loc) {
574 tex_set_trick_count();
575 }
576 tex_print_char(lmt_fileio_state.io_buffer[i]);
577 }
578 }
579 }
580 lmt_print_state.selector = saved_selector;
581 }
582
583 if (! skip) {
584 int p;
585 int m;
586 int n;
587 tex_print_nlp();
588 tex_aux_print_indent();
589 if (lmt_print_state.trick_count == 1000000) {
590 tex_set_trick_count();
591 }
592
593 if (lmt_print_state.tally < lmt_print_state.trick_count) {
594 m = lmt_print_state.tally - lmt_print_state.first_count;
595 } else {
596 m = lmt_print_state.trick_count - lmt_print_state.first_count;
597 }
598 if (lmt_print_state.first_count <= lmt_error_state.half_line_limits.size) {
599 p = 0;
600 n = lmt_print_state.first_count;
601 } else {
602 tex_print_str("...");
603 p = lmt_print_state.first_count - lmt_error_state.half_line_limits.size + 3;
604 n = lmt_error_state.half_line_limits.size;
605 }
606 for (int q = p; q <= lmt_print_state.first_count - 1; q++) {
607 tex_aux_print_valid_utf8(q);
608 }
609
613 if (m + n > lmt_error_state.line_limits.size) {
614 p = lmt_print_state.first_count + (lmt_error_state.line_limits.size - n - 3);
615 } else {
616 p = lmt_print_state.first_count + m;
617 }
618 if (lmt_print_state.first_count <= p - 1) {
619 tex_print_nlp();
620 tex_aux_print_indent();
621 for (int q = lmt_print_state.first_count; q <= p - 1; q++) {
622 tex_aux_print_valid_utf8(q);
623 }
624 if (m + n > lmt_error_state.line_limits.size) {
625 tex_print_str(" ...");
626 }
627 }
628 }
629 ++context_lines;
630 }
631 } else if (context_lines == error_context_lines_par) {
632 tex_print_nlp();
633 tex_print_str(" ...");
634 tex_print_nlp();
635 ++context_lines;
636
637 }
638 if (bottom_line) {
639 break;
640 } else {
641 --lmt_input_state.base_ptr;
642 }
643 }
644
645 lmt_input_state.cur_input = lmt_input_state.input_stack[lmt_input_state.input_stack_data.ptr];
646 tex_print_ln();
647 tex_print_nlp();
648}
649
650
657
658inline static void tex_aux_push_input(void)
659{
660 if (tex_aux_room_on_input_stack()) {
661 lmt_input_state.input_stack[lmt_input_state.input_stack_data.ptr] = lmt_input_state.cur_input;
662 ++lmt_input_state.input_stack_data.ptr;
663 } else {
664 tex_overflow_error("input stack size", lmt_input_state.input_stack_data.size);
665 }
666}
667
668inline static void tex_aux_pop_input(void)
669{
670 lmt_input_state.cur_input = lmt_input_state.input_stack[--lmt_input_state.input_stack_data.ptr];
671}
672
673
682
683void tex_begin_token_list(halfword t, quarterword kind)
684{
685 tex_aux_push_input();
686 lmt_input_state.cur_input.state = token_list_state;
687 lmt_input_state.cur_input.start = t;
688 lmt_input_state.cur_input.token_type = kind;
689 if (kind < macro_text) {
690 lmt_input_state.cur_input.loc = t;
691 } else if (kind == macro_text) {
692
693 tex_add_token_reference(t);
694 lmt_input_state.cur_input.parameter_start = lmt_input_state.parameter_stack_data.ptr;
695 } else {
696
697 tex_add_token_reference(t);
698
699 lmt_input_state.cur_input.loc = token_link(t);
700 if (tracing_macros_par > 0) {
701 tex_begin_diagnostic();
702 switch (kind) {
703 case end_of_group_text:
704 tex_print_str("endgroup");
705 break;
706 case mark_text:
707 tex_print_str("mark");
708 break;
709 case token_text:
710 tex_print_str("token");
711 break;
712 case loop_text:
713 tex_print_str("loop");
714 break;
715 case end_paragraph_text:
716 tex_print_str("endpar");
717 break;
718 case end_file_text:
719 tex_print_str("endfile");
720 break;
721 case write_text:
722 tex_print_str("write");
723 break;
724 case local_text:
725 tex_print_str("local");
726 break;
727 case local_loop_text:
728 tex_print_str("localloop");
729 break;
730 default:
731
732 tex_print_cmd_chr(internal_toks_cmd, kind - output_text + internal_toks_location(output_routine_code));
733 break;
734 }
735 tex_print_str("->");
736 if (kind == loop_text || kind == local_loop_text) {
737 tex_print_char('{');
738 }
739 tex_token_show(t);
740 tex_end_diagnostic();
741 }
742 }
743}
744
745
746
747void tex_begin_parameter_list(halfword t)
748{
749 tex_aux_push_input();
750 lmt_input_state.cur_input.state = token_list_state;
751 lmt_input_state.cur_input.start = t;
752 lmt_input_state.cur_input.loc = t;
753 lmt_input_state.cur_input.token_type = parameter_text;
754}
755
756
774
775void tex_begin_backed_up_list(halfword t)
776{
777 tex_aux_push_input();
778 lmt_input_state.cur_input.state = token_list_state;
779 lmt_input_state.cur_input.start = t;
780 lmt_input_state.cur_input.loc = t;
781 lmt_input_state.cur_input.token_type = backed_up_text;
782}
783
784void tex_begin_inserted_list(halfword t)
785{
786 tex_aux_push_input();
787 lmt_input_state.cur_input.state = token_list_state;
788 lmt_input_state.cur_input.start = t;
789 lmt_input_state.cur_input.loc = t;
790 lmt_input_state.cur_input.token_type = inserted_text;
791}
792
793void tex_begin_associated_list(halfword t)
794{
795 tex_aux_push_input();
796 lmt_input_state.cur_input.state = token_list_state;
797 lmt_input_state.cur_input.start = t;
798 lmt_input_state.cur_input.loc = t;
799 lmt_input_state.cur_input.token_type = associated_text;
800}
801
802void tex_begin_macro_list(halfword t)
803{
804 tex_aux_push_input();
805 lmt_input_state.cur_input.state = token_list_state;
806 lmt_input_state.cur_input.start = t;
807 tex_add_token_reference(t);
808 lmt_input_state.cur_input.token_type = macro_text;
809 lmt_input_state.cur_input.parameter_start = lmt_input_state.parameter_stack_data.ptr;
810}
811
812
819
820void tex_end_token_list(void)
821{
822
823 switch (lmt_input_state.cur_input.token_type) {
824 case parameter_text:
825 break;
826 case template_pre_text:
827 if (lmt_input_state.align_state > interwoven_alignment_threshold) {
828 lmt_input_state.align_state = 0;
829 } else {
830 tex_alignment_interwoven_error(7);
831 }
832 break;
833 case template_post_text:
834 case associated_text:
835 break;
836 case backed_up_text:
837 case inserted_text:
838
839
840 tex_flush_token_list(lmt_input_state.cur_input.start);
841 break;
842 case macro_text:
843 {
844 tex_delete_token_reference(lmt_input_state.cur_input.start);
845 if (get_token_preamble(lmt_input_state.cur_input.start)) {
846
847 int ptr = lmt_input_state.parameter_stack_data.ptr;
848 int start = lmt_input_state.cur_input.parameter_start;
849 while (ptr > start) {
850 --ptr;
851 if (lmt_input_state.parameter_stack[ptr]) {
852 tex_flush_token_list(lmt_input_state.parameter_stack[ptr]);
853 }
854 }
855 lmt_input_state.parameter_stack_data.ptr = start;
856 } else {
857
858 }
859 break;
860 }
861 default:
862
863 tex_delete_token_reference(lmt_input_state.cur_input.start);
864 break;
865 }
866 tex_aux_pop_input();
867
868}
869
870void tex_quit_token_list(void)
871{
872 if (lmt_input_state.cur_input.index > 0) {
873 if (lmt_input_state.cur_input.token_type == backed_up_text) {
874
875 tex_end_token_list();
876 }
877 tex_end_token_list();
878 }
879}
880
881
882
883void tex_cleanup_input_state(void)
884{
885 while (! lmt_input_state.cur_input.loc && lmt_input_state.cur_input.state == token_list_state) {
886 switch (lmt_input_state.cur_input.token_type) {
887 case parameter_text:
888 break;
889 case template_pre_text:
890 if (lmt_input_state.align_state > interwoven_alignment_threshold) {
891 lmt_input_state.align_state = 0;
892 } else {
893 tex_alignment_interwoven_error(7);
894 }
895 break;
896 case template_post_text:
897 case associated_text:
898 break;
899 case backed_up_text:
900 case inserted_text:
901
902
903 tex_flush_token_list(lmt_input_state.cur_input.start);
904 break;
905 case macro_text:
906 {
907 tex_delete_token_reference(lmt_input_state.cur_input.start);
908 if (get_token_preamble(lmt_input_state.cur_input.start)) {
909
910 int ptr = lmt_input_state.parameter_stack_data.ptr;
911 int start = lmt_input_state.cur_input.parameter_start;
912 while (ptr > start) {
913 if (lmt_input_state.parameter_stack[--ptr]) {
914 tex_flush_token_list(lmt_input_state.parameter_stack[ptr]);
915 }
916 }
917 lmt_input_state.parameter_stack_data.ptr = start;
918 }
919 break;
920 }
921 default:
922
923 tex_delete_token_reference(lmt_input_state.cur_input.start);
924 break;
925 }
926 tex_aux_pop_input();
927 }
928}
929
930
939
940
941
942void tex_back_input(halfword t)
943{
944 while ((lmt_input_state.cur_input.state == token_list_state) && (! lmt_input_state.cur_input.loc) && (lmt_input_state.cur_input.token_type != template_post_text)) {
945 tex_end_token_list();
946 }
947 {
948
949 halfword p = tex_get_available_token(t);
950 if (t < right_brace_limit) {
951 if (t < left_brace_limit) {
952 --lmt_input_state.align_state;
953 } else {
954 ++lmt_input_state.align_state;
955 }
956 }
957 if (lmt_input_state.cur_input.state == token_list_state && lmt_input_state.cur_input.start == lmt_input_state.cur_input.loc && lmt_input_state.cur_input.token_type == backed_up_text) {
958 token_link(p) = lmt_input_state.cur_input.start;
959 } else {
960 tex_aux_push_input();
961 lmt_input_state.cur_input.state = token_list_state;
962 lmt_input_state.cur_input.token_type = backed_up_text;
963 }
964 lmt_input_state.cur_input.start = p;
965 lmt_input_state.cur_input.loc = p;
966 }
967}
968
969
970
971void tex_reinsert_token(halfword t)
972{
973 halfword p = tex_get_available_token(t);
974 set_token_link(p, lmt_input_state.cur_input.loc);
975 lmt_input_state.cur_input.start = p;
976 lmt_input_state.cur_input.loc = p;
977 if (t < right_brace_limit) {
978 if (t < left_brace_limit) {
979 --lmt_input_state.align_state;
980 } else {
981 ++lmt_input_state.align_state;
982 }
983 }
984}
985
986
987
988void tex_insert_input(halfword h)
989{
990 if (h) {
991 while ((lmt_input_state.cur_input.state == token_list_state) && (! lmt_input_state.cur_input.loc) && (lmt_input_state.cur_input.token_type != template_post_text)) {
992 tex_end_token_list();
993 }
994 if (token_info(h) < right_brace_limit) {
995 if (token_info(h) < left_brace_limit) {
996 --lmt_input_state.align_state;
997 } else {
998 ++lmt_input_state.align_state;
999 }
1000 }
1001 tex_aux_push_input();
1002 lmt_input_state.cur_input.start = h;
1003 lmt_input_state.cur_input.loc = h;
1004 lmt_input_state.cur_input.state = token_list_state;
1005 lmt_input_state.cur_input.token_type = inserted_text;
1006
1009
1020 }
1021}
1022
1023void tex_append_input(halfword h)
1024{
1025 if (h) {
1026 halfword n = h;
1027 if (n) {
1028 while (token_link(n)) {
1029 n = token_link(n);
1030 }
1031 set_token_link(n, lmt_input_state.cur_input.loc);
1032 } else {
1033 set_token_link(h, lmt_input_state.cur_input.loc);
1034 }
1035 lmt_input_state.cur_input.start = h;
1036 lmt_input_state.cur_input.loc = h;
1037 }
1038}
1039
1040
1047
1048void tex_begin_file_reading(void)
1049{
1050 ++lmt_input_state.in_stack_data.ptr;
1051 if (tex_aux_room_on_in_stack() && tex_room_in_buffer(lmt_fileio_state.io_first)) {
1052 tex_aux_push_input();
1053 lmt_input_state.cur_input.index = (short) lmt_input_state.in_stack_data.ptr;
1054 lmt_input_state.in_stack[lmt_input_state.cur_input.index].full_source_filename = NULL;
1055 lmt_input_state.in_stack[lmt_input_state.cur_input.index].end_of_file_seen = 0;
1056 lmt_input_state.in_stack[lmt_input_state.cur_input.index].at_end_of_file = null;
1057 lmt_input_state.in_stack[lmt_input_state.cur_input.index].group = cur_boundary;
1058 lmt_input_state.in_stack[lmt_input_state.cur_input.index].line = lmt_input_state.input_line;
1059 lmt_input_state.in_stack[lmt_input_state.cur_input.index].if_ptr = lmt_condition_state.cond_ptr;
1060 lmt_input_state.cur_input.start = lmt_fileio_state.io_first;
1061 lmt_input_state.cur_input.state = mid_line_state;
1062 lmt_input_state.cur_input.name = io_initial_input_code;
1063 lmt_input_state.cur_input.cattable = default_catcode_table_preset;
1064 lmt_input_state.cur_input.partial = 0;
1065
1066 lmt_input_state.cur_input.state_file = 0;
1067 lmt_input_state.cur_input.state_line = 0;
1068 }
1069}
1070
1071
1077
1078void tex_end_file_reading(void)
1079{
1080 lmt_fileio_state.io_first = lmt_input_state.cur_input.start;
1081 lmt_input_state.input_line = lmt_input_state.in_stack[lmt_input_state.cur_input.index].line;
1082 switch (lmt_input_state.cur_input.name) {
1083 case io_initial_input_code:
1084 break;
1085 case io_lua_input_code:
1086 case io_token_input_code:
1087 case io_token_eof_input_code:
1088
1089 lmt_cstring_close();
1090 break;
1091 case io_tex_macro_code:
1092 break;
1093 default:
1094
1095 tex_lua_a_close_in();
1096 if (lmt_input_state.in_stack[lmt_input_state.cur_input.index].full_source_filename) {
1097 lmt_memory_free(lmt_input_state.in_stack[lmt_input_state.cur_input.index].full_source_filename);
1098 lmt_input_state.in_stack[lmt_input_state.cur_input.index].full_source_filename = NULL;
1099 }
1100 if (lmt_input_state.in_stack[lmt_input_state.cur_input.index].at_end_of_file) {
1101 tex_flush_token_list(lmt_input_state.in_stack[lmt_input_state.cur_input.index].at_end_of_file);
1102 lmt_input_state.in_stack[lmt_input_state.cur_input.index].at_end_of_file = null;
1103 }
1104 break;
1105 }
1106 tex_aux_pop_input();
1107 --lmt_input_state.in_stack_data.ptr;
1108}
1109
1110
1115
1116void tex_initialize_inputstack(void)
1117{
1118 lmt_input_state.input_stack_data.ptr = 0;
1119 lmt_input_state.input_stack_data.top = 0;
1120 lmt_input_state.in_stack[0].full_source_filename = NULL;
1121 lmt_input_state.in_stack_data.ptr = 0;
1122 lmt_input_state.open_files = 0;
1123 lmt_fileio_state.io_buffer_data.top = 0;
1124 lmt_input_state.in_stack[0].group = 0;
1125 lmt_input_state.in_stack[0].if_ptr = null;
1126 lmt_input_state.parameter_stack_data.ptr = 0;
1127 lmt_input_state.parameter_stack_data.top = 0;
1128 lmt_input_state.scanner_status = scanner_is_normal;
1129 lmt_input_state.warning_index = null;
1130 lmt_fileio_state.io_first = 1;
1131 lmt_input_state.cur_input.state = new_line_state;
1132 lmt_input_state.cur_input.start = 1;
1133 lmt_input_state.cur_input.index = 0;
1134 lmt_input_state.input_line = 0;
1135 lmt_input_state.cur_input.name = io_initial_input_code;
1136 lmt_token_state.force_eof = 0;
1137 lmt_token_state.luacstrings = 0;
1138 lmt_input_state.cur_input.cattable = default_catcode_table_preset;
1139 lmt_input_state.cur_input.partial = 0;
1140 lmt_input_state.align_state = busy_alignment_state;
1141}
1142
1143
1148
1149void tex_tex_string_start(int iotype, int cattable)
1150{
1151
1152 {
1153 halfword head = tex_scan_general_text(NULL);
1154 int saved_selector = lmt_print_state.selector;
1155 lmt_print_state.selector = new_string_selector_code;
1156 tex_show_token_list(head, 0, 0);
1157 lmt_print_state.selector = saved_selector;
1158 tex_flush_token_list(head);
1159 }
1160 {
1161 int len;
1162 char *str = tex_take_string(&len);
1163 lmt_cstring_store(str, len, tex_valid_catcode_table(cattable) ? cattable : cat_code_table_par);
1164 tex_begin_file_reading();
1165 lmt_input_state.input_line = 0;
1166 lmt_input_state.cur_input.limit = lmt_input_state.cur_input.start;
1167 lmt_input_state.cur_input.loc = lmt_input_state.cur_input.limit + 1;
1168 lmt_input_state.cur_input.name = iotype;
1169 lmt_cstring_start();
1170 }
1171}
1172
1173
1174void tex_lua_string_start(void)
1175{
1176
1177 tex_begin_file_reading();
1178 lmt_input_state.input_line = 0;
1179 lmt_input_state.cur_input.limit = lmt_input_state.cur_input.start;
1180
1181 lmt_input_state.cur_input.loc = lmt_input_state.cur_input.limit + 1;
1182 lmt_input_state.cur_input.name = io_lua_input_code;
1183 lmt_cstring_start();
1184}
1185
1186void tex_any_string_start(char* s)
1187{
1188
1189
1200
1201 lmt_cstring_store(s, (int) strlen(s), cat_code_table_par);
1202 tex_begin_file_reading();
1203 lmt_input_state.input_line = 0;
1204 lmt_input_state.cur_input.limit = lmt_input_state.cur_input.start;
1205 lmt_input_state.cur_input.loc = lmt_input_state.cur_input.limit + 1;
1206 lmt_input_state.cur_input.name = io_token_input_code;
1207 lmt_cstring_start();
1208}
1209
1210
1211
1212halfword tex_wrapped_token_list(halfword list)
1213{
1214 halfword head = tex_store_new_token(null, left_brace_token + '{');
1215 halfword tail = head;
1216 token_link(tail) = token_link(list);
1217 while (token_link(tail)) {
1218 tail = token_link(tail);
1219 }
1220 tail = tex_store_new_token(tail, right_brace_token + '}');
1221 return head;
1222}
1223
1224const char *tex_current_input_file_name(void)
1225{
1226 int level = lmt_input_state.in_stack_data.ptr;
1227 while (level > 0) {
1228 const char *s = lmt_input_state.in_stack[level--].full_source_filename;
1229 if (s) {
1230 return s;
1231 }
1232 }
1233
1234 level = lmt_input_state.in_stack_data.ptr;
1235 while (level > 0) {
1236 int t = lmt_input_state.input_stack[level--].name;
1237 if (t >= cs_offset_value) {
1238 return (const char *) str_string(t);
1239 }
1240 }
1241 return NULL;
1242}
1243 |