1
4
5# include "luametatex.h"
6
7
79
80save_state_info lmt_save_state = {
81 .save_stack = NULL,
82 .save_stack_data = {
83 .minimum = min_save_size,
84 .maximum = max_save_size,
85 .size = siz_save_size,
86 .step = stp_save_size,
87 .allocated = 0,
88 .itemsize = sizeof(save_record),
89 .top = 0,
90 .ptr = 0,
91 .initial = memory_data_unset,
92 .offset = 0,
93 },
94 .current_level = 0,
95 .current_group = 0,
96 .current_boundary = 0,
97
98};
99
100
107
108static void tex_aux_show_eqtb(halfword n);
109
110static void tex_aux_diagnostic_trace(halfword p, const char *s)
111{
112 tex_begin_diagnostic();
113 tex_print_format("{%s ", s);
114 tex_aux_show_eqtb(p);
115 tex_print_char('}');
116 tex_end_diagnostic();
117}
118
119
177
178
179
180
181void tex_initialize_levels(void)
182{
183 cur_level = level_one;
184 cur_group = bottom_level_group;
185 cur_boundary = 0;
186 lmt_scanner_state.last_cs_name = null_cs;
187}
188
189void tex_initialize_undefined_cs(void)
190{
191 set_eq_type(undefined_control_sequence, undefined_cs_cmd);
192 set_eq_flag(undefined_control_sequence, 0);
193 set_eq_value(undefined_control_sequence, null);
194 set_eq_level(undefined_control_sequence, level_zero);
195}
196
197void tex_dump_equivalents_mem(dumpstream f)
198{
199
206 int index = null_cs;
207 do {
208 int different = 1;
209 int equivalent = 0;
210 int j = index;
211 while (j < eqtb_size - 1) {
212 if (equal_eqtb_entries(j, j + 1)) {
213 ++equivalent;
214 goto FOUND1;
215 } else {
216 ++different;
217 }
218 ++j;
219 }
220
221 goto DONE1;
222 FOUND1:
223 j++;
224 while (j < eqtb_size - 1) {
225 if (equal_eqtb_entries(j, j + 1)) {
226 ++equivalent;
227 } else {
228 goto DONE1;
229 }
230 ++j;
231 }
232 DONE1:
233
234 dump_int(f, different);
235 dump_things(f, lmt_hash_state.eqtb[index], different);
236 dump_int(f, equivalent);
237 index = index + different + equivalent;
238 } while (index <= eqtb_size);
239
240 dump_int(f, lmt_hash_state.hash_data.ptr);
241 if (lmt_hash_state.hash_data.ptr > 0) {
242 dump_things(f, lmt_hash_state.eqtb[eqtb_size + 1], lmt_hash_state.hash_data.ptr);
243 }
244
245 dump_int(f, lmt_token_state.par_loc);
246
247 dump_int(f, lmt_token_state.empty);
248}
249
250void tex_undump_equivalents_mem(dumpstream f)
251{
252
253 int index = null_cs;
254 do {
255 int different;
256 int equivalent;
257 undump_int(f, different);
258 if (different > 0) {
259 undump_things(f, lmt_hash_state.eqtb[index], different);
260 }
261 undump_int(f, equivalent);
262
263 if (equivalent > 0) {
264 int last = index + different - 1;
265 for (int i = 1; i <= equivalent; i++) {
266 lmt_hash_state.eqtb[last + i] = lmt_hash_state.eqtb[last];
267 }
268 }
269 index = index + different + equivalent;
270 } while (index <= eqtb_size);
271
272 undump_int(f, lmt_hash_state.hash_data.ptr);
273 if (lmt_hash_state.hash_data.ptr > 0) {
274
275 undump_things(f, lmt_hash_state.eqtb[eqtb_size + 1], lmt_hash_state.hash_data.ptr);
276 }
277 undump_int(f, lmt_token_state.par_loc);
278 if (lmt_token_state.par_loc >= hash_base && lmt_token_state.par_loc <= lmt_hash_state.hash_data.top) {
279 lmt_token_state.par_token = cs_token_flag + lmt_token_state.par_loc;
280 } else {
281 tex_fatal_undump_error("parloc");
282 }
283
284
285
286
287
288
289 undump_int(f, lmt_token_state.empty);
290 return;
291}
292
293
308
309# define reserved_save_stack_slots 32
310
311void tex_initialize_save_stack(void)
312{
313 int size = lmt_save_state.save_stack_data.minimum;
314 lmt_save_state.save_stack = aux_allocate_clear_array(sizeof(save_record), lmt_save_state.save_stack_data.step, reserved_save_stack_slots);
315 if (lmt_save_state.save_stack) {
316 lmt_save_state.save_stack_data.allocated = lmt_save_state.save_stack_data.step;
317 } else {
318 tex_overflow_error("save", size);
319 }
320}
321
322static int tex_room_on_save_stack(void)
323{
324 int top = lmt_save_state.save_stack_data.ptr;
325 if (top > lmt_save_state.save_stack_data.top) {
326 lmt_save_state.save_stack_data.top = top;
327 if (top > lmt_save_state.save_stack_data.allocated) {
328 save_record *tmp = NULL;
329 top = lmt_save_state.save_stack_data.allocated + lmt_save_state.save_stack_data.step;
330 if (top > lmt_save_state.save_stack_data.size) {
331 top = lmt_save_state.save_stack_data.size;
332 }
333 if (top > lmt_save_state.save_stack_data.allocated) {
334 top = lmt_save_state.save_stack_data.allocated + lmt_save_state.save_stack_data.step;
335 tmp = aux_reallocate_array(lmt_save_state.save_stack, sizeof(save_record), top, reserved_save_stack_slots);
336 lmt_save_state.save_stack = tmp;
337 }
338 lmt_run_memory_callback("save", tmp ? 1 : 0);
339 if (! tmp) {
340 tex_overflow_error("save", top);
341 return 0;
342 }
343
344 lmt_save_state.save_stack_data.allocated = top;
345 }
346 }
347 return 1;
348}
349
350void tex_save_halfword_on_stack(quarterword t, halfword v)
351{
352 if (tex_room_on_save_stack()) {
353 saved_type(0) = t;
354 saved_record(0) = 0;
355 saved_value_1(0) = v;
356 ++lmt_save_state.save_stack_data.ptr;
357 }
358}
359
360
375
376static void tex_aux_group_trace(int g)
377{
378 tex_begin_diagnostic();
379 tex_print_format(g ? "{leaving %G}" : "{entering %G}", g);
380 tex_end_diagnostic();
381}
382
383
415
416static void tex_aux_group_warning(void)
417{
418
419 bool warning = false;
420
421 int index = lmt_input_state.in_stack_data.ptr;
422 lmt_input_state.base_ptr = lmt_input_state.input_stack_data.ptr;
423
424 lmt_input_state.input_stack[lmt_input_state.base_ptr] = lmt_input_state.cur_input;
425 while ((lmt_input_state.in_stack[index].group == cur_boundary) && (index > 0)) {
426
432 if (tracing_nesting_par > 0) {
433 while ((lmt_input_state.input_stack[lmt_input_state.base_ptr].state == token_list_state) || (lmt_input_state.input_stack[lmt_input_state.base_ptr].index > index)) {
434 --lmt_input_state.base_ptr;
435 }
436 if (lmt_input_state.input_stack[lmt_input_state.base_ptr].name > 17) {
437
438 warning = true;
439 }
440 }
441 lmt_input_state.in_stack[index].group = save_value(lmt_save_state.save_stack_data.ptr);
442 --index;
443 }
444 if (warning) {
445 tex_begin_diagnostic();
446 tex_print_format("[warning: end of %G of a different file]", 1);
447 tex_end_diagnostic();
448 if (tracing_nesting_par > 1) {
449 tex_show_context();
450 }
451 if (lmt_error_state.history == spotless) {
452 lmt_error_state.history = warning_issued;
453 }
454 }
455}
456
457
464
465typedef enum saved_group_entries {
466 saved_group_group_entry = 0,
467 saved_group_boundary_entry = 0,
468 saved_group_attribute_state_entry = 0,
469 saved_group_input_line_entry = 0,
470 saved_group_n_records = 1,
471} saved_group_entries;
472
473# define saved_group_group saved_group(saved_group_group_entry)
474# define saved_group_boundary saved_value_1(saved_group_boundary_entry)
475# define saved_group_attribute_state saved_value_2(saved_group_attribute_state_entry)
476# define saved_group_input_line saved_value_3(saved_group_input_line_entry)
477
478inline static void saved_group_initialize(void)
479{
480 saved_type(0) = level_boundary_save_type;
481
482}
483
484void tex_new_save_level(quarterword group)
485{
486
487 if (tex_room_on_save_stack()) {
488 add_attribute_reference(current_attribute_state);
489 saved_group_initialize();
490 saved_group_group = cur_group;
491 saved_group_boundary = cur_boundary;
492 saved_group_attribute_state = current_attribute_state;
493 saved_group_input_line = lmt_input_state.input_line;
494 if (cur_level == max_quarterword) {
495
496 tex_overflow_error("grouping levels", max_quarterword - min_quarterword);
497 }
498 cur_boundary = lmt_save_state.save_stack_data.ptr;
499 cur_group = group;
500 if (tracing_groups_par > 0) {
501 tex_aux_group_trace(0);
502 }
503 ++cur_level;
504 lmt_save_state.save_stack_data.ptr += saved_group_n_records;
505 if (end_of_group_par) {
506 update_tex_end_of_group(null);
507 }
508 }
509}
510
511int tex_saved_line_at_level(void)
512{
513 return lmt_save_state.save_stack_data.ptr > 0 ? (saved_group_input_line > 0 ? saved_group_input_line : 0) : 0;
514}
515
516
531
532void tex_show_save_groups(void)
533{
534 int pointer = lmt_nest_state.nest_data.ptr;
535 int saved_pointer = lmt_save_state.save_stack_data.ptr;
536 quarterword saved_level = cur_level;
537 quarterword saved_group = cur_group;
538 halfword saved_tracing = tracing_levels_par;
539 int alignmentstate = 1;
540 const char *package = NULL;
541 lmt_save_state.save_stack_data.ptr = cur_boundary;
542 --cur_level;
543 tracing_levels_par |= tracing_levels_group;
544 while (1) {
545 int mode;
546 tex_print_levels();
547 tex_print_group(1);
548 if (cur_group == bottom_level_group) {
549 goto DONE;
550 }
551 do {
552 mode = lmt_nest_state.nest[pointer].mode;
553 if (pointer > 0) {
554 --pointer;
555 } else {
556 mode = vmode;
557 }
558 } while (mode == hmode);
559 tex_print_str(": ");
560 switch (cur_group) {
561 case simple_group:
562 ++pointer;
563 goto FOUND2;
564 case hbox_group:
565 case adjusted_hbox_group:
566 package = "hbox";
567 break;
568 case vbox_group:
569 package = "vbox";
570 break;
571 case vtop_group:
572 package = "vtop";
573 break;
574 case dbox_group:
575 package = "dbox";
576 break;
577 case align_group:
578 if (alignmentstate == 0) {
579 package = (mode == internal_vmode) ? "halign" : "valign";
580 alignmentstate = 1;
581 goto FOUND1;
582 } else {
583 if (alignmentstate == 1) {
584 tex_print_str("align entry");
585 } else {
586 tex_print_str_esc("cr");
587 }
588 if (pointer >= alignmentstate) {
589 pointer -= alignmentstate;
590 }
591 alignmentstate = 0;
592 goto FOUND2;
593 }
594 case no_align_group:
595 ++pointer;
596 alignmentstate = -1;
597 tex_print_str_esc("noalign");
598 goto FOUND2;
599 case output_group:
600 tex_print_str_esc("output");
601 goto FOUND2;
602
603
604
605
606
607
608
609 case math_group:
610 tex_print_str_esc("mathsubformula");
611 goto FOUND2;
612 case math_component_group:
613 tex_print_str_esc("mathcomponent");
614 goto FOUND2;
615 case math_stack_group:
616 tex_print_str_esc("mathstack");
617 goto FOUND2;
618 case discretionary_group:
619 tex_show_discretionary_group();
620 goto FOUND2;
621 case math_fraction_group:
622 tex_show_math_fraction_group();
623 goto FOUND2;
624 case math_radical_group:
625 tex_show_math_radical_group();
626 goto FOUND2;
627 case math_operator_group:
628 tex_show_math_operator_group();
629 goto FOUND2;
630 case math_choice_group:
631 tex_show_math_choice_group();
632 goto FOUND2;
633 case insert_group:
634 tex_show_insert_group();
635 goto FOUND2;
636 case vadjust_group:
637 tex_show_adjust_group();
638 goto FOUND2;
639 case vcenter_group:
640 package = "vcenter";
641 goto FOUND1;
642 case also_simple_group:
643 case semi_simple_group:
644 ++pointer;
645 tex_print_str_esc("begingroup");
646 goto FOUND2;
647
648
649
650
651 case math_inline_group:
652 tex_print_char('$');
653 case math_display_group:
654 tex_print_char('$');
655 goto FOUND2;
656 case math_number_group:
657 tex_show_math_number_group();
658 goto FOUND2;
659 case math_fence_group:
660
661 tex_print_str_esc((node_subtype(lmt_nest_state.nest[pointer + 1].delimiter) == left_fence_side) ? "left" : "middle");
662 goto FOUND2;
663 default:
664 tex_confusion("show groups");
665 break;
666 }
667
672 switch (tex_get_packaging_context()) {
673 case direct_box_flag:
674 {
675 scaled shift = tex_get_packaging_shift();
676 if (shift != null_flag) {
677
678 singleword cmd = is_v_mode(lmt_nest_state.nest[pointer].mode) ? hmove_cmd : vmove_cmd;
679 tex_print_cmd_chr(cmd, (shift > 0) ? move_forward_code : move_backward_code);
680 tex_print_dimension(abs(shift), pt_unit);
681 }
682 }
683 break;
684 case global_box_flag:
685 tex_print_str_esc("global");
686 case box_flag:
687 {
688 tex_print_str_esc("setbox");
689 tex_print_int(tex_get_packaging_context());
690 tex_print_char('=');
691 }
692 break;
693 case a_leaders_flag:
694 tex_print_cmd_chr(leader_cmd, a_leaders);
695 break;
696 case c_leaders_flag:
697 tex_print_cmd_chr(leader_cmd, c_leaders);
698 break;
699 case x_leaders_flag:
700 tex_print_cmd_chr(leader_cmd, x_leaders);
701 break;
702 case g_leaders_flag:
703 tex_print_cmd_chr(leader_cmd, g_leaders);
704 break;
705 case u_leaders_flag:
706 tex_print_cmd_chr(leader_cmd, u_leaders);
707 break;
708 }
709 FOUND1:
710 tex_show_packaging_group(package);
711 FOUND2:
712 --cur_level;
713 cur_group = saved_group_group;
714 lmt_save_state.save_stack_data.ptr = saved_group_boundary;
715 }
716 DONE:
717 lmt_save_state.save_stack_data.ptr = saved_pointer;
718 cur_level = saved_level;
719 cur_group = saved_group;
720 tracing_levels_par = saved_tracing;
721}
722
723void tex_show_save_stack(void)
724{
725 halfword savedptr = lmt_save_state.save_stack_data.ptr;
726 tex_print_format("%l[savestack size %i]\n", lmt_save_state.save_stack_data.ptr);
727 while (lmt_save_state.save_stack_data.ptr) {
728 --lmt_save_state.save_stack_data.ptr;
729 tex_print_nlp();
730 tex_print_levels();
731 tex_print_format("[%i: ", lmt_save_state.save_stack_data.ptr);
732 if (save_type(lmt_save_state.save_stack_data.ptr) >= saved_record_0 && save_type(lmt_save_state.save_stack_data.ptr) <= saved_record_9) {
733 tex_print_format("save record %i, ", save_type(lmt_save_state.save_stack_data.ptr) - saved_record_0 + 1, save_record(lmt_save_state.save_stack_data.ptr));
734
735 switch (save_record(lmt_save_state.save_stack_data.ptr)) {
736 case unknown_save_type:
737 break;
738 case box_save_type:
739 if (tex_show_packaging_record()) {
740 break;
741 } else {
742 goto INVALID_TYPE;
743 }
744 case local_box_save_type:
745 if (tex_show_localbox_record()) {
746 break;
747 } else {
748 goto INVALID_TYPE;
749 }
750 case alignment_save_type:
751 if (tex_show_alignment_record()) {
752 break;
753 } else {
754 goto INVALID_TYPE;
755 }
756 case adjust_save_type:
757 if (tex_show_adjust_record()) {
758 break;
759 } else {
760 goto INVALID_TYPE;
761 }
762 case math_save_type:
763 if (tex_show_math_record()) {
764 break;
765 } else {
766 goto INVALID_TYPE;
767 }
768 case fraction_save_type:
769 if (tex_show_math_fraction_record()) {
770 break;
771 } else {
772 goto INVALID_TYPE;
773 }
774 case radical_save_type:
775 if (tex_show_math_radical_record()) {
776 break;
777 } else {
778 goto INVALID_TYPE;
779 }
780 case operator_save_type:
781 if (tex_show_math_operator_record()) {
782 break;
783 } else {
784 goto INVALID_TYPE;
785 }
786 case math_group_save_type:
787 if (tex_show_math_group_record()) {
788 break;
789 } else {
790 goto INVALID_TYPE;
791 }
792 case choice_save_type:
793 if (tex_show_math_choice_record()) {
794 break;
795 } else {
796 goto INVALID_TYPE;
797 }
798 case number_save_type:
799 if (tex_show_math_number_record()) {
800 break;
801 } else {
802 goto INVALID_TYPE;
803 }
804 case insert_save_type:
805 if (tex_show_insert_record()) {
806 break;
807 } else {
808 goto INVALID_TYPE;
809 }
810 case discretionary_save_type:
811 if (tex_show_discretionary_record()) {
812 break;
813 } else {
814 goto INVALID_TYPE;
815 }
816 default:
817 goto INVALID_RECORD;
818 }
819 } else {
820 switch (save_type(lmt_save_state.save_stack_data.ptr)) {
821 case level_boundary_save_type:
822 tex_print_format("boundary, group '%s', boundary %i, attrlist %i, line %i", lmt_interface.group_code_values[saved_group_group].name, saved_group_boundary, saved_group_attribute_state, tex_saved_line_at_level());
823 break;
824 case restore_old_value_save_type:
825 tex_print_format("restore, level %i, cs ", save_level(lmt_save_state.save_stack_data.ptr));
826 tex_aux_show_eqtb(save_value(lmt_save_state.save_stack_data.ptr));
827 break;
828 case insert_tokens_save_type:
829 tex_print_format("insert, pointer %i", save_value(lmt_save_state.save_stack_data.ptr));
830 break;
831 case restore_lua_save_type:
832 tex_print_format("restore lua, level %i, function %i", save_level(lmt_save_state.save_stack_data.ptr), save_value(lmt_save_state.save_stack_data.ptr));
833 break;
834 case restore_zero_save_type:
835 tex_print_format("restore zero, level %i, cs ", save_level(lmt_save_state.save_stack_data.ptr));
836 tex_aux_show_eqtb(save_value(lmt_save_state.save_stack_data.ptr));
837 break;
838 default:
839 goto INVALID_TYPE;
840 }
841 }
842 goto DONE;
843 INVALID_RECORD:
844 tex_print_format("invalid record %i", save_record(lmt_save_state.save_stack_data.ptr));
845 goto DONE;
846 INVALID_TYPE:
847 tex_print_format("invalid type %i", save_type(lmt_save_state.save_stack_data.ptr));
848 goto DONE;
849 DONE:
850 tex_print_char(']');
851 tex_print_nlp();
852 }
853 tex_print_format("%l[savestack bottom]\n");
854 lmt_save_state.save_stack_data.ptr = savedptr;
855}
856
857
879
880static void tex_aux_handle_overload(const char *s, halfword cs, int overload, int error_type)
881{
882 int callback_id = lmt_callback_defined(handle_overload_callback);
883 if (callback_id > 0) {
884 lmt_run_callback(lmt_lua_state.lua_instance, callback_id, "bdsd->", error_type == normal_error_type, overload, cs_text(cs), eq_flag(cs));
885 } else {
886 tex_handle_error(
887 error_type,
888 "You can't redefine %s %S.",
889 s, cs,
890 NULL
891 );
892 }
893}
894
895static int tex_aux_report_overload(halfword cs, int overload)
896{
897 int error_type = overload & 1 ? warning_error_type : normal_error_type;
898 if (has_eq_flag_bits(cs, immutable_flag_bit)) {
899 tex_aux_handle_overload("immutable", cs, overload, error_type);
900 } else if (has_eq_flag_bits(cs, primitive_flag_bit)) {
901 tex_aux_handle_overload("primitive", cs, overload, error_type);
902 } else if (has_eq_flag_bits(cs, permanent_flag_bit)) {
903 tex_aux_handle_overload("permanent", cs, overload, error_type);
904 } else if (has_eq_flag_bits(cs, frozen_flag_bit)) {
905 tex_aux_handle_overload("frozen", cs, overload, error_type);
906 } else if (has_eq_flag_bits(cs, instance_flag_bit)) {
907 tex_aux_handle_overload("instance", cs, overload, warning_error_type);
908 return 1;
909 }
910 return error_type == warning_error_type;
911}
912
913# define overload_error_type(overload) (overload & 1 ? warning_error_type : normal_error_type)
914
915int tex_define_permitted(halfword cs, halfword prefixes)
916{
917 halfword overload = overload_mode_par;
918 if (! cs || ! overload || has_eq_flag_bits(cs, mutable_flag_bit)) {
919 return 1;
920 } else if (is_overloaded(prefixes)) {
921 if (overload > 2 && has_eq_flag_bits(cs, immutable_flag_bit | permanent_flag_bit | primitive_flag_bit)) {
922 return tex_aux_report_overload(cs, overload);
923 }
924 } else if (overload > 4) {
925 if (has_eq_flag_bits(cs, immutable_flag_bit | permanent_flag_bit | primitive_flag_bit | frozen_flag_bit | instance_flag_bit)) {
926 return tex_aux_report_overload(cs, overload);
927 }
928 } else if (overload > 2) {
929 if (has_eq_flag_bits(cs, immutable_flag_bit | permanent_flag_bit | primitive_flag_bit | frozen_flag_bit)) {
930 return tex_aux_report_overload(cs, overload);
931 }
932 } else if (has_eq_flag_bits(cs, immutable_flag_bit)) {
933 return tex_aux_report_overload(cs, overload);
934 }
935 return 1;
936}
937
938static int tex_aux_mutation_permitted(halfword cs)
939{
940 halfword overload = overload_mode_par;
941 if (cs && overload && has_eq_flag_bits(cs, immutable_flag_bit)) {
942 return tex_aux_report_overload(cs, overload);
943 } else {
944 return 1;
945 }
946}
947
948
955
956static void tex_aux_eq_destroy(memoryword w)
957{
958 halfword p = eq_value_field(w);
959 if (p) {
960 switch (eq_type_field(w)) {
961 case call_cmd:
962 case protected_call_cmd:
963 case semi_protected_call_cmd:
964 case constant_call_cmd:
965 case tolerant_call_cmd:
966 case tolerant_protected_call_cmd:
967 case tolerant_semi_protected_call_cmd:
968 case register_toks_reference_cmd:
969 case internal_toks_reference_cmd:
970 tex_delete_token_reference(p);
971 break;
972 case internal_glue_reference_cmd:
973 case register_glue_reference_cmd:
974 case internal_muglue_reference_cmd:
975 case register_muglue_reference_cmd:
976 case gluespec_cmd:
977 case mugluespec_cmd:
978 case mathspec_cmd:
979 case fontspec_cmd:
980 case specification_reference_cmd:
981 tex_flush_node(p);
982 break;
983 case internal_box_reference_cmd:
984 case register_box_reference_cmd:
985 tex_flush_node_list(p);
986 break;
987 default:
988 break;
989 }
990 }
991}
992
993
1000
1001static void tex_aux_eq_save(halfword p, quarterword l)
1002{
1003 if (tex_room_on_save_stack()) {
1004 if (l == level_zero) {
1005 save_type(lmt_save_state.save_stack_data.ptr) = restore_zero_save_type;
1006 } else {
1007 save_type(lmt_save_state.save_stack_data.ptr) = restore_old_value_save_type;
1008 save_word(lmt_save_state.save_stack_data.ptr) = lmt_hash_state.eqtb[p];
1009 }
1010 save_level(lmt_save_state.save_stack_data.ptr) = l;
1011 save_value(lmt_save_state.save_stack_data.ptr) = p;
1012 ++lmt_save_state.save_stack_data.ptr;
1013 }
1014}
1015
1016
1033
1034inline static int tex_aux_equal_eq(halfword p, singleword cmd, singleword flag, halfword chr)
1035{
1036
1037 if (eq_flag(p) == flag) {
1038
1039 switch (eq_type(p)) {
1040 case internal_glue_reference_cmd:
1041 case register_glue_reference_cmd:
1042 case internal_muglue_reference_cmd:
1043 case register_muglue_reference_cmd:
1044 case gluespec_cmd:
1045 case mugluespec_cmd:
1046
1047 if (tex_same_glue(eq_value(p), chr)) {
1048 if (chr) {
1049 tex_flush_node(chr);
1050 }
1051 return 1;
1052 } else {
1053 return 0;
1054 }
1055 case mathspec_cmd:
1056
1057 if (tex_same_mathspec(eq_value(p), chr)) {
1058 if (chr) {
1059 tex_flush_node(chr);
1060 }
1061 return 1;
1062 } else {
1063 return 0;
1064 }
1065 case fontspec_cmd:
1066
1067 if (tex_same_fontspec(eq_value(p), chr)) {
1068 if (chr) {
1069 tex_flush_node(chr);
1070 }
1071 return 1;
1072 } else {
1073 return 0;
1074 }
1075 case call_cmd:
1076 case protected_call_cmd:
1077 case semi_protected_call_cmd:
1078 case constant_call_cmd:
1079 case tolerant_call_cmd:
1080 case tolerant_protected_call_cmd:
1081 case tolerant_semi_protected_call_cmd:
1082
1083
1084 if (eq_value(p) == chr && eq_level(p) == cur_level) {
1085 tex_delete_token_reference(eq_value(p));
1086 return 1;
1087 } else {
1088 return 0;
1089 }
1090 case specification_reference_cmd:
1091 case unit_reference_cmd:
1092 case internal_box_reference_cmd:
1093 case register_box_reference_cmd:
1094
1095 if (eq_type(p) == cmd && eq_value(p) == chr && ! chr) {
1096
1097 return 1;
1098 } else {
1099
1100 return 0;
1101 }
1102 case internal_toks_reference_cmd:
1103 case register_toks_reference_cmd:
1104
1105 if (p && chr && eq_value(p) == chr) {
1106 tex_delete_token_reference(eq_value(p));
1107 return 1;
1108 } else {
1109 return 0;
1110 }
1111 case internal_toks_cmd:
1112 case register_toks_cmd:
1113
1114 if (eq_value(p) == chr) {
1115
1116 return 1;
1117 } else {
1118 return 0;
1119 }
1120 case integer_cmd:
1121 case index_cmd:
1122 case dimension_cmd:
1123 case posit_cmd:
1124 if (eq_type(p) == cmd && eq_value(p) == chr) {
1125
1126 return 1;
1127 }
1128 default:
1129
1134 if (eq_type(p) == cmd && eq_value(p) == chr) {
1135
1136 return 1;
1137 }
1138 return 0;
1139 }
1140 } else {
1141 return 0;
1142 }
1143}
1144
1145
1146
1147void tex_eq_define(halfword p, singleword cmd, halfword chr)
1148{
1149 int trace = tracing_assigns_par > 0;
1150 if (tex_aux_equal_eq(p, cmd, 0, chr)) {
1151 if (trace) {
1152 tex_aux_diagnostic_trace(p, "reassigning");
1153 }
1154 } else {
1155 if (trace) {
1156 tex_aux_diagnostic_trace(p, "changing");
1157 }
1158 if (eq_level(p) == cur_level) {
1159 tex_aux_eq_destroy(lmt_hash_state.eqtb[p]);
1160 } else if (cur_level > level_one) {
1161 tex_aux_eq_save(p, eq_level(p));
1162 }
1163 set_eq_level(p, cur_level);
1164 set_eq_type(p, cmd);
1165 set_eq_flag(p, 0);
1166 set_eq_value(p, chr);
1167 if (trace) {
1168 tex_aux_diagnostic_trace(p, "into");
1169 }
1170 }
1171}
1172
1173
1180
1181void tex_eq_word_define(halfword p, int w)
1182{
1183 bool trace = tracing_assigns_par > 0;
1184 if (eq_value(p) == w) {
1185 if (trace) {
1186 tex_aux_diagnostic_trace(p, "reassigning");
1187 }
1188 } else {
1189 if (trace) {
1190 tex_aux_diagnostic_trace(p, "changing");
1191 }
1192 if (eq_level(p) != cur_level) {
1193 tex_aux_eq_save(p, eq_level(p));
1194 set_eq_level(p, cur_level);
1195 }
1196 eq_value(p) = w;
1197 if (trace) {
1198 tex_aux_diagnostic_trace(p, "into");
1199 }
1200 }
1201}
1202
1203
1210
1211void tex_geq_define(halfword p, singleword cmd, halfword chr)
1212{
1213 bool trace = tracing_assigns_par > 0;
1214 if (trace) {
1215 tex_aux_diagnostic_trace(p, "globally changing");
1216 }
1217 tex_aux_eq_destroy(lmt_hash_state.eqtb[p]);
1218 set_eq_level(p, level_one);
1219 set_eq_type(p, cmd);
1220 set_eq_flag(p, 0);
1221 set_eq_value(p, chr);
1222 if (trace) {
1223 tex_aux_diagnostic_trace(p, "into");
1224 }
1225}
1226
1227void tex_geq_word_define(halfword p, int w)
1228{
1229 bool trace = tracing_assigns_par > 0;
1230 if (trace) {
1231 tex_aux_diagnostic_trace(p, "globally changing");
1232 }
1233 eq_value(p) = w;
1234 set_eq_level(p, level_one);
1235 if (trace) {
1236 tex_aux_diagnostic_trace(p, "into");
1237 }
1238}
1239
1240
1246
1247inline static void tex_aux_set_eq_data(halfword p, singleword t, halfword e, singleword f, quarterword l)
1248{
1249 singleword flag = eq_flag(p);
1250 set_eq_level(p, l);
1251 set_eq_type(p, t);
1252 set_eq_value(p, e);
1253 if (is_mutable(f) || is_mutable(flag)) {
1254 set_eq_flag(p, (f | flag) & ~(noaligned_flag_bit | permanent_flag_bit | primitive_flag_bit | immutable_flag_bit));
1255 } else {
1256 set_eq_flag(p, f);
1257 }
1258}
1259
1260void tex_define(int g, halfword p, singleword t, halfword e)
1261{
1262 bool trace = tracing_assigns_par > 0;
1263 singleword f = make_eq_flag_bits(g);
1264 if (is_global(g)) {
1265
1266 if (trace) {
1267 tex_aux_diagnostic_trace(p, "globally changing");
1268 }
1269
1270
1271
1272 tex_aux_eq_destroy(lmt_hash_state.eqtb[p]);
1273 tex_aux_set_eq_data(p, t, e, f, level_one);
1274 } else if (! is_constrained(g) && tex_aux_equal_eq(p, t, f, e)) {
1275
1276 if (trace) {
1277 tex_aux_diagnostic_trace(p, "reassigning");
1278 return;
1279 }
1280 } else {
1281 if (trace) {
1282 tex_aux_diagnostic_trace(p, "changing");
1283 }
1284 if (eq_level(p) == cur_level) {
1285 tex_aux_eq_destroy(lmt_hash_state.eqtb[p]);
1286 } else if (is_retained(g)) {
1287
1288 } else if (cur_level > level_one) {
1289 tex_aux_eq_save(p, eq_level(p));
1290 }
1291 tex_aux_set_eq_data(p, t, e, f, cur_level);
1292 }
1293 if (trace) {
1294 tex_aux_diagnostic_trace(p, "into");
1295 }
1296}
1297
1298
1302
1303void tex_define_again(int g, halfword p, singleword t, halfword e)
1304{
1305 if (tracing_assigns_par > 0) {
1306 singleword f = make_eq_flag_bits(g);
1307 if (is_global(g)) {
1308
1309 tex_aux_diagnostic_trace(p, "globally changing");
1310
1311
1312
1313 tex_aux_eq_destroy(lmt_hash_state.eqtb[p]);
1314 tex_aux_set_eq_data(p, t, e, f, level_one);
1315 } else if (! is_constrained(g) && tex_aux_equal_eq(p, t, f, e)) {
1316
1317 tex_aux_diagnostic_trace(p, "reassigning");
1318 } else {
1319 tex_aux_diagnostic_trace(p, is_retained(g) ? "retained changing": "changing");
1320 if (eq_level(p) == cur_level) {
1321 tex_aux_eq_destroy(lmt_hash_state.eqtb[p]);
1322 } else if (is_retained(g)) {
1323
1324 } else if (cur_level > level_one) {
1325 tex_aux_eq_save(p, eq_level(p));
1326 }
1327 tex_aux_set_eq_data(p, t, e, f, cur_level);
1328 }
1329 tex_aux_diagnostic_trace(p, "into");
1330 } else {
1331 set_eq_type(p, t);
1332 set_eq_value(p, e);
1333 }
1334}
1335
1336
1339
1340void tex_define_inherit(int g, halfword p, singleword f, singleword t, halfword e)
1341{
1342 bool trace = tracing_assigns_par > 0;
1343 if (is_global(g)) {
1344
1345 if (trace) {
1346 tex_aux_diagnostic_trace(p, "globally changing");
1347 }
1348
1349
1350
1351 tex_aux_eq_destroy(lmt_hash_state.eqtb[p]);
1352 tex_aux_set_eq_data(p, t, e, f, level_one);
1353 } else if (! is_constrained(g) && tex_aux_equal_eq(p, t, f, e)) {
1354 if (trace) {
1355 tex_aux_diagnostic_trace(p, "reassigning");
1356 return;
1357 }
1358 } else {
1359 if (trace) {
1360 tex_aux_diagnostic_trace(p, is_retained(g) ? "retained changing" : "changing");
1361 }
1362 if (eq_level(p) == cur_level) {
1363 tex_aux_eq_destroy(lmt_hash_state.eqtb[p]);
1364 } else if (is_retained(g)) {
1365
1366 } else if (cur_level > level_one) {
1367 tex_aux_eq_save(p, eq_level(p));
1368 }
1369 tex_aux_set_eq_data(p, t, e, f, cur_level);
1370 }
1371 if (trace) {
1372 tex_aux_diagnostic_trace(p, "into");
1373 }
1374}
1375
1376
1380
1381static void tex_aux_just_define(int g, halfword p, halfword e)
1382{
1383 bool trace = tracing_assigns_par > 0;
1384 if (is_global(g)) {
1385 if (trace) {
1386 tex_aux_diagnostic_trace(p, "globally changing");
1387 }
1388 tex_aux_eq_destroy(lmt_hash_state.eqtb[p]);
1389 } else {
1390 if (trace) {
1391 tex_aux_diagnostic_trace(p, "changing");
1392 }
1393 if (eq_level(p) == cur_level) {
1394 tex_aux_eq_destroy(lmt_hash_state.eqtb[p]);
1395 } else if (cur_level > level_one) {
1396 tex_aux_eq_save(p, eq_level(p));
1397 }
1398 set_eq_level(p, cur_level);
1399 }
1400 set_eq_value(p, e);
1401 if (trace) {
1402 tex_aux_diagnostic_trace(p, "into");
1403 }
1404}
1405
1406
1407
1408void tex_define_swapped(int g, halfword p1, halfword p2, int force)
1409{
1410 halfword t1 = eq_type(p1);
1411 halfword t2 = eq_type(p2);
1412 halfword l1 = eq_level(p1);
1413 halfword l2 = eq_level(p2);
1414 singleword f1 = eq_flag(p1);
1415 singleword f2 = eq_flag(p2);
1416 halfword v1 = eq_value(p1);
1417 halfword v2 = eq_value(p2);
1418 if (t1 == t2 && l1 == l2) {
1419 halfword overload = force ? 0 : overload_mode_par;
1420 if (overload) {
1421 if (f1 != f2) {
1422 goto NOTDONE;
1423 } else if (is_immutable(f1)) {
1424 goto NOTDONE;
1425 }
1426 }
1427 if (v1 == v2) {
1428 return;
1429 } else {
1430 switch (t1) {
1431 case register_posit_cmd:
1432 case register_integer_cmd:
1433 case register_attribute_cmd:
1434 case register_dimension_cmd:
1435 case register_glue_cmd:
1436 case register_muglue_cmd:
1437 case internal_muglue_cmd:
1438 case integer_cmd:
1439 case index_cmd:
1440 case dimension_cmd:
1441 case posit_cmd:
1442 tex_aux_just_define(g, p1, v2);
1443 tex_aux_just_define(g, p2, v1);
1444 return;
1445 case register_toks_cmd:
1446 case internal_toks_cmd:
1447 if (v1) tex_add_token_reference(v1);
1448 if (v2) tex_add_token_reference(v2);
1449 tex_aux_just_define(g, p1, v2);
1450 tex_aux_just_define(g, p2, v1);
1451 if (v1) tex_delete_token_reference(v1);
1452 if (v2) tex_delete_token_reference(v2);
1453 return;
1454 case internal_integer_cmd:
1455 tex_assign_internal_integer_value(g, p1, v2);
1456 tex_assign_internal_integer_value(g, p2, v1);
1457 return;
1458 case internal_attribute_cmd:
1459 tex_assign_internal_attribute_value(g, p1, v2);
1460 tex_assign_internal_attribute_value(g, p2, v1);
1461 return;
1462 case internal_posit_cmd:
1463 tex_assign_internal_posit_value(g, p1, v2);
1464 tex_assign_internal_posit_value(g, p2, v1);
1465 return;
1466 case internal_dimension_cmd:
1467 tex_assign_internal_dimension_value(g, p1, v2);
1468 tex_assign_internal_dimension_value(g, p2, v1);
1469 return;
1470 case internal_glue_cmd:
1471
1472 tex_assign_internal_skip_value(g, p1, v2);
1473 tex_assign_internal_skip_value(g, p2, v1);
1474 return;
1475 default:
1476 if (overload > 2) {
1477 if (has_flag_bits(f1, immutable_flag_bit | permanent_flag_bit | primitive_flag_bit)) {
1478 if (overload > 3) {
1479 goto NOTDONE;
1480 }
1481 }
1482 }
1483 if (is_call_cmd(t1)) {
1484 if (v1) tex_add_token_reference(v1);
1485 if (v2) tex_add_token_reference(v2);
1486 tex_aux_just_define(g, p1, v2);
1487 tex_aux_just_define(g, p2, v1);
1488
1489 } else {
1490 tex_handle_error(
1491 normal_error_type,
1492 "\\swapcsvalues not (yet) implemented for commands (%C, %C)",
1493 t1, v1, t2, v2, NULL
1494 );
1495
1496 }
1497 return;
1498 }
1499 }
1500 }
1501 NOTDONE:
1502 tex_handle_error(
1503 normal_error_type,
1504 "\\swapcsvalues requires equal commands (%C, %C), levels (%i, %i) and flags (%i, %i)",
1505 t1, v1, t2, v2, l1, l2, f1, f2, NULL
1506 );
1507}
1508
1509
1512
1513void tex_forced_define(int g, halfword p, singleword f, singleword t, halfword e)
1514{
1515 bool trace = tracing_assigns_par > 0;
1516 if (is_global(g)) {
1517 if (trace) {
1518 tex_aux_diagnostic_trace(p, "globally changing");
1519 }
1520 tex_aux_eq_destroy(lmt_hash_state.eqtb[p]);
1521 set_eq_level(p, level_one);
1522 } else {
1523 if (trace) {
1524 tex_aux_diagnostic_trace(p, "changing");
1525 }
1526 if (eq_level(p) == cur_level) {
1527 tex_aux_eq_destroy(lmt_hash_state.eqtb[p]);
1528 } else if (cur_level > level_one) {
1529 tex_aux_eq_save(p, eq_level(p));
1530 }
1531 set_eq_level(p, cur_level);
1532 }
1533 set_eq_type(p, t);
1534 set_eq_flag(p, f);
1535 set_eq_value(p, e);
1536 if (trace) {
1537 tex_aux_diagnostic_trace(p, "into");
1538 }
1539}
1540
1541
1544
1545void tex_word_define(int g, halfword p, halfword w)
1546{
1547 if (tex_aux_mutation_permitted(p)) {
1548 bool trace = tracing_assigns_par > 0;
1549 if (is_global(g)) {
1550 if (trace) {
1551 tex_aux_diagnostic_trace(p, "globally changing");
1552 }
1553 eq_value(p) = w;
1554 set_eq_level(p, level_one);
1555 } else if (! is_constrained(g) && eq_value(p) == w) {
1556 if (trace) {
1557 tex_aux_diagnostic_trace(p, "reassigning");
1558 return;
1559 }
1560 } else if (is_retained(g)) {
1561 if (trace) {
1562 tex_aux_diagnostic_trace(p, "retained changing");
1563 set_eq_level(p, cur_level);
1564 }
1565 eq_value(p) = w;
1566 } else {
1567 if (trace) {
1568 tex_aux_diagnostic_trace(p, "changing");
1569 }
1570 if (eq_level(p) != cur_level) {
1571 tex_aux_eq_save(p, eq_level(p));
1572 set_eq_level(p, cur_level);
1573 }
1574 eq_value(p) = w;
1575 }
1576 if (trace) {
1577 tex_aux_diagnostic_trace(p, "into");
1578 }
1579 if (is_immutable(g)) {
1580 eq_flag(p) |= immutable_flag_bit;
1581 } else if (is_mutable(g)) {
1582 eq_flag(p) |= mutable_flag_bit;
1583 }
1584 }
1585}
1586
1587
1625
1626
1631
1632void tex_save_for_after_group(halfword t)
1633{
1634 if (t && cur_level > level_one && tex_room_on_save_stack()) {
1635 save_type(lmt_save_state.save_stack_data.ptr) = insert_tokens_save_type;
1636 save_level(lmt_save_state.save_stack_data.ptr) = level_zero;
1637 save_value(lmt_save_state.save_stack_data.ptr) = t;
1638 ++lmt_save_state.save_stack_data.ptr;
1639 }
1640}
1641
1642
1673
1674void tex_unsave(void)
1675{
1676 if (end_of_group_par) {
1677
1681 tex_begin_inserted_list(tex_get_available_token(token_val(end_local_cmd, 0)));
1682 tex_begin_token_list(end_of_group_par, end_of_group_text);
1683 if (tracing_nesting_par > 2) {
1684 tex_local_control_message("entering token scanner via endgroup");
1685 }
1686 tex_local_control(1);
1687 }
1688 delete_attribute_reference(current_attribute_state);
1689 tex_unsave_math_codes(cur_level);
1690 tex_unsave_cat_codes(cat_code_table_par, cur_level);
1691 tex_unsave_text_codes(cur_level);
1692 tex_unsave_math_data(cur_level);
1693 if (cur_level > level_one) {
1694
1698 bool append = false;
1699 bool trace = tracing_restores_par > 0;
1700 --cur_level;
1701
1702 while (1) {
1703 --lmt_save_state.save_stack_data.ptr;
1704 switch (save_type(lmt_save_state.save_stack_data.ptr)) {
1705 case level_boundary_save_type:
1706 goto DONE;
1707 case restore_old_value_save_type:
1708 {
1709 halfword p = save_value(lmt_save_state.save_stack_data.ptr);
1710
1717 if (p < internal_integer_base || p > eqtb_size) {
1718 if (eq_level(p) == level_one) {
1719 tex_aux_eq_destroy(save_word(lmt_save_state.save_stack_data.ptr));
1720 if (trace) {
1721 tex_aux_diagnostic_trace(p, "retaining");
1722 }
1723 } else {
1724 tex_aux_eq_destroy(lmt_hash_state.eqtb[p]);
1725 lmt_hash_state.eqtb[p] = save_word(lmt_save_state.save_stack_data.ptr);
1726 if (trace) {
1727 tex_aux_diagnostic_trace(p, "restoring");
1728 }
1729 }
1730 } else if (eq_level(p) == level_one) {
1731 if (trace) {
1732 tex_aux_diagnostic_trace(p, "retaining");
1733 }
1734 } else {
1735 lmt_hash_state.eqtb[p] = save_word(lmt_save_state.save_stack_data.ptr);
1736 if (trace) {
1737 tex_aux_diagnostic_trace(p, "restoring");
1738 }
1739 }
1740 break;
1741 }
1742 case insert_tokens_save_type:
1743 {
1744
1745 halfword p = save_value(lmt_save_state.save_stack_data.ptr);
1746 if (append) {
1747
1748 tex_append_input(p);
1749 } else {
1750 tex_insert_input(p);
1751 append = true;
1752 }
1753 break;
1754 }
1755 case restore_lua_save_type:
1756 {
1757
1758 halfword p = save_value(lmt_save_state.save_stack_data.ptr);
1759 if (p > 0) {
1760 strnumber u = tex_save_cur_string();
1761 lmt_token_state.luacstrings = 0;
1762 lmt_function_call(p, 0);
1763 tex_restore_cur_string(u);
1764 if (lmt_token_state.luacstrings > 0) {
1765 tex_lua_string_start();
1766 }
1767 } else {
1768 tex_normal_error("lua restore", "invalid number");
1769 }
1770 append = true;
1771 break;
1772 }
1773 case restore_zero_save_type:
1774 {
1775 halfword p = save_value(lmt_save_state.save_stack_data.ptr);
1776 if (eq_level(p) == level_one) {
1777 if (trace) {
1778 tex_aux_diagnostic_trace(p, "retaining");
1779 }
1780 } else {
1781 if (p < internal_integer_base || p > eqtb_size) {
1782 tex_aux_eq_destroy(lmt_hash_state.eqtb[p]);
1783 }
1784 lmt_hash_state.eqtb[p] = lmt_hash_state.eqtb[undefined_control_sequence];
1785 if (trace) {
1786 tex_aux_diagnostic_trace(p, "restoring");
1787 }
1788 }
1789 break;
1790 }
1791 default:
1792
1793 tex_formatted_error("tex unsave", "bad save type case %d, probably a stack pointer issue", save_type(lmt_save_state.save_stack_data.ptr));
1794 break;
1795 }
1796 }
1797 DONE:
1798 if (tracing_groups_par > 0) {
1799 tex_aux_group_trace(1);
1800 }
1801 if (lmt_input_state.in_stack[lmt_input_state.in_stack_data.ptr].group == cur_boundary) {
1802
1803 tex_aux_group_warning();
1804 }
1805 cur_group = saved_group_group;
1806 cur_boundary = saved_group_boundary;
1807 set_current_attribute_state(saved_group_attribute_state);
1808 } else {
1809
1810 tex_confusion("current level");
1811 }
1812}
1813
1814
1878
1879void tex_show_cmd_chr(halfword cmd, halfword chr)
1880{
1881 tex_begin_diagnostic();
1882 if (cur_list.mode != lmt_nest_state.shown_mode) {
1883 if (tracing_commands_par >= 4) {
1884
1885 tex_print_format("[mode: entering %M]", cur_list.mode);
1886 tex_print_nlp();
1887 tex_print_levels();
1888 tex_print_str("{");
1889 } else {
1890 tex_print_format("{%M: ", cur_list.mode);
1891 }
1892 lmt_nest_state.shown_mode = cur_list.mode;
1893 } else {
1894 tex_print_str("{");
1895 }
1896 tex_print_cmd_chr((singleword) cmd, chr);
1897 if (cmd == if_test_cmd && tracing_ifs_par > 0) {
1898 halfword p;
1899 int n, l;
1900 if (tracing_commands_par >= 4) {
1901 tex_print_str(": ");
1902 } else {
1903 tex_print_char(' ');
1904 }
1905 if (cur_chr >= first_real_if_test_code || cur_chr == or_else_code || cur_chr == or_unless_code) {
1906 n = 1;
1907 l = lmt_input_state.input_line;
1908 } else {
1909 tex_print_cmd_chr(if_test_cmd, lmt_condition_state.cur_if);
1910 tex_print_char(' ');
1911 n = 0;
1912 l = lmt_condition_state.if_line;
1913 }
1914
1918 p = lmt_condition_state.cond_ptr;
1919 while (p) {
1920 ++n;
1921 p = node_next(p);
1922 }
1923 if (l) {
1924 if (tracing_commands_par >= 4) {
1925 tex_print_format("(level %i, line %i, nesting %i)", n, l, lmt_condition_state.if_nesting);
1926 } else {
1927
1928 tex_print_format("(level %i, line %i)", n, l);
1929 }
1930 } else {
1931 tex_print_format("(level %i)", n);
1932 }
1933 }
1934 tex_print_char('}');
1935 tex_end_diagnostic();
1936}
1937
1938
1964
1965void tex_aux_show_eqtb(halfword n)
1966{
1967 if (n < null_cs) {
1968 tex_print_format("bad token %i, case 1", n);
1969 } else if (eqtb_indirect_range(n)) {
1970 tex_print_cs(n);
1971 tex_print_char('=');
1972 tex_print_cmd_chr(eq_type(n), eq_value(n));
1973 if (eq_type(n) >= call_cmd) {
1974 tex_print_char(':');
1975 tex_token_show(eq_value(n));
1976 }
1977 } else {
1978 switch (eq_type(n)) {
1979 case internal_toks_reference_cmd:
1980 tex_print_cmd_chr(internal_toks_cmd, n);
1981 goto TOKS;
1982 case register_toks_reference_cmd:
1983 tex_print_str_esc("toks");
1984 tex_print_int(register_toks_number(n));
1985 TOKS:
1986 tex_print_char('=');
1987 tex_token_show(eq_value(n));
1988 break;
1989 case internal_box_reference_cmd:
1990 tex_print_cmd_chr(eq_type(n), n);
1991 goto BOX;
1992 case register_box_reference_cmd:
1993 tex_print_str_esc("box");
1994 tex_print_int(register_box_number(n));
1995 BOX:
1996 tex_print_char('=');
1997 if (eq_value(n)) {
1998 tex_show_node_list(eq_value(n), 0, 1);
1999 tex_print_levels();
2000 } else {
2001 tex_print_str("void");
2002 }
2003 break;
2004 case internal_glue_reference_cmd:
2005 tex_print_cmd_chr(internal_glue_cmd, n);
2006 goto SKIP;
2007 case register_glue_reference_cmd:
2008 tex_print_str_esc("skip");
2009 tex_print_int(register_glue_number(n));
2010 SKIP:
2011 tex_print_char('=');
2012 if (tracing_nodes_par > 2) {
2013 tex_print_format("<%i>", eq_value(n));
2014 }
2015 tex_print_spec(eq_value(n), pt_unit);
2016 break;
2017 case internal_muglue_reference_cmd:
2018 tex_print_cmd_chr(internal_muglue_cmd, n);
2019 goto MUSKIP;
2020 case register_muglue_reference_cmd:
2021 tex_print_str_esc("muskip");
2022 tex_print_int(register_muglue_number(n));
2023 MUSKIP:
2024 if (tracing_nodes_par > 2) {
2025 tex_print_format("<%i>", eq_value(n));
2026 }
2027 tex_print_char('=');
2028 tex_print_spec(eq_value(n), mu_unit);
2029 break;
2030 case internal_integer_reference_cmd:
2031 tex_print_cmd_chr(internal_integer_cmd, n);
2032 goto COUNT;
2033 case register_integer_reference_cmd:
2034 tex_print_str_esc("count");
2035 tex_print_int(register_integer_number(n));
2036 COUNT:
2037 tex_print_char('=');
2038 tex_print_int(eq_value(n));
2039 break;
2040 case internal_attribute_reference_cmd:
2041 tex_print_cmd_chr(internal_attribute_cmd, n);
2042 goto ATTRIBUTE;
2043 case register_attribute_reference_cmd:
2044 tex_print_str_esc("attribute");
2045 tex_print_int(register_attribute_number(n));
2046 ATTRIBUTE:
2047 tex_print_char('=');
2048 tex_print_int(eq_value(n));
2049 break;
2050 case internal_posit_reference_cmd:
2051 tex_print_cmd_chr(internal_posit_cmd, n);
2052 goto POSIT;
2053 case register_posit_reference_cmd:
2054 tex_print_str_esc("posit");
2055 tex_print_int(register_posit_number(n));
2056 POSIT:
2057 tex_print_char('=');
2058 tex_print_posit(eq_value(n));
2059 break;
2060 case internal_dimension_reference_cmd:
2061 tex_print_cmd_chr(internal_dimension_cmd, n);
2062 goto DIMEN;
2063 case register_dimension_reference_cmd:
2064 tex_print_str_esc("dimen");
2065 tex_print_int(register_dimension_number(n));
2066 DIMEN:
2067 tex_print_char('=');
2068 tex_print_dimension(eq_value(n), pt_unit);
2069 break;
2070 case specification_reference_cmd:
2071 tex_print_cmd_chr(specification_cmd, n);
2072 tex_print_char('=');
2073 if (eq_value(n)) {
2074
2075
2076
2077 tex_print_int(specification_count(eq_value(n)));
2078 } else {
2079 tex_print_char('0');
2080 }
2081 break;
2082 case unit_reference_cmd:
2083 tex_print_cmd_chr(association_cmd, n);
2084 tex_print_char('=');
2085 if (eq_value(n)) {
2086 tex_print_str("todo");
2087 } else {
2088 tex_print_char('0');
2089 }
2090 break;
2091 default:
2092 tex_print_format("bad token %i, case 2", n);
2093 break;
2094 }
2095 }
2096}
2097
2098
2105
2106halfword tex_automatic_disc_penalty(halfword mode)
2107{
2108 return hyphenation_permitted(mode, automatic_penalty_hyphenation_mode) ? automatic_hyphen_penalty_par : ex_hyphen_penalty_par;
2109}
2110
2111halfword tex_explicit_disc_penalty(halfword mode)
2112{
2113 return hyphenation_permitted(mode, explicit_penalty_hyphenation_mode) ? explicit_hyphen_penalty_par : ex_hyphen_penalty_par;
2114}
2115
2116
2125
2126inline static void tex_aux_set_eq(halfword base, quarterword level, singleword cmd, halfword value, halfword count)
2127{
2128 if (count > 0) {
2129 set_eq_level(base, level);
2130 set_eq_type(base, cmd);
2131 set_eq_flag(base, 0);
2132 set_eq_value(base, value);
2133 for (int k = base + 1; k <= base + count; k++){
2134 copy_eqtb_entry(k, base);
2135 }
2136 }
2137}
2138
2139void tex_synchronize_equivalents(void)
2140{
2141 tex_aux_set_eq(null_cs, level_zero, undefined_cs_cmd, null, lmt_hash_state.hash_data.top - 1);
2142}
2143
2144void tex_initialize_equivalents(void)
2145{
2146
2147 tex_aux_set_eq(null_cs, level_zero, undefined_cs_cmd, null, lmt_hash_state.hash_data.top - 1);
2148 tex_aux_set_eq(internal_glue_base, level_one, internal_glue_reference_cmd, zero_glue, number_glue_pars);
2149 tex_aux_set_eq(register_glue_base, level_one, register_glue_reference_cmd, zero_glue, max_glue_register_index);
2150 tex_aux_set_eq(internal_muglue_base, level_one, internal_muglue_reference_cmd, zero_glue, number_muglue_pars);
2151 tex_aux_set_eq(register_muglue_base, level_one, register_muglue_reference_cmd, zero_glue, max_muglue_register_index);
2152 tex_aux_set_eq(internal_toks_base, level_one, internal_toks_reference_cmd, null, number_tok_pars);
2153 tex_aux_set_eq(register_toks_base, level_one, register_toks_reference_cmd, null, max_toks_register_index);
2154 tex_aux_set_eq(internal_box_base, level_one, internal_box_reference_cmd, null, number_box_pars);
2155 tex_aux_set_eq(register_box_base, level_one, register_box_reference_cmd, null, max_box_register_index);
2156 tex_aux_set_eq(internal_integer_base, level_one, internal_integer_reference_cmd, 0, number_integer_pars);
2157 tex_aux_set_eq(register_integer_base, level_one, register_integer_reference_cmd, 0, max_integer_register_index);
2158 tex_aux_set_eq(internal_attribute_base, level_one, internal_attribute_reference_cmd, unused_attribute_value, number_attribute_pars);
2159 tex_aux_set_eq(register_attribute_base, level_one, register_attribute_reference_cmd, unused_attribute_value, max_attribute_register_index);
2160 tex_aux_set_eq(internal_posit_base, level_one, internal_posit_reference_cmd, 0, number_posit_pars);
2161 tex_aux_set_eq(register_posit_base, level_one, register_posit_reference_cmd, 0, max_posit_register_index);
2162 tex_aux_set_eq(internal_dimension_base, level_one, internal_dimension_reference_cmd, 0, number_dimension_pars);
2163 tex_aux_set_eq(register_dimension_base, level_one, register_dimension_reference_cmd, 0, max_dimension_register_index);
2164 tex_aux_set_eq(internal_specification_base, level_one, specification_reference_cmd, null, number_specification_pars);
2165 tex_aux_set_eq(internal_unit_base, level_one, unit_reference_cmd, unset_unit_class, max_unit_register_index);
2166 tex_aux_set_eq(undefined_control_sequence, level_zero, undefined_cs_cmd, null, 0);
2167
2168 cat_code_table_par = 0;
2169}
2170
2171int tex_located_save_value(int id)
2172{
2173 int i = lmt_save_state.save_stack_data.ptr - 1;
2174 while (save_type(i) != level_boundary_save_type) {
2175 i--;
2176 }
2177 while (i < lmt_save_state.save_stack_data.ptr) {
2178 if (save_type(i) == restore_old_value_save_type && save_value(i) == id) {
2179
2184 return save_value(i - 1);
2185 }
2186 i++;
2187 }
2188 return 0;
2189}
2190
2191extern int tex_cs_state(halfword p)
2192{
2193 if (p == null_cs) {
2194 return cs_null_error;
2195 } else if (p < hash_base) {
2196 return cs_below_base_error;
2197 } else if (p == undefined_control_sequence) {
2198 return cs_undefined_error;
2199 } else if (eqtb_out_of_range(p)) {
2200 return cs_out_of_range_error;
2201 } else {
2202 return cs_no_error;
2203 }
2204}
2205 |