1
4
5# include "luametatex.h"
6
7
13
14
15
16# define MATHCODESTACK 8
17# define MATHCODESTEP 8
18# define MATHCODEDEFAULT 0xFFFFFFFF
19# define MATHCODEACTIVE 0xFFFFFFFE
20
21
22
23# define DELCODESTACK 4
24# define DELCODESTEP 4
25# define DELCODEDEFAULT 0xFFFFFFFF
26
27typedef struct mathcode_state_info {
28 sa_tree mathcode_head;
29 sa_tree delcode_head;
30} mathcode_state_info;
31
32static mathcode_state_info lmt_mathcode_state = {
33 .mathcode_head = NULL,
34 .delcode_head = NULL,
35};
36
37
43
44# define print_hex_digit_one(A) do { \
45 if ((A) >= 10) { \
46 tex_print_char('A' + (A) - 10); \
47 } else { \
48 tex_print_char('0' + (A)); \
49 } \
50} while (0)
51
52# define print_hex_digit_two(A) do { \
53 print_hex_digit_one((A) / 16); \
54 print_hex_digit_one((A) % 16); \
55} while (0)
56
57# define print_hex_digit_four(A) do { \
58 print_hex_digit_two((A) / 256); \
59 print_hex_digit_two((A) % 256); \
60} while (0)
61
62# define print_hex_digit_six(A) do { \
63 print_hex_digit_two( (A) / 65536); \
64 print_hex_digit_two(((A) % 65536) / 256); \
65 print_hex_digit_two( (A) % 256); \
66} while (0)
67
68
69
70mathcodeval tex_mathchar_from_integer(int value, int extcode)
71{
72 mathcodeval mval;
73 if (extcode == tex_mathcode) {
74 mval.class_value = math_old_class_part(value);
75 mval.family_value = math_old_family_part(value);
76 mval.character_value = math_old_character_part(value);
77 } else {
78 mval.class_value = math_class_part(value);
79 mval.family_value = math_family_part(value);
80 mval.character_value = math_character_part(value);
81 }
82 return mval;
83}
84
85mathcodeval tex_mathchar_from_spec(int value)
86{
87 mathcodeval mval = tex_no_math_code();
88 if (value) {
89 mval.class_value = math_spec_class(value);
90 mval.family_value = math_spec_family(value);
91 mval.character_value = math_spec_character(value);
92 }
93 return mval;
94}
95
96void tex_show_mathcode_value(mathcodeval mval, int extcode)
97{
98 tex_print_char('"');
99 if (extcode == tex_mathcode) {
100 print_hex_digit_one(math_old_class_mask(mval.class_value));
101 print_hex_digit_one(math_old_family_mask(mval.family_value));
102 print_hex_digit_two(math_old_character_mask(mval.character_value));
103 } else {
104 print_hex_digit_two(mval.class_value);
105 tex_print_char('"');
106 print_hex_digit_two(mval.family_value);
107 tex_print_char('"');
108 print_hex_digit_six(mval.character_value);
109 }
110}
111
112static void tex_aux_show_mathcode(int n)
113{
114 mathcodeval mval = tex_get_math_code(n);
115 tex_print_format("%eUmathcode%i=", n);
116 tex_show_mathcode_value(mval, umath_mathcode);
117}
118
119static void tex_aux_unsave_mathcode(int level)
120{
121 if (lmt_mathcode_state.mathcode_head->stack) {
122 while (lmt_mathcode_state.mathcode_head->sa_stack_ptr > 0 && abs(lmt_mathcode_state.mathcode_head->stack[lmt_mathcode_state.mathcode_head->sa_stack_ptr].level) >= level) {
123 sa_stack_item item = lmt_mathcode_state.mathcode_head->stack[lmt_mathcode_state.mathcode_head->sa_stack_ptr];
124 if (item.level > 0) {
125 sa_rawset_item_4(lmt_mathcode_state.mathcode_head, item.code, item.value_1);
126 if (tracing_restores_par > 1) {
127 tex_begin_diagnostic();
128 tex_print_str("{restoring ");
129 tex_aux_show_mathcode(item.code);
130 tex_print_char('}');
131 tex_end_diagnostic();
132 }
133 }
134 (lmt_mathcode_state.mathcode_head->sa_stack_ptr)--;
135 }
136 }
137}
138
139mathcodeval tex_no_math_code(void)
140{
141 return (mathcodeval) { 0, 0, 0 };
142}
143
144void tex_set_math_code(int n, mathcodeval v, int level)
145{
146 sa_tree_item item;
147 if (v.class_value == active_math_class_value && v.family_value == 0 && v.character_value == 0) {
148 item.uint_value = MATHCODEACTIVE;
149 } else if (v.class_value == 0 && v.family_value == 0) {
150
151 item.uint_value = MATHCODEDEFAULT;
152 } else {
153 item.math_code_value.class_value = v.class_value;
154 item.math_code_value.family_value = v.family_value;
155 item.math_code_value.character_value = v.character_value;
156 }
157 sa_set_item_4(lmt_mathcode_state.mathcode_head, n, item, level);
158 if (tracing_assigns_par > 1) {
159 tex_begin_diagnostic();
160 tex_print_str("{assigning ");
161 tex_aux_show_mathcode(n);
162 tex_print_char('}');
163 tex_end_diagnostic();
164 }
165}
166
167mathcodeval tex_get_math_code(int n)
168{
169 sa_tree_item item;
170 mathcodeval m = tex_no_math_code();
171 sa_get_item_4(lmt_mathcode_state.mathcode_head, n, &item);
172 if (item.uint_value == MATHCODEDEFAULT) {
173 m.character_value = n;
174 } else if (item.uint_value == MATHCODEACTIVE) {
175 m.class_value = active_math_class_value;
176 } else if (item.math_code_value.class_value == active_math_class_value) {
177 m.class_value = active_math_class_value;
178 m.character_value = n;
179 } else {
180 m.class_value = (short) item.math_code_value.class_value;
181 m.family_value = (short) item.math_code_value.family_value;
182 m.character_value = item.math_code_value.character_value;
183 }
184 return m;
185}
186
187int tex_get_math_code_number(int n)
188{
189 mathcodeval d = tex_get_math_code(n);
190 return math_packed_character(d.class_value, d.family_value, d.character_value);
191}
192
193static void tex_aux_initialize_mathcode(void)
194{
195 lmt_mathcode_state.mathcode_head = sa_new_tree(mathcode_sparse_identifier, MATHCODESTACK, MATHCODESTEP, 4, (sa_tree_item) { .uint_value = MATHCODEDEFAULT });
196}
197
198static void tex_aux_dump_mathcode(dumpstream f)
199{
200 sa_dump_tree(f, lmt_mathcode_state.mathcode_head);
201}
202
203static void tex_aux_undump_mathcode(dumpstream f)
204{
205 lmt_mathcode_state.mathcode_head = sa_undump_tree(f);
206}
207
208static void tex_aux_show_delcode(int n)
209{
210 delcodeval dval = tex_get_del_code(n);
211 tex_print_format("%eUdelcode=", n);
212 if (tex_has_del_code(dval)) {
213 tex_print_char('"');
214 print_hex_digit_two(dval.small.family_value);
215 print_hex_digit_six(dval.small.character_value);
216 } else {
217 tex_print_str("-1");
218 }
219}
220
221static void tex_aux_unsave_delcode(int level)
222{
223 if (lmt_mathcode_state.delcode_head->stack) {
224 while (lmt_mathcode_state.delcode_head->sa_stack_ptr > 0 && abs(lmt_mathcode_state.delcode_head->stack[lmt_mathcode_state.delcode_head->sa_stack_ptr].level) >= level) {
225 sa_stack_item item = lmt_mathcode_state.delcode_head->stack[lmt_mathcode_state.delcode_head->sa_stack_ptr];
226 if (item.level > 0) {
227 sa_rawset_item_8(lmt_mathcode_state.delcode_head, item.code, item.value_1, item.value_2);
228 if (tracing_restores_par > 1) {
229 tex_begin_diagnostic();
230 tex_print_str("{restoring ");
231 tex_aux_show_delcode(item.code);
232 tex_print_char('}');
233 tex_end_diagnostic();
234 }
235 }
236 (lmt_mathcode_state.delcode_head->sa_stack_ptr)--;
237 }
238 }
239}
240
241void tex_set_del_code(int n, delcodeval v, int level)
242{
243 sa_tree_item v1, v2;
244 v1.math_code_value.class_value = v.small.class_value;
245 v1.math_code_value.family_value = v.small.family_value;
246 v1.math_code_value.character_value = v.small.character_value;
247 v2.math_code_value.class_value = v.large.class_value;
248 v2.math_code_value.family_value = v.large.family_value;
249 v2.math_code_value.character_value = v.large.character_value;
250
251 sa_set_item_8(lmt_mathcode_state.delcode_head, n, v1, v2, level);
252 if (tracing_assigns_par > 1) {
253 tex_begin_diagnostic();
254 tex_print_str("{assigning ");
255 tex_aux_show_delcode(n);
256 tex_print_char('}');
257 tex_end_diagnostic();
258 }
259}
260
261int tex_has_del_code(delcodeval d)
262{
263 return d.small.family_value >= 0;
264}
265
266delcodeval tex_no_del_code(void)
267{
268 return (delcodeval) { { 0, -1, 0 }, { 0, 0, 0 } };
269}
270
271delcodeval tex_get_del_code(int n)
272{
273 sa_tree_item v1, v2;
274 delcodeval d = { { 0, -1, 0 }, { 0, 0, 0} };
275 sa_get_item_8(lmt_mathcode_state.delcode_head, n, &v1, &v2);
276 if (v1.uint_value != DELCODEDEFAULT) {
277 d.small.class_value = (short) v1.math_code_value.class_value;
278 d.small.family_value = (short) v1.math_code_value.family_value;
279 d.small.character_value = v1.math_code_value.character_value;
280 d.large.class_value = (short) v2.math_code_value.class_value;
281 d.large.family_value = (short) v2.math_code_value.family_value;
282 d.large.character_value = v2.math_code_value.character_value;
283 }
284 return d;
285}
286
287
288
289mathdictval tex_no_dict_code(void)
290{
291 return (mathdictval) { 0, 0, 0 };
292}
293
294
295
296
297int tex_get_del_code_number(int n)
298{
299 delcodeval d = tex_get_del_code(n);
300 if (tex_has_del_code(d)) {
301 return ((d.small.family_value * 256 + d.small.character_value) * 4096 +
302 (d.large.family_value * 256) + d.large.character_value);
303 } else {
304 return -1;
305 }
306}
307
308static void tex_aux_initialize_delcode(void)
309{
310 lmt_mathcode_state.delcode_head = sa_new_tree(delcode_sparse_identifier, DELCODESTACK, DELCODESTEP, 8, (sa_tree_item) { .uint_value = DELCODEDEFAULT });
311}
312
313static void tex_aux_dump_delcode(dumpstream f)
314{
315 sa_dump_tree(f, lmt_mathcode_state.delcode_head);
316}
317
318static void tex_aux_undump_delcode(dumpstream f)
319{
320 lmt_mathcode_state.delcode_head = sa_undump_tree(f);
321}
322
323void tex_unsave_math_codes(int grouplevel)
324{
325 tex_aux_unsave_mathcode(grouplevel);
326 tex_aux_unsave_delcode(grouplevel);
327}
328
329void tex_initialize_math_codes(void)
330{
331 tex_aux_initialize_mathcode();
332 tex_aux_initialize_delcode();
333
334 tex_set_default_math_codes();
335}
336
337void tex_free_math_codes(void)
338{
339 sa_destroy_tree(lmt_mathcode_state.mathcode_head);
340 sa_destroy_tree(lmt_mathcode_state.delcode_head);
341}
342
343void tex_dump_math_codes(dumpstream f)
344{
345 tex_aux_dump_mathcode(f);
346 tex_aux_dump_delcode(f);
347}
348
349void tex_undump_math_codes(dumpstream f)
350{
351 tex_aux_undump_mathcode(f);
352 tex_aux_undump_delcode(f);
353}
354 |