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