1
4
5# include "luametatex.h"
6
7
8
9inline static int tex_aux_the_cat_code(halfword b)
10{
11 return (lmt_input_state.cur_input.cattable == default_catcode_table_preset) ?
12 tex_get_cat_code(cat_code_table_par, b)
13 : ( (lmt_input_state.cur_input.cattable > -0xFF) ?
14 tex_get_cat_code(lmt_input_state.cur_input.cattable, b)
15 : (
16 - lmt_input_state.cur_input.cattable - 0xFF
17 ) ) ;
18}
19
20
53
54token_memory_state_info lmt_token_memory_state = {
55 .tokens = NULL,
56 .tokens_data = {
57 .minimum = min_token_size,
58 .maximum = max_token_size,
59 .size = siz_token_size,
60 .step = stp_token_size,
61 .allocated = 0,
62 .itemsize = sizeof(memoryword),
63 .top = 0,
64 .ptr = 0,
65 .initial = 0,
66 .offset = 0,
67 },
68 .available = 0,
69 .padding = 0,
70};
71
72
82
83token_state_info lmt_token_state = {
84 .null_list = null,
85 .in_lua_escape = 0,
86 .force_eof = 0,
87 .luacstrings = 0,
88 .par_loc = null,
89 .par_token = null,
90
91
92 .buffer = NULL,
93 .bufloc = 0,
94 .bufmax = 0,
95 .empty = null,
96};
97
98
99
100# define reserved_token_mem_slots 2
101
102void tex_initialize_token_mem(void)
103{
104 memoryword *tokens = NULL;
105 int size = 0;
106 if (lmt_main_state.run_state == initializing_state) {
107 size = lmt_token_memory_state.tokens_data.minimum;
108 } else {
109 size = lmt_token_memory_state.tokens_data.allocated;
110 lmt_token_memory_state.tokens_data.initial = lmt_token_memory_state.tokens_data.ptr;
111 }
112 if (size > 0) {
113 tokens = aux_allocate_clear_array(sizeof(memoryword), size, reserved_token_mem_slots);
114 }
115 if (tokens) {
116 lmt_token_memory_state.tokens = tokens;
117 lmt_token_memory_state.tokens_data.allocated = size;
118 } else {
119 tex_overflow_error("tokens", size);
120 }
121}
122
123static void tex_aux_bump_token_memory(void)
124{
125
126 int size = lmt_token_memory_state.tokens_data.allocated + lmt_token_memory_state.tokens_data.step;
127 if (size > lmt_token_memory_state.tokens_data.size) {
128 lmt_run_memory_callback("token", 0);
129 tex_show_runaway();
130 tex_overflow_error("token memory size", lmt_token_memory_state.tokens_data.allocated);
131 } else {
132 memoryword *tokens = aux_reallocate_array(lmt_token_memory_state.tokens, sizeof(memoryword), size, reserved_token_mem_slots);
133 lmt_run_memory_callback("token", tokens ? 1 : 0);
134 if (tokens) {
135 lmt_token_memory_state.tokens = tokens;
136 } else {
137
138 tex_show_runaway();
139 tex_overflow_error("token memory size", lmt_token_memory_state.tokens_data.allocated);
140 }
141 }
142 memset((void *) (lmt_token_memory_state.tokens + lmt_token_memory_state.tokens_data.allocated + 1), 0, ((size_t) lmt_token_memory_state.tokens_data.step + reserved_token_mem_slots) * sizeof(memoryword));
143 lmt_token_memory_state.tokens_data.allocated = size;
144}
145
146void tex_initialize_tokens(void)
147{
148 lmt_token_memory_state.available = null;
149 lmt_token_memory_state.tokens_data.top = 0;
150 lmt_token_state.null_list = tex_get_available_token(null);
151
152}
153
154
163
164void tex_compact_tokens(void)
165{
166 int nc = 0;
167
168 memoryword *target = aux_allocate_clear_array(sizeof(memoryword), lmt_token_memory_state.tokens_data.allocated, 0);
169 halfword *mapper = aux_allocate_array(sizeof(halfword), lmt_token_memory_state.tokens_data.allocated, 0);
170 int nofluacmds = 0;
171 if (target && mapper) {
172 memoryword *tokens = lmt_token_memory_state.tokens;
173 memset((void *) mapper, -1, ((size_t) lmt_token_memory_state.tokens_data.allocated) * sizeof(halfword));
174
175 for (int cs = 0; cs < (eqtb_size + lmt_hash_state.hash_data.ptr + 1); cs++) {
176 switch (eq_type(cs)) {
177 case call_cmd:
178 case protected_call_cmd:
179 case semi_protected_call_cmd:
180 case constant_call_cmd:
181 case tolerant_call_cmd:
182 case tolerant_protected_call_cmd:
183 case tolerant_semi_protected_call_cmd:
184 case internal_toks_reference_cmd:
185 case register_toks_reference_cmd:
186 {
187 halfword v = eq_value(cs);
188 if (v) {
189 if (mapper[v] < 0) {
190
191 halfword t = v;
192 nc++;
193 mapper[v] = nc;
194 while (1) {
195 target[nc].half1 = tokens[t].half1;
196 t = tokens[t].half0;
197 if (t) {
198 nc++;
199 target[nc-1].half0 = nc;
200 } else {
201 target[nc].half0 = null;
202 break;
203 }
204 }
205
206 }
207 eq_value(cs) = mapper[v];
208 }
209 break;
210 }
211 case lua_value_cmd:
212 case lua_call_cmd:
213 case lua_local_call_cmd:
214 {
215 ++nofluacmds;
216 break;
217 }
218 }
219 }
220 lmt_token_state.empty = mapper[lmt_token_state.empty];
221
222 tex_print_format("tokenlist compacted from %i to %i entries, ", lmt_token_memory_state.tokens_data.top, nc);
223 if (nofluacmds) {
224
229 tex_print_format("%i potentially aliased lua call/value entries, ", nofluacmds);
230 }
231 lmt_token_memory_state.tokens_data.top = nc;
232 lmt_token_memory_state.tokens_data.ptr = nc;
233 aux_deallocate_array(lmt_token_memory_state.tokens);
234 lmt_token_memory_state.tokens = target;
235 lmt_token_memory_state.available = null;
236 } else {
237 tex_overflow_error("token compaction size", lmt_token_memory_state.tokens_data.allocated);
238 }
239}
240
241
242
266
267halfword tex_get_available_token(halfword t)
268{
269 halfword p = lmt_token_memory_state.available;
270 if (p) {
271 lmt_token_memory_state.available = token_link(p);
272 } else if (lmt_token_memory_state.tokens_data.top < lmt_token_memory_state.tokens_data.allocated) {
273 p = ++lmt_token_memory_state.tokens_data.top;
274 } else {
275 tex_aux_bump_token_memory();
276 p = ++lmt_token_memory_state.tokens_data.top;
277 }
278 ++lmt_token_memory_state.tokens_data.ptr;
279 token_link(p) = null;
280 token_info(p) = t;
281 return p;
282}
283
284
290
291void tex_put_available_token(halfword p)
292{
293 token_link(p) = lmt_token_memory_state.available;
294 lmt_token_memory_state.available = p;
295 --lmt_token_memory_state.tokens_data.ptr;
296}
297
298halfword tex_store_new_token(halfword p, halfword t)
299{
300 halfword q = tex_get_available_token(t);
301 token_link(p) = q;
302 return q;
303}
304
305
313
314void tex_flush_token_list(halfword head)
315{
316 if (head) {
317 if (! token_link(head)) {
318
319 token_link(head) = lmt_token_memory_state.available;
320 --lmt_token_memory_state.tokens_data.ptr;
321 } else {
322 halfword current = head;
323 halfword tail;
324 int i = 0;
325 do {
326 ++i;
327 tail = current;
328 current = token_link(tail);
329 } while (current);
330 token_link(tail) = lmt_token_memory_state.available;
331 lmt_token_memory_state.tokens_data.ptr -= i;
332 }
333 lmt_token_memory_state.available = head;
334 }
335}
336
337void tex_flush_token_list_head_tail(halfword head, halfword tail, int n)
338{
339 if (head) {
340 lmt_token_memory_state.tokens_data.ptr -= n;
341 token_link(tail) = lmt_token_memory_state.available;
342 lmt_token_memory_state.available = head;
343 }
344}
345
346void tex_add_token_reference(halfword p)
347{
348 if (get_token_reference(p) < max_token_reference) {
349 add_token_reference(p);
350
351
352 }
353}
354
355void tex_increment_token_reference(halfword p, int n)
356{
357 if ((get_token_reference(p) + n) < max_token_reference) {
358 inc_token_reference(p, n);
359 } else {
360 inc_token_reference(p, max_token_reference - get_token_reference(p));
361
362
363 }
364}
365
366void tex_delete_token_reference(halfword p)
367{
368 if (p) {
369 halfword r = get_token_reference(p);
370 if (! r) {
371 tex_flush_token_list(p);
372 } else if (r < max_token_reference) {
373 sub_token_reference(p);
374 }
375 }
376}
377
378
446
447void tex_print_meaning(halfword code)
448{
449
462 int untraced = is_untraced(eq_flag(cur_cs));
463 if (! untraced) {
464 switch (code) {
465 case meaning_code:
466 case meaning_full_code:
467 case meaning_ful_code:
468 case meaning_asis_code:
469 tex_print_cmd_flags(cur_cs, cur_cmd, (code != meaning_code), code == meaning_asis_code);
470 break;
471 }
472 }
473 switch (cur_cmd) {
474 case call_cmd:
475 case protected_call_cmd:
476 case semi_protected_call_cmd:
477 case constant_call_cmd:
478 case tolerant_call_cmd:
479 case tolerant_protected_call_cmd:
480 case tolerant_semi_protected_call_cmd:
481 if (untraced) {
482 tex_print_cs(cur_cs);
483 return;
484 } else {
485 switch (code) {
486 case meaning_code:
487 case meaning_full_code:
488 case meaning_ful_code:
489 tex_print_str("macro");
490 if (code == meaning_ful_code) {
491 return;
492 } else {
493 goto FOLLOWUP;
494 }
495 case meaning_asis_code:
496
497 tex_print_cmd_chr(def_cmd, def_code);
498 tex_print_char(' ');
499 tex_print_cs(cur_cs);
500 tex_print_char(' ');
501 if (cur_chr && token_link(cur_chr)) {
502 tex_show_token_list(token_link(cur_chr), get_token_preamble(cur_chr) ? 1 : 3, 0);
503 } else {
504 tex_print_char('{');
505 tex_print_char('}');
506 }
507 return;
508 case meaning_les_code:
509 if (cur_chr && token_link(cur_chr)) {
510 tex_show_token_list(token_link(cur_chr), 2, 0);
511 }
512 return;
513 }
514 goto DETAILS;
515 }
516 case get_mark_cmd:
517 tex_print_cmd_chr((singleword) cur_cmd, cur_chr);
518 tex_print_char(':');
519 tex_print_nlp();
520 tex_token_show(tex_get_some_mark(cur_chr, 0));
521 return;
522 case lua_value_cmd:
523 case lua_call_cmd:
524 case lua_local_call_cmd:
525 case lua_protected_call_cmd:
526 case lua_semi_protected_call_cmd:
527 if (untraced) {
528 tex_print_cs(cur_cs);
529 return;
530 } else {
531 goto DEFAULT;
532 }
533 case if_test_cmd:
534 if (cur_chr > last_if_test_code) {
535 tex_print_cs(cur_cs);
536 return;
537 } else {
538 goto DEFAULT;
539 }
540 default:
541 DEFAULT:
542 tex_print_cmd_chr((singleword) cur_cmd, cur_chr);
543 if (cur_cmd < call_cmd) {
544 return;
545 } else {
546
547 break;
548 }
549 }
550 FOLLOWUP:
551 tex_print_char(':');
552 DETAILS:
553 tex_print_nlp();
554 tex_token_show(cur_chr);
555}
556
557
592
593static const char *tex_aux_special_cmd_string(halfword cmd, halfword chr, const char *unknown)
594{
595 switch (cmd) {
596 case node_cmd : return "[[special cmd: node pointer]]";
597 case lua_protected_call_cmd : return "[[special cmd: lua protected call]]";
598 case lua_semi_protected_call_cmd : return "[[special cmd: lua semi protected call]]";
599 case lua_value_cmd : return "[[special cmd: lua value call]]";
600 case iterator_value_cmd : return "[[special cmd: iterator value]]";
601 case lua_call_cmd : return "[[special cmd: lua call]]";
602 case lua_local_call_cmd : return "[[special cmd: lua local call]]";
603 case begin_local_cmd : return "[[special cmd: begin local call]]";
604 case end_local_cmd : return "[[special cmd: end local call]]";
605
606 case prefix_cmd : return "\\always ";
607 default : printf("[[unknown cmd: (%i,%i)]]\n", cmd, chr); return unknown;
608 }
609}
610
611void tex_show_token_list(halfword p, int asis, int single)
612{
613 if (p) {
614 unsigned char n = 0;
615 int max = lmt_token_memory_state.tokens_data.top;
616 if (asis == 3) {
617 tex_print_char('{');
618 }
619 while (p) {
620 if (p < 0 || p > max) {
621 tex_print_str(error_string_clobbered(41));
622 return;
623 } else if (token_info(p) >= cs_token_flag) {
624 tex_print_cs_checked(token_info(p) - cs_token_flag);
625 } else if (token_info(p) > 0) {
626 int cmd = token_cmd(token_info(p));
627 int chr = token_chr(token_info(p));
628 switch (cmd) {
629 case left_brace_cmd:
630 case right_brace_cmd:
631 case math_shift_cmd:
632 case alignment_tab_cmd:
633 case superscript_cmd:
634 case subscript_cmd:
635 case spacer_cmd:
636 case letter_cmd:
637 case other_char_cmd:
638 case active_char_cmd:
639 case ignore_cmd:
640 tex_print_tex_str(chr);
641 break;
642 case parameter_cmd:
643
648 if (! single) {
649 tex_print_tex_str(chr);
650 }
651 tex_print_tex_str(chr);
652 break;
653 case parameter_reference_cmd:
654 tex_print_tex_str(match_visualizer);
655 if (chr <= 9) {
656 tex_print_char(chr + '0');
657 } else if (chr <= max_match_count) {
658 tex_print_char(chr + '0' + gap_match_count);
659 } else {
660 tex_print_char('!');
661 return;
662 }
663 break;
664 case match_cmd:
665 tex_print_char(match_visualizer);
666 if (is_valid_match_ref(chr)) {
667 ++n;
668 }
669 tex_print_char(chr ? chr : '0');
670 if (n > max_match_count) {
671 return;
672 } else {
673 break;
674 }
675 case end_match_cmd:
676 switch (asis) {
677 case 1:
678 tex_print_char('{');
679 break;
680 case 2:
681 return;
682 default:
683 if (chr == 0) {
684 tex_print_str("->");
685 }
686 break;
687 }
688 break;
689 case ignore_something_cmd:
690 break;
691 case set_font_cmd:
692 tex_print_format("[font->%s]", font_original(cur_val));
693 break;
694 case end_paragraph_cmd:
695
696 tex_print_str_esc("par ");
697 break;
698 default:
699 tex_print_str(tex_aux_special_cmd_string(cmd, chr, error_string_bad(43)));
700 break;
701 }
702 } else {
703 tex_print_str(error_string_bad(42));
704 }
705 p = token_link(p);
706 }
707 if (asis == 1 || asis == 3) {
708 tex_print_char('}');
709 }
710 }
711}
712
713void tex_show_token_list_context(halfword p, halfword q)
714{
715 if (p) {
716
717 unsigned char n = 0;
718 int max = lmt_token_memory_state.tokens_data.top;
719 lmt_print_state.tally = 0;
720 while (p) {
721 if (p == q) {
722
723 tex_set_trick_count();
724 }
725
726 if (p < 0 || p > max) {
727 tex_print_str(error_string_clobbered(41));
728 return;
729 } else if (token_info(p) >= cs_token_flag) {
730
731 tex_print_cs_checked(token_info(p) - cs_token_flag);
732
733 } else if (token_info(p) > 0) {
734 int cmd = token_cmd(token_info(p));
735 int chr = token_chr(token_info(p));
736
741 switch (cmd) {
742 case left_brace_cmd:
743 case right_brace_cmd:
744 case math_shift_cmd:
745 case alignment_tab_cmd:
746 case superscript_cmd:
747 case subscript_cmd:
748 case spacer_cmd:
749 case letter_cmd:
750 case other_char_cmd:
751 case active_char_cmd:
752 case ignore_cmd:
753 tex_print_tex_str(chr);
754 break;
755 case parameter_cmd:
756
759 tex_print_tex_str(chr);
760 tex_print_tex_str(chr);
761 break;
762 case parameter_reference_cmd:
763 tex_print_tex_str(match_visualizer);
764 if (chr <= 9) {
765 tex_print_char(chr + '0');
766 } else if (chr <= max_match_count) {
767 tex_print_char(chr + '0' + gap_match_count);
768 } else {
769 tex_print_char('!');
770 return;
771 }
772 break;
773 case match_cmd:
774 tex_print_char(match_visualizer);
775 if (is_valid_match_ref(chr)) {
776 ++n;
777 }
778 tex_print_char(chr ? chr : '0');
779 if (n > max_match_count) {
780
781 return;
782 } else {
783 break;
784 }
785 case end_match_cmd:
786 tex_print_str("->");
787 break;
788 case ignore_something_cmd:
789 break;
790 case set_font_cmd:
791 tex_print_format("[font->%s]", font_original(cur_val));
792 break;
793 case end_paragraph_cmd:
794
795 tex_print_str_esc("par ");
796 break;
797 default:
798 tex_print_str(tex_aux_special_cmd_string(cmd, chr, error_string_bad(43)));
799 break;
800 }
801
802
803 } else {
804 tex_print_str(error_string_bad(42));
805 }
806 p = token_link(p);
807 }
808 if (p) {
809 tex_print_str_esc("ETC.");
810 }
811 }
812}
813
814
820
821inline static halfword get_unichar_from_buffer(int *b)
822{
823 halfword a = (halfword) ((const unsigned char) *(lmt_fileio_state.io_buffer + *b));
824 if (a <= 0x80) {
825 *b += 1;
826 } else {
827 int al;
828 a = (halfword) aux_str2uni_len(lmt_fileio_state.io_buffer + *b, &al);
829 *b += al;
830 }
831 return a;
832}
833
834
840
841void tex_token_show(halfword p)
842{
843 if (p && token_link(p)) {
844 tex_show_token_list(token_link(p), 0, 0);
845 }
846}
847
848
856
857int tex_get_char_cat_code(int c)
858{
859 return tex_aux_the_cat_code(c);
860}
861
862static void tex_aux_invalid_character_error(void)
863{
864 tex_handle_error(
865 normal_error_type,
866 "Text line contains an invalid character",
867 "A funny symbol that I can't read has just been input. Continue, and I'll forget\n"
868 "that it ever happened."
869 );
870}
871
872static int tex_aux_process_sup_mark(void);
873
874static int tex_aux_scan_control_sequence(void);
875
876typedef enum next_line_retval {
877 next_line_ok,
878 next_line_return,
879 next_line_restart
880} next_line_retval;
881
882inline static next_line_retval tex_aux_next_line(void);
883
884
908
909halfword tex_scan_character(const char *s, int left_brace, int skip_space, int skip_relax)
910{
911 halfword save_cur_cs = cur_cs;
912 while (1) {
913 tex_get_x_token();
914 switch (cur_cmd) {
915 case spacer_cmd:
916 if (skip_space) {
917 break;
918 } else {
919 goto DONE;
920 }
921 case relax_cmd:
922 if (skip_relax) {
923 break;
924 } else {
925 goto DONE;
926 }
927 case letter_cmd:
928 case other_char_cmd:
929 if (cur_chr <= 'z' && strchr(s, cur_chr)) {
930 cur_cs = save_cur_cs;
931 return cur_chr;
932 } else {
933 goto DONE;
934 }
935 case left_brace_cmd:
936 if (left_brace) {
937 cur_cs = save_cur_cs;
938 return '{';
939 } else {
940 goto DONE;
941 }
942 default:
943 goto DONE;
944 }
945 }
946 DONE:
947 tex_back_input(cur_tok);
948 cur_cs = save_cur_cs;
949 return 0;
950}
951
952void tex_aux_show_keyword_error(const char *s)
953{
954 tex_handle_error(
955 normal_error_type,
956 "Valid keyword expected, likely '%s'",
957 s,
958 "You started a keyword but it seems to be an invalid one. The first character(s)\n"
959 "might give you a clue. You might want to quit unwanted lookahead with \\relax."
960 );
961}
962
963
968
969int tex_scan_optional_keyword(const char *s)
970{
971 halfword save_cur_cs = cur_cs;
972 int done = 0;
973 const char *p = s;
974 while (*p) {
975 tex_get_x_token();
976 switch (cur_cmd) {
977 case letter_cmd:
978 case other_char_cmd:
979 if ((cur_chr == *p) || (cur_chr == *p - 'a' + 'A')) {
980 if (*(++p)) {
981 done = 1;
982 } else {
983 cur_cs = save_cur_cs;
984 return 1;
985 }
986 } else if (done) {
987 goto BAD_NEWS;
988 } else {
989
990 tex_back_input(cur_tok);
991 cur_cs = save_cur_cs;
992 return 1;
993 }
994 break;
995 case spacer_cmd:
996 if (done) {
997 goto BAD_NEWS;
998 } else {
999 break;
1000 }
1001
1002 default:
1003 tex_back_input(cur_tok);
1004 if (done) {
1005
1006 goto BAD_NEWS;
1007 } else {
1008 cur_cs = save_cur_cs;
1009 return 0;
1010 }
1011 }
1012 }
1013 BAD_NEWS:
1014 tex_aux_show_keyword_error(s);
1015 cur_cs = save_cur_cs;
1016 return 0;
1017}
1018
1019
1023
1024int tex_scan_mandate_keyword(const char *s, int offset)
1025{
1026 halfword save_cur_cs = cur_cs;
1027 int done = 0;
1028
1029 const char *p = s + offset;
1030 while (*p) {
1031 tex_get_x_token();
1032 switch (cur_cmd) {
1033 case letter_cmd:
1034 case other_char_cmd:
1035 if ((cur_chr == *p) || (cur_chr == *p - 'a' + 'A')) {
1036 if (*(++p)) {
1037 done = 1;
1038 } else {
1039 cur_cs = save_cur_cs;
1040 return 1;
1041 }
1042 } else {
1043 goto BAD_NEWS;
1044 }
1045 break;
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056 case spacer_cmd:
1057 if (done) {
1058 goto BAD_NEWS;
1059 } else {
1060 break;
1061 }
1062
1063 default:
1064 tex_back_input(cur_tok);
1065
1066 goto BAD_NEWS;
1067 }
1068 }
1069 BAD_NEWS:
1070 tex_aux_show_keyword_error(s);
1071 cur_cs = save_cur_cs;
1072 return 0;
1073}
1074
1075
1079
1080int tex_scan_keyword(const char *s)
1081{
1082 if (*s) {
1083 halfword h = null;
1084 halfword p = null;
1085 halfword save_cur_cs = cur_cs;
1086 int n = 0;
1087 while (*s) {
1088
1089 tex_get_x_token();
1090 if ((cur_cmd == letter_cmd || cur_cmd == other_char_cmd) && ((cur_chr == *s) || (cur_chr == *s - 'a' + 'A'))) {
1091 p = tex_store_new_token(p, cur_tok);
1092 if (! h) {
1093 h = p;
1094 }
1095 n++;
1096 s++;
1097 } else if ((p != h) || (cur_cmd != spacer_cmd)) {
1098 tex_back_input(cur_tok);
1099 if (h) {
1100 tex_begin_backed_up_list(h);
1101 }
1102 cur_cs = save_cur_cs;
1103 return 0;
1104 }
1105 }
1106 if (h) {
1107 tex_flush_token_list_head_tail(h, p, n);
1108 }
1109 cur_cs = save_cur_cs;
1110 return 1;
1111 } else {
1112
1113 return 0 ;
1114 }
1115}
1116
1117int tex_scan_keyword_case_sensitive(const char *s)
1118{
1119 if (*s) {
1120 halfword h = null;
1121 halfword p = null;
1122 halfword save_cur_cs = cur_cs;
1123 int n = 0;
1124 while (*s) {
1125 tex_get_x_token();
1126 if ((cur_cmd == letter_cmd || cur_cmd == other_char_cmd) && (cur_chr == *s)) {
1127 p = tex_store_new_token(p, cur_tok);
1128 if (! h) {
1129 h = p;
1130 }
1131 n++;
1132 s++;
1133 } else if ((p != h) || (cur_cmd != spacer_cmd)) {
1134 tex_back_input(cur_tok);
1135 if (h) {
1136 tex_begin_backed_up_list(h);
1137 }
1138 cur_cs = save_cur_cs;
1139 return 0;
1140 }
1141 }
1142 if (h) {
1143 tex_flush_token_list_head_tail(h, p, n);
1144 }
1145 cur_cs = save_cur_cs;
1146 return 1;
1147 } else {
1148 return 0 ;
1149 }
1150}
1151
1152
1158
1159halfword tex_active_to_cs(int c, int force)
1160{
1161 halfword cs = -1;
1162 if (c >= 0 && c <= max_character_code) {
1163 char utfbytes[8] = { active_character_first, active_character_second, active_character_third, 0 };
1164 aux_uni2string((char *) &utfbytes[3], c);
1165 cs = tex_string_locate(utfbytes, (size_t) utf8_size(c) + 3, force);
1166 }
1167 if (cs < 0) {
1168 cs = tex_string_locate(active_character_unknown, 4, force);
1169 }
1170 return cs;
1171}
1172
1173
1211
1212
1213
1214
1215
1216
1217
1263
1264
1274
1275
1293
1294static int tex_aux_get_next_file(void)
1295{
1296 SWITCH:
1297 if (lmt_input_state.cur_input.loc <= lmt_input_state.cur_input.limit) {
1298
1299 cur_chr = get_unichar_from_buffer(&lmt_input_state.cur_input.loc);
1300 RESWITCH:
1301 if (lmt_input_state.cur_input.cattable == no_catcode_table_preset) {
1302
1303 cur_cmd = cur_chr == ' ' ? spacer_cmd : other_char_cmd;
1304 } else {
1305 cur_cmd = tex_aux_the_cat_code(cur_chr);
1306 }
1307 switch (lmt_input_state.cur_input.state + cur_cmd) {
1308 case mid_line_state + ignore_cmd:
1309 case skip_blanks_state + ignore_cmd:
1310 case new_line_state + ignore_cmd:
1311 case skip_blanks_state + spacer_cmd:
1312 case new_line_state + spacer_cmd:
1313
1314 goto SWITCH;
1315 case mid_line_state + escape_cmd:
1316 case new_line_state + escape_cmd:
1317 case skip_blanks_state + escape_cmd:
1318
1319 lmt_input_state.cur_input.state = (unsigned char) tex_aux_scan_control_sequence();
1320 break;
1321 case mid_line_state + active_char_cmd:
1322 case new_line_state + active_char_cmd:
1323 case skip_blanks_state + active_char_cmd:
1324
1325 if ((lmt_input_state.scanner_status == scanner_is_tolerant || lmt_input_state.scanner_status == scanner_is_matching) && tex_pass_active_math_char(cur_chr)) {
1326
1327 } else if ((lmt_input_state.scanner_status == scanner_is_defining || lmt_input_state.scanner_status == scanner_is_absorbing) && tex_pass_active_math_char(cur_chr)) {
1328
1329 } else if ((cur_mode == mmode || lmt_nest_state.math_mode) && tex_check_active_math_char(cur_chr)) {
1330
1331 } else {
1332 cur_cs = tex_active_to_cs(cur_chr, ! lmt_hash_state.no_new_cs);
1333 cur_cmd = eq_type(cur_cs);
1334 cur_chr = eq_value(cur_cs);
1335 }
1336 lmt_input_state.cur_input.state = mid_line_state;
1337 break;
1338 case mid_line_state + superscript_cmd:
1339 case new_line_state + superscript_cmd:
1340 case skip_blanks_state + superscript_cmd:
1341
1346 if (sup_mark_mode_par) {
1347 if (sup_mark_mode_par == 1 && cur_mode != mmode && tex_aux_process_sup_mark()) {
1348 goto RESWITCH;
1349 }
1350 } else if (tex_aux_process_sup_mark()) {
1351 goto RESWITCH;
1352 } else {
1353
1357 }
1358 lmt_input_state.cur_input.state = mid_line_state;
1359 break;
1360 case mid_line_state + invalid_char_cmd:
1361 case new_line_state + invalid_char_cmd:
1362 case skip_blanks_state + invalid_char_cmd:
1363
1364 tex_aux_invalid_character_error();
1365
1366 return 0;
1367 case mid_line_state + spacer_cmd:
1368
1369 lmt_input_state.cur_input.state = skip_blanks_state;
1370 cur_chr = ' ';
1371 break;
1372 case mid_line_state + end_line_cmd:
1373
1374 lmt_input_state.cur_input.loc = lmt_input_state.cur_input.limit + 1;
1375 cur_cmd = spacer_cmd;
1376 cur_chr = ' ';
1377 break;
1378 case skip_blanks_state + end_line_cmd:
1379 case mid_line_state + comment_cmd:
1380 case new_line_state + comment_cmd:
1381 case skip_blanks_state + comment_cmd:
1382
1383 lmt_input_state.cur_input.loc = lmt_input_state.cur_input.limit + 1;
1384 goto SWITCH;
1385 case new_line_state + end_line_cmd:
1386 if (! auto_paragraph_mode(auto_paragraph_go_on)) {
1387 lmt_input_state.cur_input.loc = lmt_input_state.cur_input.limit + 1;
1388 }
1389
1390 if (auto_paragraph_mode(auto_paragraph_text)) {
1391 cur_cs = null;
1392 cur_cmd = end_paragraph_cmd;
1393 cur_chr = new_line_end_paragraph_code;
1394
1395 } else {
1396 cur_cs = lmt_token_state.par_loc;
1397 cur_cmd = eq_type(cur_cs);
1398 cur_chr = eq_value(cur_cs);
1399 }
1400 break;
1401 case skip_blanks_state + left_brace_cmd:
1402 case new_line_state + left_brace_cmd:
1403 lmt_input_state.cur_input.state = mid_line_state;
1404 ++lmt_input_state.align_state;
1405 break;
1406 case mid_line_state + left_brace_cmd:
1407 ++lmt_input_state.align_state;
1408 break;
1409 case skip_blanks_state + right_brace_cmd:
1410 case new_line_state + right_brace_cmd:
1411 lmt_input_state.cur_input.state = mid_line_state;
1412 --lmt_input_state.align_state;
1413 break;
1414 case mid_line_state + right_brace_cmd:
1415 --lmt_input_state.align_state;
1416 break;
1417 case mid_line_state + math_shift_cmd:
1418 case mid_line_state + alignment_tab_cmd:
1419 case mid_line_state + parameter_cmd:
1420 case mid_line_state + subscript_cmd:
1421 case mid_line_state + letter_cmd:
1422 case mid_line_state + other_char_cmd:
1423 break;
1424
1438 default:
1439 lmt_input_state.cur_input.state = mid_line_state;
1440 break;
1441 }
1442 } else {
1443 if (! io_token_input(lmt_input_state.cur_input.name)) {
1444 lmt_input_state.cur_input.state = new_line_state;
1445 }
1446
1452 do {
1453 next_line_retval r = tex_aux_next_line();
1454 if (r == next_line_restart) {
1455
1456 return 0;
1457 } else if (r == next_line_return) {
1458 return 1;
1459 }
1460 } while (0);
1461
1462 goto SWITCH;
1463 }
1464 return 1;
1465}
1466
1467
1479
1480# define is_hex(a) ((a >= '0' && a <= '9') || (a >= 'a' && a <= 'f'))
1481
1482 inline static halfword tex_aux_two_hex_to_cur_chr(int c1, int c2)
1483 {
1484 return
1485 0x10 * (c1 <= '9' ? c1 - '0' : c1 - 'a' + 10)
1486 + 0x01 * (c2 <= '9' ? c2 - '0' : c2 - 'a' + 10);
1487 }
1488
1489 inline static halfword tex_aux_four_hex_to_cur_chr(int c1, int c2,int c3, int c4)
1490 {
1491 return
1492 0x1000 * (c1 <= '9' ? c1 - '0' : c1 - 'a' + 10)
1493 + 0x0100 * (c2 <= '9' ? c2 - '0' : c2 - 'a' + 10)
1494 + 0x0010 * (c3 <= '9' ? c3 - '0' : c3 - 'a' + 10)
1495 + 0x0001 * (c4 <= '9' ? c4 - '0' : c4 - 'a' + 10);
1496}
1497
1498inline static halfword tex_aux_six_hex_to_cur_chr(int c1, int c2, int c3, int c4, int c5, int c6)
1499{
1500 return
1501 0x100000 * (c1 <= '9' ? c1 - '0' : c1 - 'a' + 10)
1502 + 0x010000 * (c2 <= '9' ? c2 - '0' : c2 - 'a' + 10)
1503 + 0x001000 * (c3 <= '9' ? c3 - '0' : c3 - 'a' + 10)
1504 + 0x000100 * (c4 <= '9' ? c4 - '0' : c4 - 'a' + 10)
1505 + 0x000010 * (c5 <= '9' ? c5 - '0' : c5 - 'a' + 10)
1506 + 0x000001 * (c6 <= '9' ? c6 - '0' : c6 - 'a' + 10);
1507
1508}
1509
1510static int tex_aux_process_sup_mark(void)
1511{
1512 if (cur_chr == lmt_fileio_state.io_buffer[lmt_input_state.cur_input.loc]) {
1513 if (lmt_input_state.cur_input.loc < lmt_input_state.cur_input.limit) {
1514 if ((cur_chr == lmt_fileio_state.io_buffer[lmt_input_state.cur_input.loc + 1]) && (cur_chr == lmt_fileio_state.io_buffer[lmt_input_state.cur_input.loc + 2])) {
1515 if ((cur_chr == lmt_fileio_state.io_buffer[lmt_input_state.cur_input.loc + 3]) && (cur_chr == lmt_fileio_state.io_buffer[lmt_input_state.cur_input.loc + 4])) {
1516 if ((lmt_input_state.cur_input.loc + 10) <= lmt_input_state.cur_input.limit) {
1517
1518 int c1 = lmt_fileio_state.io_buffer[lmt_input_state.cur_input.loc + 5];
1519 int c2 = lmt_fileio_state.io_buffer[lmt_input_state.cur_input.loc + 6];
1520 int c3 = lmt_fileio_state.io_buffer[lmt_input_state.cur_input.loc + 7];
1521 int c4 = lmt_fileio_state.io_buffer[lmt_input_state.cur_input.loc + 8];
1522 int c5 = lmt_fileio_state.io_buffer[lmt_input_state.cur_input.loc + 9];
1523 int c6 = lmt_fileio_state.io_buffer[lmt_input_state.cur_input.loc + 10];
1524 if (is_hex(c1) && is_hex(c2) && is_hex(c3) && is_hex(c4) && is_hex(c5) && is_hex(c6)) {
1525 lmt_input_state.cur_input.loc += 11;
1526 cur_chr = tex_aux_six_hex_to_cur_chr(c1, c2, c3, c4, c5, c6);
1527 return 1;
1528 } else {
1529 tex_handle_error(
1530 normal_error_type,
1531 "^^^^^^ needs six hex digits",
1532 NULL
1533 );
1534 }
1535 } else {
1536 tex_handle_error(
1537 normal_error_type,
1538 "^^^^^^ needs six hex digits, end of input",
1539 NULL
1540 );
1541 }
1542 } else if ((lmt_input_state.cur_input.loc + 6) <= lmt_input_state.cur_input.limit) {
1543
1544 int c1 = lmt_fileio_state.io_buffer[lmt_input_state.cur_input.loc + 3];
1545 int c2 = lmt_fileio_state.io_buffer[lmt_input_state.cur_input.loc + 4];
1546 int c3 = lmt_fileio_state.io_buffer[lmt_input_state.cur_input.loc + 5];
1547 int c4 = lmt_fileio_state.io_buffer[lmt_input_state.cur_input.loc + 6];
1548 if (is_hex(c1) && is_hex(c2) && is_hex(c3) && is_hex(c4)) {
1549 lmt_input_state.cur_input.loc += 7;
1550 cur_chr = tex_aux_four_hex_to_cur_chr(c1, c2, c3, c4);
1551 return 1;
1552 } else {
1553 tex_handle_error(
1554 normal_error_type,
1555 "^^^^ needs four hex digits",
1556 NULL
1557 );
1558 }
1559 } else {
1560 tex_handle_error(
1561 normal_error_type,
1562 "^^^^ needs four hex digits, end of input",
1563 NULL
1564 );
1565 }
1566 } else if ((lmt_input_state.cur_input.loc + 2) <= lmt_input_state.cur_input.limit) {
1567
1568 int c1 = lmt_fileio_state.io_buffer[lmt_input_state.cur_input.loc + 1];
1569 int c2 = lmt_fileio_state.io_buffer[lmt_input_state.cur_input.loc + 2];
1570 if (is_hex(c1) && is_hex(c2)) {
1571 lmt_input_state.cur_input.loc += 3;
1572 cur_chr = tex_aux_two_hex_to_cur_chr(c1, c2);
1573 return 1;
1574 }
1575 }
1576
1577 {
1578 int c1 = lmt_fileio_state.io_buffer[lmt_input_state.cur_input.loc + 1];
1579 if (c1 < 0x80) {
1580 lmt_input_state.cur_input.loc = lmt_input_state.cur_input.loc + 2;
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590 cur_chr = (c1 < 0x40 ? c1 + 0x40 : c1 - 0x40);
1591 return 1;
1592 }
1593 }
1594 }
1595 }
1596 return 0;
1597}
1598
1599
1615
1616
1625
1626static int tex_aux_check_expanded_code(int *kk, halfword *chr)
1627{
1628 if (sup_mark_mode_par > 1 || (sup_mark_mode_par == 1 && cur_mode == mmode)) {
1629 return 0;
1630 } else {
1631 int k = *kk;
1632
1633 if (lmt_fileio_state.io_buffer[k] == *chr && k < lmt_input_state.cur_input.limit) {
1634 int d = 1;
1635 int l;
1636 if ((*chr == lmt_fileio_state.io_buffer[k + 1]) && (*chr == lmt_fileio_state.io_buffer[k + 2])) {
1637 if ((*chr == lmt_fileio_state.io_buffer[k + 3]) && (*chr == lmt_fileio_state.io_buffer[k + 4])) {
1638 if ((k + 10) <= lmt_input_state.cur_input.limit) {
1639 int c1 = lmt_fileio_state.io_buffer[k + 6 - 1];
1640 int c2 = lmt_fileio_state.io_buffer[k + 6 ];
1641 int c3 = lmt_fileio_state.io_buffer[k + 6 + 1];
1642 int c4 = lmt_fileio_state.io_buffer[k + 6 + 2];
1643 int c5 = lmt_fileio_state.io_buffer[k + 6 + 3];
1644 int c6 = lmt_fileio_state.io_buffer[k + 6 + 4];
1645 if (is_hex(c1) && is_hex(c2) && is_hex(c3) && is_hex(c4) && is_hex(c5) && is_hex(c6)) {
1646 d = 6;
1647 *chr = tex_aux_six_hex_to_cur_chr(c1, c2, c3, c4, c5, c6);
1648 } else {
1649 tex_handle_error(
1650 normal_error_type,
1651 "^^^^^^ needs six hex digits",
1652 NULL
1653 );
1654 }
1655 } else {
1656 tex_handle_error(
1657 normal_error_type,
1658 "^^^^^^ needs six hex digits, end of input",
1659 NULL
1660 );
1661 }
1662 } else if ((k + 6) <= lmt_input_state.cur_input.limit) {
1663 int c1 = lmt_fileio_state.io_buffer[k + 4 - 1];
1664 int c2 = lmt_fileio_state.io_buffer[k + 4 ];
1665 int c3 = lmt_fileio_state.io_buffer[k + 4 + 1];
1666 int c4 = lmt_fileio_state.io_buffer[k + 4 + 2];
1667 if (is_hex(c1) && is_hex(c2) && is_hex(c3) && is_hex(c4)) {
1668 d = 4;
1669 *chr = tex_aux_four_hex_to_cur_chr(c1, c2, c3, c4);
1670 } else {
1671 tex_handle_error(
1672 normal_error_type,
1673 "^^^^ needs four hex digits",
1674 NULL
1675 );
1676 }
1677 } else {
1678 tex_handle_error(
1679 normal_error_type,
1680 "^^^^ needs four hex digits, end of input",
1681 NULL
1682 );
1683 }
1684 } else {
1685 int c1 = lmt_fileio_state.io_buffer[k + 1];
1686 if (c1 < 0x80) {
1687 d = 1;
1688 if (is_hex(c1) && (k + 2) <= lmt_input_state.cur_input.limit) {
1689 int c2 = lmt_fileio_state.io_buffer[k + 2];
1690 if (is_hex(c2)) {
1691 d = 2;
1692 *chr = tex_aux_two_hex_to_cur_chr(c1, c2);
1693 } else {
1694 *chr = (c1 < 0x40 ? c1 + 0x40 : c1 - 0x40);
1695 }
1696 } else {
1697 *chr = (c1 < 0x40 ? c1 + 0x40 : c1 - 0x40);
1698 }
1699 }
1700 }
1701 if (d > 2) {
1702 d = 2 * d - 1;
1703 } else {
1704 d++;
1705 }
1706 if (*chr <= 0x7F) {
1707 lmt_fileio_state.io_buffer[k - 1] = (unsigned char) *chr;
1708 } else if (*chr <= 0x7FF) {
1709 lmt_fileio_state.io_buffer[k - 1] = (unsigned char) (0xC0 + *chr / 0x40);
1710 k++;
1711 d--;
1712 lmt_fileio_state.io_buffer[k - 1] = (unsigned char) (0x80 + *chr % 0x40);
1713 } else if (*chr <= 0xFFFF) {
1714 lmt_fileio_state.io_buffer[k - 1] = (unsigned char) (0xE0 + *chr / 0x1000);
1715 k++;
1716 d--;
1717 lmt_fileio_state.io_buffer[k - 1] = (unsigned char) (0x80 + (*chr % 0x1000) / 0x40);
1718 k++;
1719 d--;
1720 lmt_fileio_state.io_buffer[k - 1] = (unsigned char) (0x80 + (*chr % 0x1000) % 0x40);
1721 } else {
1722 lmt_fileio_state.io_buffer[k - 1] = (unsigned char) (0xF0 + *chr / 0x40000);
1723 k++;
1724 d--;
1725 lmt_fileio_state.io_buffer[k - 1] = (unsigned char) (0x80 + (*chr % 0x40000) / 0x1000);
1726 k++;
1727 d--;
1728 lmt_fileio_state.io_buffer[k - 1] = (unsigned char) (0x80 + ((*chr % 0x40000) % 0x1000) / 0x40);
1729 k++;
1730 d--;
1731 lmt_fileio_state.io_buffer[k - 1] = (unsigned char) (0x80 + ((*chr % 0x40000) % 0x1000) % 0x40);
1732 }
1733 l = k;
1734 lmt_input_state.cur_input.limit -= d;
1735 while (l <= lmt_input_state.cur_input.limit) {
1736 lmt_fileio_state.io_buffer[l] = lmt_fileio_state.io_buffer[l + d];
1737 l++;
1738 }
1739 *kk = k;
1740 cur_chr = *chr;
1741 return 1;
1742 } else {
1743 return 0;
1744 }
1745 }
1746}
1747
1748static int tex_aux_scan_control_sequence(void)
1749{
1750 int state = mid_line_state;
1751 if (lmt_input_state.cur_input.loc > lmt_input_state.cur_input.limit) {
1752
1753 cur_cs = null_cs;
1754 } else {
1755
1756 while (1) {
1757 int loc = lmt_input_state.cur_input.loc;
1758 halfword chr = get_unichar_from_buffer(&loc);
1759 halfword cat = tex_aux_the_cat_code(chr);
1760 if (cat != letter_cmd || loc > lmt_input_state.cur_input.limit) {
1761 if (cat == spacer_cmd) {
1762 state = skip_blanks_state;
1763 } else {
1764 state = mid_line_state;
1765 if (cat == superscript_cmd && tex_aux_check_expanded_code(&loc, &chr)) {
1766 continue;
1767 }
1768 }
1769 } else {
1770 state = skip_blanks_state;
1771
1772
1773
1774
1775
1776 while (cat == letter_cmd && loc <= lmt_input_state.cur_input.limit) {
1777 chr = get_unichar_from_buffer(&loc);
1778 cat = tex_aux_the_cat_code(chr);
1779 }
1780
1781
1782 if (cat == superscript_cmd && tex_aux_check_expanded_code(&loc, &chr)) {
1783 continue;
1784 } else if (cat != letter_cmd) {
1785
1786 if (chr <= 0x7F) {
1787 loc -= 1;
1788 } else if (chr > 0xFFFF) {
1789 loc -= 4;
1790 } else if (chr > 0x7FF) {
1791 loc -= 3;
1792 } else {
1793 loc -= 2;
1794 }
1795
1796 }
1797 }
1798 cur_cs = tex_id_locate(lmt_input_state.cur_input.loc, loc - lmt_input_state.cur_input.loc, ! lmt_hash_state.no_new_cs);
1799 lmt_input_state.cur_input.loc = loc;
1800 break;
1801 }
1802 }
1803 cur_cmd = eq_type(cur_cs);
1804 cur_chr = eq_value(cur_cs);
1805 return state;
1806}
1807
1808
1815
1816static void tex_aux_file_warning(void)
1817{
1818 {
1819
1820 halfword saved_stack_ptr = lmt_save_state.save_stack_data.ptr;
1821 quarterword saved_group = cur_group;
1822 quarterword saved_level = cur_level;
1823 lmt_save_state.save_stack_data.ptr = cur_boundary;
1824 while (lmt_input_state.in_stack[lmt_input_state.in_stack_data.ptr].group != lmt_save_state.save_stack_data.ptr) {
1825 --cur_level;
1826 tex_print_nlp();
1827 tex_print_format("Warning: end of file when %G is incomplete", 1);
1828 cur_group = save_level(lmt_save_state.save_stack_data.ptr);
1829 lmt_save_state.save_stack_data.ptr = save_value(lmt_save_state.save_stack_data.ptr);
1830 }
1831
1832 lmt_save_state.save_stack_data.ptr = saved_stack_ptr;
1833 cur_level = saved_level;
1834 cur_group = saved_group;
1835 }
1836 {
1837 condition_state_info saved_condition_state = lmt_condition_state;
1838 while (lmt_input_state.in_stack[lmt_input_state.in_stack_data.ptr].if_ptr != lmt_condition_state.cond_ptr) {
1839
1840 tex_print_nlp();
1841 tex_print_format("Warning: end of file when %C", if_test_cmd, lmt_condition_state.cur_if);
1842 if (lmt_condition_state.if_limit == fi_code) {
1843 tex_print_str_esc("else");
1844 }
1845 if (lmt_condition_state.if_line) {
1846 tex_print_format(" entered on line %i", lmt_condition_state.if_line);
1847 }
1848 tex_print_str(" is incomplete");
1849 lmt_condition_state.cur_if = if_limit_subtype(lmt_condition_state.cond_ptr);
1850 lmt_condition_state.cur_unless = if_limit_unless(lmt_condition_state.cond_ptr);
1851 lmt_condition_state.if_step = if_limit_step(lmt_condition_state.cond_ptr);
1852 lmt_condition_state.if_unless = if_limit_stepunless(lmt_condition_state.cond_ptr);
1853 lmt_condition_state.if_limit = if_limit_type(lmt_condition_state.cond_ptr);
1854 lmt_condition_state.if_line = if_limit_line(lmt_condition_state.cond_ptr);
1855 lmt_condition_state.cond_ptr = node_next(lmt_condition_state.cond_ptr);
1856 }
1857 lmt_condition_state = saved_condition_state;
1858 }
1859 tex_print_nlp();
1860 if (tracing_nesting_par > 1) {
1861 tex_show_context();
1862 }
1863 if (lmt_error_state.history == spotless) {
1864 lmt_error_state.history = warning_issued;
1865 }
1866}
1867
1868static void tex_aux_check_validity(void)
1869{
1870 switch (lmt_input_state.scanner_status) {
1871 case scanner_is_normal:
1872 break;
1873 case scanner_is_skipping:
1874 tex_handle_error(
1875 condition_error_type,
1876 "The file ended while I was skipping conditional text.",
1877 "This kind of error happens when you say '\\if...' and forget the\n"
1878 "matching '\\fi'. It can also be that you use '\\orelse' or '\\orunless\n'"
1879 "in the wrong way. Or maybe a forbidden control sequence was encountered."
1880 );
1881 break;
1882 case scanner_is_defining:
1883 tex_handle_error(runaway_error_type, "The file ended when scanning a definition.", NULL);
1884 break;
1885 case scanner_is_matching:
1886 tex_handle_error(runaway_error_type, "The file ended when scanning an argument.", NULL);
1887 break;
1888 case scanner_is_tolerant:
1889 break;
1890 case scanner_is_aligning:
1891 tex_handle_error(runaway_error_type, "The file ended when scanning an alignment preamble.", NULL);
1892 break;
1893 case scanner_is_absorbing:
1894 tex_handle_error(runaway_error_type, "The file ended when absorbing something.", NULL);
1895 break;
1896 }
1897}
1898
1899static inline int tex_aux_every_eof(void)
1900{
1901 halfword t = lmt_input_state.in_stack[lmt_input_state.cur_input.index].at_end_of_file;
1902 if (t) {
1903
1904 lmt_input_state.cur_input.limit = lmt_fileio_state.io_first - 1;
1905 lmt_input_state.in_stack[lmt_input_state.cur_input.index].end_of_file_seen = 1;
1906 lmt_input_state.in_stack[lmt_input_state.cur_input.index].at_end_of_file = null;
1907 tex_begin_token_list(t, end_file_text);
1908 tex_delete_token_reference(t);
1909 return 1;
1910 } else if (every_eof_par) {
1911
1912 lmt_input_state.cur_input.limit = lmt_fileio_state.io_first - 1;
1913 lmt_input_state.in_stack[lmt_input_state.cur_input.index].end_of_file_seen = 1;
1914 tex_begin_token_list(every_eof_par, every_eof_text);
1915 return 1;
1916 } else {
1917 return 0;
1918 }
1919}
1920
1921inline static next_line_retval tex_aux_next_line(void)
1922{
1923 if (lmt_input_state.cur_input.name > io_initial_input_code) {
1924
1925 unsigned inhibit_eol = 0;
1926 ++lmt_input_state.input_line;
1927 lmt_fileio_state.io_first = lmt_input_state.cur_input.start;
1928 if (! lmt_token_state.force_eof) {
1929 switch (lmt_input_state.cur_input.name) {
1930 case io_lua_input_code:
1931 {
1932 halfword result = null;
1933 int cattable = 0;
1934 int partial = 0;
1935 int finalline = 0;
1936 int type = lmt_cstring_input(&result, &cattable, &partial, &finalline);
1937 switch (type) {
1938 case eof_tex_input:
1939 lmt_token_state.force_eof = 1;
1940 break;
1941 case string_tex_input:
1942
1943 lmt_input_state.cur_input.limit = lmt_fileio_state.io_last;
1944 lmt_input_state.cur_input.cattable = (short) cattable;
1945 lmt_input_state.cur_input.partial = (signed char) partial;
1946 if (finalline || partial || cattable == no_catcode_table_preset) {
1947 inhibit_eol = 1;
1948 }
1949 if (! partial) {
1950 lmt_input_state.cur_input.state = new_line_state;
1951 }
1952 break;
1953 case token_tex_input:
1954
1955 {
1956 halfword t = result - cs_token_flag;
1957 if (t >= 0 && eq_type(t) == input_cmd && eq_value(t) == end_of_input_code && lmt_input_state.cur_input.index > 0) {
1958 tex_end_file_reading();
1959 }
1960 tex_back_input(result);
1961 return next_line_restart;
1962 }
1963 case token_list_tex_input:
1964
1965 if (result) {
1966 tex_begin_backed_up_list(result);
1967 }
1968 return next_line_restart;
1969 case node_tex_input:
1970
1971 if (node_token_overflow(result)) {
1972
1973 tex_back_input(token_val(ignore_cmd, node_token_lsb(result)));
1974 tex_reinsert_token(token_val(node_cmd, node_token_msb(result)));
1975 return next_line_restart;
1976 } else {
1977
1978 tex_back_input(token_val(node_cmd, result));
1979 return next_line_restart;
1980 }
1981 default:
1982 lmt_token_state.force_eof = 1;
1983 break;
1984 }
1985 break;
1986 }
1987 case io_token_input_code:
1988 case io_token_eof_input_code:
1989 {
1990
1991 halfword result = null;
1992 int cattable = 0;
1993 int partial = 0;
1994 int finalline = 0;
1995 int type = lmt_cstring_input(&result, &cattable, &partial, &finalline);
1996 switch (type) {
1997 case eof_tex_input:
1998 lmt_token_state.force_eof = 1;
1999 if (lmt_input_state.cur_input.name == io_token_eof_input_code && tex_aux_every_eof()) {
2000 return next_line_restart;
2001 }
2002 break;
2003 case string_tex_input:
2004
2005 lmt_input_state.cur_input.limit = lmt_fileio_state.io_last;
2006 lmt_input_state.cur_input.cattable = (short) cattable;
2007 lmt_input_state.cur_input.partial = (signed char) partial;
2008 inhibit_eol = lmt_input_state.cur_input.name != io_token_eof_input_code;
2009 if (! partial) {
2010 lmt_input_state.cur_input.state = new_line_state;
2011 }
2012 break;
2013 default:
2014 if (result) {
2015
2016 }
2017 lmt_token_state.force_eof = 1;
2018 break;
2019 }
2020 break;
2021 }
2022 case io_tex_macro_code:
2023
2024
2025 default:
2026 if (tex_lua_input_ln()) {
2027
2028 lmt_input_state.cur_input.limit = lmt_fileio_state.io_last;
2029 lmt_input_state.cur_input.cattable = default_catcode_table_preset;
2030 break;
2031 } else if (! lmt_input_state.in_stack[lmt_input_state.cur_input.index].end_of_file_seen && tex_aux_every_eof()) {
2032 return next_line_restart;
2033 } else {
2034 tex_aux_check_validity();
2035 lmt_token_state.force_eof = 1;
2036 break;
2037 }
2038 }
2039 }
2040 if (lmt_token_state.force_eof) {
2041 if (tracing_nesting_par > 0) {
2042 if ((lmt_input_state.in_stack[lmt_input_state.in_stack_data.ptr].group != cur_boundary) || (lmt_input_state.in_stack[lmt_input_state.in_stack_data.ptr].if_ptr != lmt_condition_state.cond_ptr)) {
2043 if (! io_token_input(lmt_input_state.cur_input.name)) {
2044
2045 tex_aux_file_warning();
2046 }
2047 }
2048 }
2049 if (io_file_input(lmt_input_state.cur_input.name)) {
2050 tex_report_stop_file();
2051 --lmt_input_state.open_files;
2052 }
2053 lmt_token_state.force_eof = 0;
2054 tex_end_file_reading();
2055 return next_line_restart;
2056 } else {
2057 if (inhibit_eol || end_line_char_inactive) {
2058 lmt_input_state.cur_input.limit--;
2059 } else {
2060 lmt_fileio_state.io_buffer[lmt_input_state.cur_input.limit] = (unsigned char) end_line_char_par;
2061 }
2062 lmt_fileio_state.io_first = lmt_input_state.cur_input.limit + 1;
2063 lmt_input_state.cur_input.loc = lmt_input_state.cur_input.start;
2064
2065 }
2066 } else if (lmt_input_state.input_stack_data.ptr > 0) {
2067 cur_cmd = 0;
2068 cur_chr = 0;
2069 return next_line_return;
2070 } else {
2071
2072 switch (lmt_print_state.selector) {
2073 case no_print_selector_code:
2074 case terminal_selector_code:
2075 tex_open_log_file();
2076 break;
2077 }
2078 tex_handle_error(eof_error_type, "end of file encountered", NULL);
2079
2080 if (lmt_error_state.interaction > nonstop_mode) {
2081 tex_fatal_error("aborting job");
2082 }
2083 }
2084
2085 return next_line_ok;
2086}
2087
2088halfword tex_get_at_end_of_file(void)
2089{
2090 for (int i = lmt_input_state.input_stack_data.ptr; i > 0; i--) {
2091 if (lmt_input_state.input_stack[i].name == io_file_input_code) {
2092 return lmt_input_state.in_stack[lmt_input_state.input_stack[i].index].at_end_of_file;
2093 }
2094 }
2095 return null;
2096}
2097
2098void tex_set_at_end_of_file(halfword h)
2099{
2100 for (int i = lmt_input_state.input_stack_data.ptr; i > 0; i--) {
2101 if (lmt_input_state.input_stack[i].name == io_file_input_code) {
2102 lmt_input_state.in_stack[lmt_input_state.input_stack[i].index].at_end_of_file = h;
2103 return;
2104 }
2105 }
2106 tex_flush_token_list(h);
2107}
2108
2109
2112
2113static int tex_aux_get_next_tokenlist(void)
2114{
2115 halfword t = token_info(lmt_input_state.cur_input.loc);
2116
2117 lmt_input_state.cur_input.loc = token_link(lmt_input_state.cur_input.loc);
2118 if (t >= cs_token_flag) {
2119
2120 cur_cs = t - cs_token_flag;
2121 cur_cmd = eq_type(cur_cs);
2122 if (cur_cmd == deep_frozen_dont_expand_cmd) {
2123
2131 cur_cs = token_info(lmt_input_state.cur_input.loc) - cs_token_flag;
2132 lmt_input_state.cur_input.loc = null;
2133 cur_cmd = eq_type(cur_cs);
2134 if (cur_cmd > max_command_cmd) {
2135 cur_cmd = relax_cmd;
2136
2137 cur_chr = no_expand_relax_code;
2138 return 1;
2139 }
2140 }
2141 cur_chr = eq_value(cur_cs);
2142 } else {
2143 cur_cmd = token_cmd(t);
2144 cur_chr = token_chr(t);
2145 switch (cur_cmd) {
2146 case left_brace_cmd:
2147 ++lmt_input_state.align_state;
2148 break;
2149 case right_brace_cmd:
2150 --lmt_input_state.align_state;
2151 break;
2152 case active_char_cmd:
2153 if ((cur_mode == mmode || lmt_nest_state.math_mode) && tex_check_active_math_char(cur_chr)) {
2154
2155 }
2156 break;
2157 case parameter_reference_cmd:
2158 {
2159
2160 halfword p = lmt_input_state.parameter_stack[lmt_input_state.cur_input.parameter_start + cur_chr - 1];
2161 if (p) {
2162 tex_begin_parameter_list(p);
2163 }
2164 return 0;
2165 }
2166 }
2167 }
2168 return 1;
2169}
2170
2171
2182
2183void tex_get_next(void)
2184{
2185 while (1) {
2186 cur_cs = 0;
2187 if (lmt_input_state.cur_input.state != token_list_state) {
2188
2189 if (! tex_aux_get_next_file()) {
2190 continue;
2191 } else {
2192
2193 }
2194 } else if (! lmt_input_state.cur_input.loc) {
2195
2196 tex_end_token_list();
2197 continue;
2198 } else if (! tex_aux_get_next_tokenlist()) {
2199
2200 continue;
2201 }
2202
2203
2204
2205
2206
2207
2208
2209 switch (cur_cmd) {
2210 case alignment_tab_cmd:
2211 case alignment_cmd:
2212
2213 if (lmt_input_state.align_state) {
2214 return;
2215 } else {
2216 tex_insert_alignment_template();
2217 continue;
2218 }
2219 default:
2220 return;
2221 }
2222 }
2223}
2224
2225void tex_get_next_non_spacer(void)
2226{
2227 while (1) {
2228 cur_cs = 0;
2229 if (lmt_input_state.cur_input.state != token_list_state) {
2230
2231 if (! tex_aux_get_next_file()) {
2232 continue;
2233 } else {
2234
2235 }
2236 } else if (! lmt_input_state.cur_input.loc) {
2237
2238 tex_end_token_list();
2239 continue;
2240 } else if (! tex_aux_get_next_tokenlist()) {
2241
2242 continue;
2243 }
2244 switch (cur_cmd) {
2245 case spacer_cmd:
2246 continue;
2247 case alignment_tab_cmd:
2248 case alignment_cmd:
2249
2250 if (lmt_input_state.align_state) {
2251 return;
2252 } else {
2253 tex_insert_alignment_template();
2254 continue;
2255 }
2256 default:
2257 return;
2258 }
2259 }
2260}
2261
2262
2293
2294halfword tex_get_token(void)
2295{
2296 lmt_hash_state.no_new_cs = 0;
2297 tex_get_next();
2298 lmt_hash_state.no_new_cs = 1;
2299 cur_tok = cur_cs ? cs_token_flag + cur_cs : token_val(cur_cmd, cur_chr);
2300 return cur_tok;
2301}
2302
2303
2309
2310void tex_get_x_or_protected(void)
2311{
2312 lmt_hash_state.no_new_cs = 0;
2313 while (1) {
2314 tex_get_next();
2315 if (cur_cmd <= max_command_cmd || is_protected_cmd(cur_cmd)) {
2316 break;
2317 } else {
2318 tex_expand_current_token();
2319 }
2320 }
2321 cur_tok = cur_cs ? cs_token_flag + cur_cs : token_val(cur_cmd, cur_chr);
2322 lmt_hash_state.no_new_cs = 1;
2323}
2324
2325
2326
2327halfword tex_string_to_toks(const char *ss)
2328{
2329 const char *s = ss;
2330 const char *se = ss + strlen(s);
2331
2332 halfword h = null;
2333 halfword p = null;
2334
2335 while (s < se) {
2336 int tl;
2337 halfword t = (halfword) aux_str2uni_len((const unsigned char *) s, &tl);
2338 s += tl;
2339 if (t == ' ') {
2340 t = space_token;
2341 } else {
2342 t += other_token;
2343 }
2344 p = tex_store_new_token(p, t);
2345 if (! h) {
2346 h = p;
2347 }
2348 }
2349 return h;
2350}
2351
2352
2367
2368static halfword lmt_str_toks(lstring b)
2369{
2370 unsigned char *k = (unsigned char *) b.s;
2371 halfword head = null;
2372 halfword tail = head;
2373 while (k < (unsigned char *) b.s + b.l) {
2374 int tl;
2375 halfword t = aux_str2uni_len(k, &tl);
2376 k += tl;
2377 if (t == ' ') {
2378 t = space_token;
2379 } else {
2380 if ((t == '\\') || (t == '"') || (t == '\'') || (t == 10) || (t == 13)) {
2381 tail = tex_store_new_token(tail, escape_token);
2382 if (! head) {
2383 head = tail;
2384 }
2385 if (t == 10) {
2386 t = 'n';
2387 } else if (t == 13) {
2388 t = 'r';
2389 }
2390 }
2391 t += other_token;
2392 }
2393 tail = tex_store_new_token(tail, t);
2394 if (! head) {
2395 head = tail;
2396 }
2397 }
2398 return head;
2399}
2400
2401
2408
2409halfword tex_str_toks(lstring s, halfword *tail)
2410{
2411 halfword h = null;
2412 halfword p = null;
2413 if (s.s) {
2414 unsigned char *k = s.s;
2415 unsigned char *l = k + s.l;
2416 while (k < l) {
2417 int tl;
2418 halfword t = aux_str2uni_len(k, &tl);
2419 if (t == ' ') {
2420 t = space_token;
2421 } else {
2422 t += other_token;
2423 }
2424 k += tl;
2425 p = tex_store_new_token(p, t);
2426 if (! h) {
2427 h = p;
2428 }
2429 }
2430 }
2431 if (tail) {
2432 *tail = null;
2433 }
2434 return h;
2435}
2436
2437halfword tex_cur_str_toks(halfword *tail)
2438{
2439 halfword h = null;
2440 halfword p = null;
2441 unsigned char *k = (unsigned char *) lmt_string_pool_state.string_temp;
2442 if (k) {
2443 unsigned char *l = k + lmt_string_pool_state.string_temp_top;
2444
2445 while (k < l) {
2446
2447 int tl;
2448 halfword t = aux_str2uni_len(k, &tl);
2449 if (t == ' ') {
2450 t = space_token;
2451 } else {
2452 t += other_token;
2453 }
2454 k += tl;
2455 p = tex_store_new_token(p, t);
2456 if (! h) {
2457 h = p;
2458 }
2459 }
2460 }
2461 tex_reset_cur_string();
2462 if (tail) {
2463 *tail = p;
2464 }
2465 return h;
2466}
2467
2468
2474
2475halfword tex_str_scan_toks(int ct, lstring ls)
2476{
2477
2478 unsigned char *k = ls.s;
2479 unsigned char *l = k + ls.l;
2480
2481 halfword h = null;
2482 halfword p = null;
2483 while (k < l) {
2484 int cc;
2485
2486 int lt;
2487 halfword t = aux_str2uni_len(k, <);
2488 k += lt;
2489 cc = tex_get_cat_code(ct, t);
2490 if (cc == 0) {
2491
2492 int lname = 0 ;
2493 int s = 0 ;
2494 int c = 0 ;
2495 unsigned char *name = k ;
2496 while (k < l) {
2497 t = (halfword) aux_str2uni_len((const unsigned char *) k, &s);
2498 c = tex_get_cat_code(ct, t);
2499 if (c == 11) {
2500 k += s ;
2501 lname += s ;
2502 } else if (c == 10) {
2503
2504 k += s ;
2505 break ;
2506 } else {
2507 break ;
2508 }
2509 }
2510 if (s > 0) {
2511
2512 halfword cs = tex_string_locate_only((const char *) name, lname);
2513 if (cs == undefined_control_sequence) {
2514
2515 t += cc * (1<<21);
2516 k = name ;
2517 } else {
2518 t = cs_token_flag + cs;
2519 }
2520 } else {
2521
2525 t += cc * (1 << 21);
2526 k = name ;
2527 }
2528 } else {
2529
2532 t += cc * (1 << 21);
2533 }
2534 p = tex_store_new_token(p, t);
2535 if (! h) {
2536 h = p;
2537 }
2538 }
2539 return h;
2540}
2541
2542
2543
2544static void tex_aux_set_toks_register(halfword loc, singleword cmd, halfword t, int g)
2545{
2546 halfword ref = get_reference_token();
2547 set_token_link(ref, t);
2548 tex_define((g > 0) ? global_flag_bit : 0, loc, cmd == internal_toks_cmd ? internal_toks_reference_cmd : register_toks_reference_cmd, ref);
2549}
2550
2551static halfword tex_aux_append_copied_toks_list(halfword loc, singleword cmd, int g, halfword s, halfword t, halfword *tail)
2552{
2553 halfword ref = get_reference_token();
2554 halfword p = ref;
2555 while (s) {
2556 p = tex_store_new_token(p, token_info(s));
2557 s = token_link(s);
2558 }
2559 while (t) {
2560 p = tex_store_new_token(p, token_info(t));
2561 t = token_link(t);
2562 }
2563 tex_define((g > 0) ? global_flag_bit : 0, loc, cmd == internal_toks_cmd ? internal_toks_reference_cmd : register_toks_reference_cmd, ref);
2564 if (tail) {
2565 *tail = p;
2566 }
2567 return ref;
2568}
2569
2570
2571
2572halfword tex_copy_token_list(halfword h1, halfword *t)
2573{
2574 halfword h2 = tex_store_new_token(null, token_info(h1));
2575 halfword t1 = token_link(h1);
2576 halfword t2 = h2;
2577 while (t1) {
2578 t2 = tex_store_new_token(t2, token_info(t1));
2579 t1 = token_link(t1);
2580 }
2581 if (t) {
2582 *t = t2;
2583 }
2584 return h2;
2585}
2586
2587
2623
2624# define immediate_permitted(loc,target) ((eq_level(loc) == cur_level) && (get_token_reference(target) == 0))
2625
2626typedef enum combine_operations {
2627 combine_assign,
2628 combine_append,
2629 combine_prepend,
2630} combine_operations;
2631
2632void tex_run_combine_the_toks(void)
2633{
2634 halfword source = null;
2635 halfword target = null;
2636 halfword append, expand, global;
2637 halfword nt, ns;
2638 singleword cmd;
2639
2640 switch (cur_chr) {
2641 case expanded_toks_code: append = combine_assign; global = 0; expand = 1; break;
2642 case append_toks_code: append = combine_append; global = 0; expand = 0; break;
2643 case append_expanded_toks_code: append = combine_append; global = 0; expand = 1; break;
2644 case prepend_toks_code: append = combine_prepend; global = 0; expand = 0; break;
2645 case prepend_expanded_toks_code: append = combine_prepend; global = 0; expand = 1; break;
2646 case global_expanded_toks_code: append = combine_assign; global = 1; expand = 1; break;
2647 case global_append_toks_code: append = combine_append; global = 1; expand = 0; break;
2648 case global_append_expanded_toks_code: append = combine_append; global = 1; expand = 1; break;
2649 case global_prepend_toks_code: append = combine_prepend; global = 1; expand = 0; break;
2650 case global_prepend_expanded_toks_code: append = combine_prepend; global = 1; expand = 1; break;
2651 default: append = combine_assign; global = 0; expand = 0; break;
2652 }
2653
2654 tex_get_x_token();
2655 if (cur_cmd == register_toks_cmd || cur_cmd == internal_toks_cmd) {
2656 nt = eq_value(cur_cs);
2657 cmd = (singleword) cur_cmd;
2658 } else {
2659
2660 tex_back_input(cur_tok);
2661 nt = register_toks_location(tex_scan_toks_register_number());
2662 cmd = register_toks_cmd;
2663 }
2664 target = eq_value(nt);
2665
2666 do {
2667 tex_get_x_token();
2668 } while (cur_cmd == spacer_cmd);
2669 if (cur_cmd == left_brace_cmd) {
2670 source = expand ? tex_scan_toks_expand(1, NULL, 0, 0) : tex_scan_toks_normal(1, NULL);
2671
2672 if (source) {
2673 if (target) {
2674 halfword s = token_link(source);
2675 if (s) {
2676 halfword t = token_link(target);
2677 if (! t) {
2678
2679 set_token_link(target, s);
2680 token_link(source) = null;
2681 } else {
2682 switch (append) {
2683 case combine_assign:
2684 goto ASSIGN_1;
2685 case 1:
2686
2687 if (immediate_permitted(nt,target)) {
2688 halfword p = t;
2689 while (token_link(p)) {
2690 p = token_link(p);
2691 }
2692 token_link(p) = s;
2693 token_link(source) = null;
2694 } else {
2695 tex_aux_append_copied_toks_list(nt, cmd, global, t, s, NULL);
2696 }
2697 break;
2698 case 2:
2699
2700 if (immediate_permitted(nt,target)) {
2701 halfword p = s;
2702 while (token_link(p)) {
2703 p = token_link(p);
2704 }
2705 token_link(source) = null;
2706 set_token_link(p, t);
2707 set_token_link(target, s);
2708 } else {
2709 tex_aux_append_copied_toks_list(nt, cmd, global, s, t, NULL);
2710 }
2711 break;
2712 }
2713 }
2714 }
2715 } else {
2716 ASSIGN_1:
2717 tex_aux_set_toks_register(nt, cmd, token_link(source), global);
2718 token_link(source) = null;
2719 }
2720 tex_flush_token_list(source);
2721 }
2722 } else {
2723
2724 if (cur_cmd == register_toks_cmd) {
2725 ns = register_toks_number(eq_value(cur_cs));
2726 } else if (cur_cmd == internal_toks_cmd) {
2727 ns = internal_toks_number(eq_value(cur_cs));
2728 } else {
2729 ns = tex_scan_toks_register_number();
2730 }
2731
2732 source = toks_register(ns);
2733 if (source) {
2734 if (target) {
2735 if (expand) {
2736 halfword defref = lmt_input_state.def_ref;
2737 tex_back_input(right_brace_token + '}');
2738 tex_begin_token_list(source, token_text);
2739 source = tex_scan_toks_expand(1, NULL, 0, 1);
2740 lmt_input_state.def_ref = defref;
2741 switch (append) {
2742 case combine_assign:
2743 eq_value(nt) = source;
2744 break;
2745 case combine_append:
2746 if (immediate_permitted(nt, target)) {
2747 halfword p = tex_tail_of_token_list(token_link(target));
2748 token_link(p) = token_link(source);
2749 } else {
2750 halfword tail;
2751 tex_aux_append_copied_toks_list(nt, cmd, global, target, null, &tail);
2752 token_link(tail) = token_link(source);
2753 }
2754 tex_put_available_token(source);
2755 break;
2756 case combine_prepend:
2757 if (immediate_permitted(nt, target)) {
2758 halfword p = tex_tail_of_token_list(token_link(source));
2759 token_link(p) = token_link(target);
2760 token_link(target) = token_link(source);
2761 } else {
2762 halfword head = tex_aux_append_copied_toks_list(nt, cmd, global, target, null, NULL);
2763 halfword tail = tex_tail_of_token_list(token_link(source));
2764 token_link(tail) = token_link(head);
2765 token_link(head) = token_link(source);
2766 }
2767 tex_put_available_token(source);
2768 break;
2769 }
2770 } else {
2771 halfword t = token_link(target);
2772 halfword s = token_link(source);
2773 switch (append) {
2774 case combine_assign:
2775 tex_add_token_reference(source);
2776 eq_value(nt) = source;
2777 break;
2778 case combine_append:
2779 if (immediate_permitted(nt, target)) {
2780 halfword p = tex_tail_of_token_list(t);
2781 while (s) {
2782 p = tex_store_new_token(p, token_info(s));
2783 s = token_link(s);
2784 }
2785 } else {
2786 tex_aux_append_copied_toks_list(nt, cmd, global, t, s, NULL);
2787 }
2788 break;
2789 case combine_prepend:
2790 if (immediate_permitted(nt, target)) {
2791 halfword h = null;
2792 halfword p = null;
2793 while (s) {
2794 p = tex_store_new_token(p, token_info(s));
2795 if (! h) {
2796 h = p;
2797 }
2798 s = token_link(s);
2799 }
2800 set_token_link(p, t);
2801 set_token_link(target, h);
2802 } else {
2803 tex_aux_append_copied_toks_list(nt, cmd, global, s, t, NULL);
2804 }
2805 break;
2806 }
2807 }
2808 } else if (expand) {
2809 halfword defref = lmt_input_state.def_ref;
2810 tex_back_input(right_brace_token + '}');
2811 tex_begin_token_list(source, token_text);
2812 source = tex_scan_toks_expand(1, NULL, 0, 1);
2813 eq_value(nt) = source;
2814 lmt_input_state.def_ref = defref;
2815 } else {
2816
2817 tex_add_token_reference(source);
2818 eq_value(nt) = source;
2819 }
2820 }
2821 }
2822}
2823
2824
2830
2831static void tex_aux_print_job_name(void)
2832{
2833 if (lmt_fileio_state.job_name) {
2834
2835 char *s = lmt_fileio_state.job_name;
2836 int callback_id = lmt_callback_defined(process_jobname_callback);
2837 if (callback_id > 0) {
2838 char *ss;
2839 int lua_retval = lmt_run_callback(lmt_lua_state.lua_instance, callback_id, "S->S", s, &ss);
2840 if (lua_retval && ss) {
2841 s = ss;
2842 }
2843 }
2844 tex_print_str(s);
2845 }
2846}
2847
2848
2855
2856
2857
2858# define push_selector { \
2859 saved_selector = lmt_print_state.selector; \
2860 lmt_print_state.selector = new_string_selector_code; \
2861}
2862
2863# define pop_selector { \
2864 lmt_print_state.selector = saved_selector; \
2865}
2866
2867void tex_run_convert_tokens(halfword code)
2868{
2869
2870 switch (code) {
2871
2877 case number_code:
2878 {
2879 int saved_selector;
2880 halfword v = tex_scan_integer(0, NULL);
2881 push_selector;
2882 tex_print_int(v);
2883 pop_selector;
2884 break;
2885 }
2886 case to_integer_code:
2887 case to_hexadecimal_code:
2888 {
2889 int saved_selector;
2890 halfword v = tex_scan_integer(0, NULL);
2891 tex_get_x_token();
2892 if (cur_cmd != relax_cmd) {
2893 tex_back_input(cur_tok);
2894 }
2895 push_selector;
2896 if (code == to_integer_code) {
2897 tex_print_int(v);
2898 } else {
2899 tex_print_hex(v);
2900 }
2901 pop_selector;
2902 break;
2903 }
2904 case to_scaled_code:
2905 case to_sparse_scaled_code:
2906 case to_dimension_code:
2907 case to_sparse_dimension_code:
2908 {
2909 int saved_selector;
2910 halfword v = tex_scan_dimension(0, 0, 0, 0, NULL);
2911 tex_get_x_token();
2912 if (cur_cmd != relax_cmd) {
2913 tex_back_input(cur_tok);
2914 }
2915 push_selector;
2916 switch (code) {
2917 case to_sparse_dimension_code:
2918 case to_sparse_scaled_code:
2919 tex_print_sparse_dimension(v, no_unit);
2920 break;
2921 default:
2922 tex_print_dimension(v, no_unit);
2923 break;
2924 }
2925 switch (code) {
2926 case to_dimension_code:
2927 case to_sparse_dimension_code:
2928 tex_print_unit(pt_unit);
2929 break;
2930 }
2931 pop_selector;
2932 break;
2933 }
2934 case to_mathstyle_code:
2935 {
2936 int saved_selector;
2937 halfword v = tex_scan_math_style_identifier(1, 0);
2938 push_selector;
2939 tex_print_int(v);
2940 pop_selector;
2941 break;
2942 }
2943 case lua_function_code:
2944 {
2945
2946 halfword v = tex_scan_integer(0, NULL);
2947 if (v > 0) {
2948 strnumber u = tex_save_cur_string();
2949 lmt_token_state.luacstrings = 0;
2950 lmt_function_call(v, 0);
2951 tex_restore_cur_string(u);
2952 if (lmt_token_state.luacstrings > 0) {
2953 tex_lua_string_start();
2954 }
2955 } else {
2956 tex_normal_error("luafunction", "invalid number");
2957 }
2958 return;
2959 }
2960 case lua_bytecode_code:
2961 {
2962 halfword v = tex_scan_integer(0, NULL);
2963 if (v < 0 || v > 65535) {
2964 tex_normal_error("luabytecode", "invalid number");
2965 } else {
2966 strnumber u = tex_save_cur_string();
2967 lmt_token_state.luacstrings = 0;
2968 lmt_bytecode_call(v);
2969 tex_restore_cur_string(u);
2970 if (lmt_token_state.luacstrings > 0) {
2971 tex_lua_string_start();
2972 }
2973 }
2974 return;
2975 }
2976 case lua_code:
2977 {
2978 full_scanner_status saved_full_status = tex_save_full_scanner_status();
2979 strnumber u = tex_save_cur_string();
2980 halfword s = tex_scan_toks_expand(0, NULL, 0, 1);
2981 tex_unsave_full_scanner_status(saved_full_status);
2982 lmt_token_state.luacstrings = 0;
2983 lmt_token_call(s);
2984 tex_delete_token_reference(s);
2985 tex_restore_cur_string(u);
2986 if (lmt_token_state.luacstrings > 0) {
2987 tex_lua_string_start();
2988 }
2989
2990 return;
2991 }
2992 case expanded_code:
2993 case semi_expanded_code:
2994 {
2995 full_scanner_status saved_full_status = tex_save_full_scanner_status();
2996 strnumber u = tex_save_cur_string();
2997 halfword s = tex_scan_toks_expand(0, NULL, code == semi_expanded_code, 0);
2998 tex_unsave_full_scanner_status(saved_full_status);
2999 if (token_link(s)) {
3000 tex_begin_inserted_list(token_link(s));
3001 token_link(s) = null;
3002 }
3003 tex_put_available_token(s);
3004 tex_restore_cur_string(u);
3005
3006 return;
3007 }
3008
3026
3027
3028
3038 case string_code:
3039 case cs_string_code:
3040 case cs_active_code:
3041 {
3042 int saved_selector;
3043 int saved_scanner_status = lmt_input_state.scanner_status;
3044 lmt_input_state.scanner_status = scanner_is_normal;
3045 tex_get_token();
3046 lmt_input_state.scanner_status = saved_scanner_status;
3047 push_selector;
3048 if (code == cs_active_code) {
3049 tex_print_str(active_character_namespace);
3050 }
3051 if (cur_cs) {
3052 if (code == cs_string_code) {
3053 tex_print_cs_name(cur_cs);
3054 } else {
3055 tex_print_cs(cur_cs);
3056 }
3057 } else {
3058 tex_print_tex_str(cur_chr);
3059 }
3060 pop_selector;
3061 break;
3062 }
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3126 case detokenized_code:
3127
3128 {
3129 int saved_selector;
3130 int saved_scanner_status = lmt_input_state.scanner_status;
3131 halfword t = null;
3132 lmt_input_state.scanner_status = scanner_is_normal;
3133 tex_get_token();
3134 lmt_input_state.scanner_status = saved_scanner_status;
3135 t = tex_get_available_token(cur_tok);
3136 push_selector;
3137 tex_show_token_list(t, 0, 0);
3138 tex_put_available_token(t);
3139 pop_selector;
3140 break;
3141 }
3142 case detokened_code:
3143
3144 {
3145 int saved_selector;
3146 int saved_scanner_status = lmt_input_state.scanner_status;
3147 halfword list = null;
3148 lmt_input_state.scanner_status = scanner_is_normal;
3149 tex_get_token();
3150 lmt_input_state.scanner_status = saved_scanner_status;
3151 switch (cur_cmd) {
3152 case call_cmd:
3153 case protected_call_cmd:
3154 case semi_protected_call_cmd:
3155 case constant_call_cmd:
3156 case tolerant_call_cmd:
3157 case tolerant_protected_call_cmd:
3158 case tolerant_semi_protected_call_cmd:
3159 if (! get_token_preamble(cur_chr)) {
3160
3161 list = token_link(cur_chr);
3162 break;
3163 } else {
3164 goto WHATEVER;
3165 }
3166 case internal_toks_cmd:
3167 case register_toks_cmd:
3168 list = token_link(eq_value(cur_chr));
3169 break;
3170 case register_cmd:
3171 if (cur_chr == token_val_level) {
3172 halfword n = tex_scan_toks_register_number();
3173 list = token_link(toks_register(n));
3174 break;
3175 } else {
3176 goto WHATEVER;
3177 }
3178 break;
3179 default:
3180 WHATEVER:
3181 {
3182 halfword t = tex_get_available_token(cur_tok);
3183 push_selector;
3184 tex_show_token_list(t, 0, 0);
3185 pop_selector;
3186 tex_put_available_token(t);
3187 }
3188 break;
3189 }
3190 if (list) {
3191 push_selector;
3192 tex_show_token_list(list, 2, 0);
3193 pop_selector;
3194 }
3195 break;
3196 }
3197 case roman_numeral_code:
3198 {
3199 int saved_selector;
3200 halfword v = tex_scan_integer(0, NULL);
3201 push_selector;
3202 tex_print_roman_int(v);
3203 pop_selector;
3204 break;
3205 }
3206 case meaning_code:
3207 case meaning_full_code:
3208 case meaning_less_code:
3209 case meaning_ful_code:
3210 case meaning_les_code:
3211 case meaning_asis_code:
3212 {
3213 int saved_selector;
3214 int saved_scanner_status = lmt_input_state.scanner_status;
3215 lmt_input_state.scanner_status = scanner_is_normal;
3216 tex_get_token();
3217 lmt_input_state.scanner_status = saved_scanner_status;
3218 push_selector;
3219 tex_print_meaning(code);
3220 pop_selector;
3221 break;
3222 }
3223 case to_character_code:
3224 {
3225 int saved_selector;
3226 int chr = tex_scan_char_number(0);
3227 push_selector;
3228 tex_print_tex_str(chr);
3229 pop_selector;
3230 break;
3231 }
3232 case lua_escape_string_code:
3233
3234 {
3235
3246 lstring str;
3247 int length = 0;
3248
3249 halfword saved_escape_char = escape_char_par;
3250 full_scanner_status saved_full_status = tex_save_full_scanner_status();
3251 halfword result = tex_scan_toks_expand(0, NULL, 0, 0);
3252
3253
3254 escape_char_par = '\\';
3255 str.s = (unsigned char *) tex_tokenlist_to_tstring(result, 0, &length, 0, 0, 0, 0, 1);
3256 str.l = (unsigned) length;
3257
3258 escape_char_par = saved_escape_char;
3259 tex_delete_token_reference(result);
3260 tex_unsave_full_scanner_status(saved_full_status);
3261 if (str.l) {
3262 result = lmt_str_toks(str);
3263 tex_begin_inserted_list(result);
3264 }
3265 return;
3266 }
3267 case font_name_code:
3268 {
3269 int saved_selector;
3270 halfword fnt = tex_scan_font_identifier(NULL);
3271 push_selector;
3272 tex_print_font(fnt);
3273 pop_selector;
3274 break;
3275 }
3276 case font_specification_code:
3277 {
3278 int saved_selector;
3279 halfword fnt = tex_scan_font_identifier(NULL);
3280 push_selector;
3281 tex_append_string((const unsigned char *) font_original(fnt), (unsigned) strlen(font_original(fnt)));
3282 pop_selector;
3283 break;
3284 }
3285 case job_name_code:
3286 {
3287 int saved_selector;
3288 if (! lmt_fileio_state.job_name) {
3289 tex_open_log_file();
3290 }
3291 push_selector;
3292 tex_aux_print_job_name();
3293 pop_selector;
3294 break;
3295 }
3296 case format_name_code:
3297 {
3298 int saved_selector;
3299 if (! lmt_fileio_state.job_name) {
3300 tex_open_log_file();
3301 }
3302 push_selector;
3303 tex_print_str(lmt_engine_state.dump_name);
3304 pop_selector;
3305 break;
3306 }
3307 case luatex_banner_code:
3308 {
3309 int saved_selector;
3310 push_selector;
3311 tex_print_str(lmt_engine_state.luatex_banner);
3312 pop_selector;
3313 break;
3314 }
3315 default:
3316 tex_confusion("convert tokens");
3317 break;
3318 }
3319 {
3320 halfword head = tex_cur_str_toks(NULL);
3321 tex_begin_inserted_list(head);
3322 }
3323}
3324
3325
3328
3329strnumber tex_the_convert_string(halfword c, int i)
3330{
3331 int saved_selector = lmt_print_state.selector;
3332 strnumber ret = 0;
3333 int done = 1 ;
3334 lmt_print_state.selector = new_string_selector_code;
3335 switch (c) {
3336 case number_code:
3337 case to_integer_code:
3338 tex_print_int(i);
3339 break;
3340 case to_hexadecimal_code:
3341 tex_print_hex(i);
3342 break;
3343 case to_scaled_code:
3344 tex_print_dimension(i, no_unit);
3345 break;
3346 case to_sparse_scaled_code:
3347 tex_print_sparse_dimension(i, no_unit);
3348 break;
3349 case to_dimension_code:
3350 tex_print_dimension(i, pt_unit);
3351 break;
3352 case to_sparse_dimension_code:
3353 tex_print_sparse_dimension(i, pt_unit);
3354 break;
3355 case roman_numeral_code:
3356 tex_print_roman_int(i);
3357 break;
3358 case to_character_code:
3359 tex_print_tex_str(i);
3360 break;
3361 case font_name_code:
3362 tex_print_font(i);
3363 break;
3364 case font_specification_code:
3365 tex_print_str(font_original(i));
3366 break;
3367 case job_name_code:
3368 tex_aux_print_job_name();
3369 break;
3370 case format_name_code:
3371 tex_print_str(lmt_engine_state.dump_name);
3372 break;
3373 case luatex_banner_code:
3374 tex_print_str(lmt_engine_state.luatex_banner);
3375 break;
3376 case font_identifier_code:
3377 tex_print_font_identifier(i);
3378 break;
3379 default:
3380 done = 0;
3381 break;
3382 }
3383 if (done) {
3384 ret = tex_make_string();
3385 }
3386 lmt_print_state.selector = saved_selector;
3387 return ret;
3388}
3389
3390
3391
3392strnumber tex_tokens_to_string(halfword p)
3393{
3394 if (lmt_print_state.selector == new_string_selector_code) {
3395 tex_normal_error("tokens", "tokens_to_string() called while selector = new_string");
3396 return get_nullstr();
3397 } else {
3398 int saved_selector = lmt_print_state.selector;
3399 lmt_print_state.selector = new_string_selector_code;
3400 tex_token_show(p);
3401 lmt_print_state.selector = saved_selector;
3402 return tex_make_string();
3403 }
3404}
3405
3406
3424
3425# define default_buffer_size 512
3426# define default_buffer_step 4096
3427
3428
3429
3430static void tex_aux_make_room_in_buffer(int a)
3431{
3432 if (lmt_token_state.bufloc + a + 1 > lmt_token_state.bufmax) {
3433 char *tmp = aux_reallocate_array(lmt_token_state.buffer, sizeof(unsigned char), lmt_token_state.bufmax + default_buffer_step, 1);
3434 if (tmp) {
3435 lmt_token_state.bufmax += default_buffer_step;
3436 } else {
3437
3438 }
3439 lmt_token_state.buffer = tmp;
3440 }
3441}
3442
3443static void tex_aux_append_uchar_to_buffer(int s)
3444{
3445 tex_aux_make_room_in_buffer(4);
3446 if (s <= 0x7F) {
3447 lmt_token_state.buffer[lmt_token_state.bufloc++] = (char) (s);
3448 } else if (s <= 0x7FF) {
3449 lmt_token_state.buffer[lmt_token_state.bufloc++] = (char) (0xC0 + (s / 0x40));
3450 lmt_token_state.buffer[lmt_token_state.bufloc++] = (char) (0x80 + (s % 0x40));
3451 } else if (s <= 0xFFFF) {
3452 lmt_token_state.buffer[lmt_token_state.bufloc++] = (char) (0xE0 + (s / 0x1000));
3453 lmt_token_state.buffer[lmt_token_state.bufloc++] = (char) (0x80 + ((s % 0x1000) / 0x40));
3454 lmt_token_state.buffer[lmt_token_state.bufloc++] = (char) (0x80 + ((s % 0x1000) % 0x40));
3455 } else {
3456 lmt_token_state.buffer[lmt_token_state.bufloc++] = (char) (0xF0 + (s / 0x40000));
3457 lmt_token_state.buffer[lmt_token_state.bufloc++] = (char) (0x80 + ((s % 0x40000) / 0x1000));
3458 lmt_token_state.buffer[lmt_token_state.bufloc++] = (char) (0x80 + (((s % 0x40000) % 0x1000) / 0x40));
3459 lmt_token_state.buffer[lmt_token_state.bufloc++] = (char) (0x80 + (((s % 0x40000) % 0x1000) % 0x40));
3460 }
3461}
3462
3463static void tex_aux_append_char_to_buffer(int c)
3464{
3465 tex_aux_make_room_in_buffer(1);
3466 lmt_token_state.buffer[lmt_token_state.bufloc++] = (char) (c);
3467}
3468
3469
3470
3471static void tex_aux_append_str_to_buffer(const char *s)
3472{
3473 const char *v = s;
3474 tex_aux_make_room_in_buffer((int) strlen(v));
3475
3476 while (*v) {
3477 lmt_token_state.buffer[lmt_token_state.bufloc++] = (char) (*v);
3478 v++;
3479 }
3480}
3481
3482
3483
3484static void tex_aux_append_esc_to_buffer(const char *s)
3485{
3486 int e = escape_char_par;
3487 if (e > 0 && e < cs_offset_value) {
3488 tex_aux_append_uchar_to_buffer(e);
3489 }
3490 tex_aux_append_str_to_buffer(s);
3491}
3492
3493# define is_cat_letter(a) (tex_aux_the_cat_code(aux_str2uni(str_string((a)))) == letter_cmd)
3494
3495
3496
3497char *tex_tokenlist_to_tstring(int pp, int inhibit_par, int *siz, int skippreamble, int nospace, int strip, int wipe, int single)
3498{
3499 if (pp) {
3500
3501 int p = token_link(pp);
3502 if (p) {
3503 int e = escape_char_par;
3504 int n = 0;
3505 int min = 0;
3506 int max = lmt_token_memory_state.tokens_data.top;
3507 int skip = 0;
3508 int tail = p;
3509 int count = 0;
3510 if (lmt_token_state.bufmax > default_buffer_size) {
3511
3512 aux_deallocate_array(lmt_token_state.buffer);
3513 lmt_token_state.buffer = aux_allocate_clear_array(sizeof(unsigned char), default_buffer_size, 1);
3514 lmt_token_state.bufmax = default_buffer_size;
3515 } else if (! lmt_token_state.buffer) {
3516
3517 lmt_token_state.buffer = aux_allocate_clear_array(sizeof(unsigned char), default_buffer_size, 1);
3518 lmt_token_state.bufmax = default_buffer_size;
3519 }
3520 lmt_token_state.bufloc = 0;
3521 if (skippreamble == 1) {
3522 skip = get_token_preamble(pp);
3523 }
3524 while (p) {
3525 if (p < min || p > max) {
3526 tex_aux_append_str_to_buffer(error_string_clobbered(31));
3527 break;
3528 } else {
3529 int info = token_info(p);
3530 if (info < 0) {
3531
3532 tex_aux_append_str_to_buffer(error_string_bad(32));
3533 } else if (info < cs_token_flag) {
3534
3535 int cmd = token_cmd(info);
3536 int chr = token_chr(info);
3537 switch (cmd) {
3538 case left_brace_cmd:
3539 case right_brace_cmd:
3540 case math_shift_cmd:
3541 case alignment_tab_cmd:
3542 case superscript_cmd:
3543 case subscript_cmd:
3544 case spacer_cmd:
3545 case letter_cmd:
3546 case other_char_cmd:
3547 case active_char_cmd:
3548 if (! skip) {
3549 tex_aux_append_uchar_to_buffer(chr);
3550 }
3551 break;
3552 case parameter_cmd:
3553 if (! skip) {
3554
3555 if (! single && ! nospace && lmt_expand_state.cs_name_level == 0) {
3556 tex_aux_append_uchar_to_buffer(chr);
3557 }
3558 tex_aux_append_uchar_to_buffer(chr);
3559 }
3560 break;
3561 case parameter_reference_cmd:
3562 if (! skip) {
3563 tex_aux_append_char_to_buffer(match_visualizer);
3564 if (chr <= 9) {
3565 tex_aux_append_char_to_buffer(chr + '0');
3566 } else if (chr <= max_match_count) {
3567 tex_aux_append_char_to_buffer(chr + '0' + gap_match_count);
3568 } else {
3569 tex_aux_append_char_to_buffer('!');
3570 goto EXIT;
3571 }
3572 } else {
3573 if (chr > max_match_count) {
3574 goto EXIT;
3575 }
3576 }
3577 break;
3578 case match_cmd:
3579 if (! skip) {
3580 tex_aux_append_char_to_buffer(match_visualizer);
3581 }
3582 if (is_valid_match_ref(chr)) {
3583 ++n;
3584 }
3585 if (! skip) {
3586 tex_aux_append_char_to_buffer(chr ? chr : '0');
3587
3588
3589
3590
3591
3592 }
3593 if (n > max_match_count) {
3594 goto EXIT;
3595 }
3596 break;
3597 case end_match_cmd:
3598 if (skippreamble == 2) {
3599 goto EXIT;
3600 } else if (chr == 0) {
3601 if (! skip) {
3602 tex_aux_append_char_to_buffer('-');
3603 tex_aux_append_char_to_buffer('>');
3604 }
3605 skip = 0 ;
3606 }
3607 break;
3608 case end_paragraph_cmd:
3609 if (! inhibit_par && (auto_paragraph_mode(auto_paragraph_text))) {
3610 tex_aux_append_esc_to_buffer("par");
3611 }
3612 break;
3613 case deep_frozen_keep_constant_cmd:
3614 if (! skip) {
3615 halfword h = token_link(chr);
3616 while (h) {
3617 tex_aux_append_uchar_to_buffer(token_chr(token_info(h)));
3618 h = token_link(h);
3619 }
3620 }
3621 break;
3622 default:
3623 tex_aux_append_str_to_buffer(tex_aux_special_cmd_string(cmd, chr, error_string_bad(33)));
3624 break;
3625 }
3626 } else if (! (inhibit_par && info == lmt_token_state.par_token)) {
3627 int q = info - cs_token_flag;
3628 if (q < hash_base) {
3629 if (q == null_cs) {
3630 tex_aux_append_esc_to_buffer("csname");
3631 tex_aux_append_esc_to_buffer("endcsname");
3632 } else {
3633 tex_aux_append_str_to_buffer(error_string_impossible(34));
3634 }
3635 } else if (eqtb_out_of_range(q)) {
3636 tex_aux_append_str_to_buffer(error_string_impossible(35));
3637 } else {
3638 strnumber txt = cs_text(q);
3639 if (txt < 0 || txt >= lmt_string_pool_state.string_pool_data.ptr) {
3640 tex_aux_append_str_to_buffer(error_string_nonexistent(36));
3641 } else {
3642 int allocated = 0;
3643 char *sh = tex_makecstring(txt, &allocated);
3644 char *s = sh;
3645 if (tex_is_active_cs(txt)) {
3646 s = s + 3;
3647 while (*s) {
3648 tex_aux_append_char_to_buffer(*s);
3649 s++;
3650 }
3651 } else {
3652 if (e >= 0) {
3653 tex_aux_append_uchar_to_buffer(e);
3654 }
3655 while (*s) {
3656 tex_aux_append_char_to_buffer(*s);
3657 s++;
3658 }
3659 if ((! nospace) && ((! tex_single_letter(txt)) || is_cat_letter(txt))) {
3660 tex_aux_append_char_to_buffer(' ');
3661 }
3662 }
3663 if (allocated) {
3664 lmt_memory_free(sh);
3665 }
3666 }
3667 }
3668 }
3669 tail = p;
3670 ++count;
3671 p = token_link(p);
3672 }
3673 }
3674 EXIT:
3675 if (strip && lmt_token_state.bufloc > 1) {
3676 if (lmt_token_state.buffer[lmt_token_state.bufloc-1] == strip) {
3677 lmt_token_state.bufloc -= 1;
3678 }
3679 if (lmt_token_state.bufloc > 1 && lmt_token_state.buffer[0] == strip) {
3680 memcpy(&lmt_token_state.buffer[0], &lmt_token_state.buffer[1], lmt_token_state.bufloc-1);
3681 lmt_token_state.bufloc -= 1;
3682 }
3683 }
3684 lmt_token_state.buffer[lmt_token_state.bufloc] = '\0';
3685 if (siz) {
3686 *siz = lmt_token_state.bufloc;
3687 }
3688 if (wipe) {
3689 tex_flush_token_list_head_tail(pp, tail, count);
3690 }
3691 return lmt_token_state.buffer;
3692 } else {
3693 if (wipe) {
3694 tex_put_available_token(pp);
3695 }
3696 }
3697 }
3698 if (siz) {
3699 *siz = 0;
3700 }
3701 return NULL;
3702}
3703
3704
3713
3714
3715
3716halfword tex_get_tex_dimension_register (int j, int internal) { return internal ? dimension_parameter(j) : dimension_register(j) ; }
3717halfword tex_get_tex_skip_register (int j, int internal) { return internal ? glue_parameter(j) : skip_register(j) ; }
3718halfword tex_get_tex_muskip_register (int j, int internal) { return internal ? muglue_parameter(j) : muskip_register(j); }
3719halfword tex_get_tex_count_register (int j, int internal) { return internal ? count_parameter(j) : count_register(j) ; }
3720halfword tex_get_tex_posit_register (int j, int internal) { return internal ? posit_parameter(j) : posit_register(j) ; }
3721halfword tex_get_tex_attribute_register (int j, int internal) { return internal ? attribute_parameter(j) : attribute_register(j) ; }
3722halfword tex_get_tex_box_register (int j, int internal) { return internal ? box_parameter(j) : box_register(j) ; }
3723
3724void tex_set_tex_dimension_register(int j, halfword v, int flags, int internal)
3725{
3726
3727
3728
3729 if (internal) {
3730 tex_assign_internal_dimension_value(flags, internal_dimension_location(j), v);
3731 } else {
3732 tex_word_define(flags, register_dimension_location(j), v);
3733 }
3734}
3735
3736void tex_set_tex_skip_register(int j, halfword v, int flags, int internal)
3737{
3738
3739
3740
3741 if (internal) {
3742 tex_assign_internal_skip_value(flags, internal_glue_location(j), v);
3743 } else {
3744 tex_word_define(flags, register_glue_location(j), v);
3745 }
3746}
3747
3748void tex_set_tex_muskip_register(int j, halfword v, int flags, int internal)
3749{
3750
3751
3752
3753 tex_word_define(flags, internal ? internal_muglue_location(j) : register_muglue_location(j), v);
3754}
3755
3756void tex_set_tex_count_register(int j, halfword v, int flags, int internal)
3757{
3758
3759
3760
3761 if (internal) {
3762 tex_assign_internal_integer_value(flags, internal_integer_location(j), v);
3763 } else {
3764 tex_word_define(flags, register_integer_location(j), v);
3765 }
3766}
3767void tex_set_tex_posit_register(int j, halfword v, int flags, int internal)
3768{
3769
3770
3771
3772 if (internal) {
3773 tex_assign_internal_posit_value(flags, internal_posit_location(j), v);
3774 } else {
3775 tex_word_define(flags, register_posit_location(j), v);
3776 }
3777}
3778
3779
3780void tex_set_tex_attribute_register(int j, halfword v, int flags, int internal)
3781{
3782
3783
3784
3785 if (j > lmt_node_memory_state.max_used_attribute) {
3786 lmt_node_memory_state.max_used_attribute = j;
3787 }
3788 tex_change_attribute_register(flags, register_attribute_location(j), v);
3789 tex_word_define(flags, internal ? internal_attribute_location(j) : register_attribute_location(j), v);
3790}
3791
3792void tex_set_tex_box_register(int j, halfword v, int flags, int internal)
3793{
3794
3795
3796
3797 if (internal) {
3798 tex_define(flags, internal_box_location(j), internal_box_reference_cmd, v);
3799 } else {
3800 tex_define(flags, register_box_location(j), register_box_reference_cmd, v);
3801 }
3802}
3803
3804void tex_set_tex_toks_register(int j, lstring s, int flags, int internal)
3805{
3806 halfword ref = get_reference_token();
3807 halfword head = tex_str_toks(s, NULL);
3808 set_token_link(ref, head);
3809
3810
3811
3812 if (internal) {
3813 tex_define(flags, internal_toks_location(j), internal_toks_reference_cmd, ref);
3814 } else {
3815 tex_define(flags, register_toks_location(j), register_toks_reference_cmd, ref);
3816 }
3817}
3818
3819void tex_scan_tex_toks_register(int j, int c, lstring s, int flags, int internal)
3820{
3821 halfword ref = get_reference_token();
3822 halfword head = tex_str_scan_toks(c, s);
3823 set_token_link(ref, head);
3824
3825
3826
3827 if (internal) {
3828 tex_define(flags, internal_toks_location(j), internal_toks_reference_cmd, ref);
3829 } else {
3830 tex_define(flags, register_toks_location(j), register_toks_reference_cmd, ref);
3831 }
3832}
3833
3834int tex_get_tex_toks_register(int j, int internal)
3835{
3836 halfword t = internal ? toks_parameter(j) : toks_register(j);
3837 if (t) {
3838 return tex_tokens_to_string(t);
3839 } else {
3840 return get_nullstr();
3841 }
3842}
3843
3844
3845
3846halfword tex_parse_str_to_tok(halfword head, halfword *tail, halfword ct, const char *str, size_t lstr, int option)
3847{
3848 halfword p = null;
3849 if (! head) {
3850 head = get_reference_token();
3851 }
3852 p = (tail && *tail) ? *tail : head;
3853 if (lstr > 0) {
3854 const char *se = str + lstr;
3855 while (str < se) {
3856
3857 int ul;
3858 halfword u = (halfword) aux_str2uni_len((const unsigned char *) str, &ul);
3859 halfword t = null;
3860 halfword cc = tex_get_cat_code(ct, u);
3861 str += ul;
3862
3866 switch (cc) {
3867 case escape_cmd:
3868 {
3869
3870 int lname = 0;
3871 const char *name = str;
3872 while (str < se) {
3873 int s;
3874 halfword u = (halfword) aux_str2uni_len((const unsigned char *) str, &s);
3875 int c = tex_get_cat_code(ct, u);
3876 if (c == letter_cmd) {
3877 str += s;
3878 lname += s;
3879 } else if (c == spacer_cmd) {
3880
3881 if (lname == 0) {
3882
3883 lname += s;
3884 }
3885 str += s;
3886 break ;
3887 } else {
3888 if (lname == 0) {
3889 lname += s;
3890 str += s;
3891 }
3892 break ;
3893 }
3894 }
3895 if (lname > 0) {
3896
3897 halfword cs = tex_string_locate(name, lname, option == 1 ? 1 : 0);
3898 if (cs == undefined_control_sequence) {
3899 if (option == 2) {
3900
3901
3902 } else {
3903
3904 t = u + (cc * (1<<21));
3905 str = name;
3906 }
3907 } else {
3908
3909 t = cs_token_flag + cs;
3910 }
3911 } else {
3912
3916 t = u + (cc * (1 << 21));
3917 str = name;
3918 }
3919 break;
3920 }
3921 case comment_cmd:
3922 goto DONE;
3923 case ignore_cmd:
3924 break;
3925 case spacer_cmd:
3926
3927 t = token_val(spacer_cmd, ' ');
3928 break;
3929 default:
3930
3933 t = u + (cc * (1<<21));
3934 break;
3935 }
3936 if (t) {
3937 p = tex_store_new_token(p, t);
3938 }
3939 }
3940 }
3941 DONE:
3942 if (tail) {
3943 *tail = p;
3944 }
3945 return head;
3946}
3947
3948
3949
3950int tex_used_token_count(void) {
3951 return lmt_token_memory_state.tokens_data.ptr;
3952}
3953
3954void tex_dump_token_mem(dumpstream f)
3955{
3956
3962 halfword p = lmt_token_memory_state.available;
3963 halfword u = lmt_token_memory_state.tokens_data.top + 1;
3964 while (p) {
3965 --u;
3966 p = token_link(p);
3967 }
3968 lmt_token_memory_state.tokens_data.ptr = u;
3969 dump_int(f, lmt_token_state.null_list);
3970 dump_int(f, lmt_token_memory_state.tokens_data.allocated);
3971 dump_int(f, lmt_token_memory_state.tokens_data.top);
3972 dump_int(f, lmt_token_memory_state.tokens_data.ptr);
3973 dump_int(f, lmt_token_memory_state.available);
3974 dump_things(f, lmt_token_memory_state.tokens[0], lmt_token_memory_state.tokens_data.top + 1);
3975}
3976
3977void tex_undump_token_mem(dumpstream f)
3978{
3979 undump_int(f, lmt_token_state.null_list);
3980 undump_int(f, lmt_token_memory_state.tokens_data.allocated);
3981 undump_int(f, lmt_token_memory_state.tokens_data.top);
3982 undump_int(f, lmt_token_memory_state.tokens_data.ptr);
3983 undump_int(f, lmt_token_memory_state.available);
3984 tex_initialize_token_mem();
3985 undump_things(f, lmt_token_memory_state.tokens[0], lmt_token_memory_state.tokens_data.top + 1);
3986}
3987 |