1
4
5# include "luametatex.h"
6
7
29
30string_pool_info lmt_string_pool_state = {
31 .string_pool = NULL,
32 .string_pool_data = {
33 .minimum = min_pool_size,
34 .maximum = max_pool_size,
35 .size = siz_pool_size,
36 .step = stp_pool_size,
37 .allocated = 0,
38 .itemsize = sizeof(lstring),
39 .top = 0,
40 .ptr = 0,
41 .initial = 0,
42 .offset = cs_offset_value,
43 },
44 .string_body_data = {
45 .minimum = min_body_size,
46 .maximum = max_body_size,
47 .size = siz_body_size,
48 .step = stp_body_size,
49 .allocated = 0,
50 .itemsize = sizeof(unsigned char),
51 .top = memory_data_unset,
52 .ptr = memory_data_unset,
53 .initial = 0,
54 .offset = 0,
55 },
56 .reserved = 0,
57 .string_max_length = 0,
58 .string_temp = NULL,
59 .string_temp_allocated = 0,
60 .string_temp_top = 0,
61};
62
63
81
82# define initial_temp_string_slots 256
83# define reserved_temp_string_slots 2
84
85inline static void tex_aux_increment_pool_string(int n)
86{
87 lmt_string_pool_state.string_body_data.allocated += n;
88 if (lmt_string_pool_state.string_body_data.allocated > lmt_string_pool_state.string_body_data.size) {
89 tex_overflow_error("poolbody", lmt_string_pool_state.string_body_data.allocated);
90 }
91}
92
93inline static void tex_aux_decrement_pool_string(int n)
94{
95 lmt_string_pool_state.string_body_data.allocated -= n;
96}
97
98static void tex_aux_flush_cur_string(void)
99{
100 if (lmt_string_pool_state.string_temp) {
101 aux_deallocate_array(lmt_string_pool_state.string_temp);
102 }
103 lmt_string_pool_state.string_temp = NULL;
104 lmt_string_pool_state.string_temp_top = 0;
105 lmt_string_pool_state.string_temp_allocated = 0;
106}
107
108void tex_reset_cur_string(void)
109{
110 unsigned char *tmp = aux_allocate_clear_array(sizeof(unsigned char), initial_temp_string_slots, reserved_temp_string_slots);
111 if (tmp) {
112 lmt_string_pool_state.string_temp = tmp;
113 lmt_string_pool_state.string_temp_top = 0;
114 lmt_string_pool_state.string_temp_allocated = initial_temp_string_slots;
115 } else {
116 tex_overflow_error("pool", initial_temp_string_slots);
117 }
118}
119
120static int tex_aux_room_in_string(int wsize)
121{
122
123 if (! lmt_string_pool_state.string_temp) {
124 tex_reset_cur_string();
125 }
126 if ((lmt_string_pool_state.string_temp_top + wsize) > lmt_string_pool_state.string_temp_allocated) {
127 unsigned char *tmp = NULL;
128 int size = lmt_string_pool_state.string_temp_allocated + lmt_string_pool_state.string_temp_allocated / 5 + STRING_EXTRA_AMOUNT;
129 if (size < wsize) {
130 size = wsize + STRING_EXTRA_AMOUNT;
131 }
132 tmp = aux_reallocate_array(lmt_string_pool_state.string_temp, sizeof(unsigned char), size, reserved_temp_string_slots);
133 if (tmp) {
134 lmt_string_pool_state.string_temp = tmp;
135 memset(tmp + lmt_string_pool_state.string_temp_top, 0, (size_t) size - lmt_string_pool_state.string_temp_top);
136 } else {
137 tex_overflow_error("pool", size);
138 }
139 lmt_string_pool_state.string_temp_allocated = size;
140 }
141 return 1;
142}
143
144# define reserved_string_slots 1
145
146
147
148void tex_initialize_string_mem(void)
149{
150 int size = lmt_string_pool_state.string_pool_data.minimum;
151 if (lmt_main_state.run_state == initializing_state) {
152 size = lmt_string_pool_state.string_pool_data.minimum;
153 lmt_string_pool_state.string_pool_data.ptr = cs_offset_value;
154 } else {
155 size = lmt_string_pool_state.string_pool_data.allocated;
156 lmt_string_pool_state.string_pool_data.initial = lmt_string_pool_state.string_pool_data.ptr;
157 }
158 if (size > 0) {
159 lstring *pool = aux_allocate_clear_array(sizeof(lstring), size, reserved_string_slots);
160 if (pool) {
161 lmt_string_pool_state.string_pool = pool;
162 lmt_string_pool_state.string_pool_data.allocated = size;
163 } else {
164 tex_overflow_error("pool", size);
165 }
166 }
167}
168
169void tex_initialize_string_pool(void)
170{
171 unsigned char *nullstring = lmt_memory_malloc(1);
172 int size = lmt_string_pool_state.string_pool_data.allocated;
173 if (size && nullstring) {
174 lmt_string_pool_state.string_pool[0].s = nullstring;
175 nullstring[0] = '\0';
176 lmt_string_pool_state.string_pool_data.ptr += 1;
177 tex_reset_cur_string();
178 } else {
179 tex_overflow_error("pool", size);
180 }
181}
182
183static int tex_aux_room_in_string_pool(int n)
184{
185 int top = lmt_string_pool_state.string_pool_data.ptr + n;
186 if (top > lmt_string_pool_state.string_pool_data.top) {
187 lmt_string_pool_state.string_pool_data.top = top;
188 top -= cs_offset_value;
189 if (top > lmt_string_pool_state.string_pool_data.allocated) {
190 lstring *tmp = NULL;
191 top = lmt_string_pool_state.string_pool_data.allocated;
192 do {
193 top += lmt_string_pool_state.string_pool_data.step;
194 n -= lmt_string_pool_state.string_pool_data.step;
195 } while (n > 0);
196 if (top > lmt_string_pool_state.string_pool_data.size) {
197 top = lmt_string_pool_state.string_pool_data.size;
198 }
199 if (top > lmt_string_pool_state.string_pool_data.allocated) {
200 lmt_string_pool_state.string_pool_data.allocated = top;
201 tmp = aux_reallocate_array(lmt_string_pool_state.string_pool, sizeof(lstring), top, reserved_string_slots);
202 lmt_string_pool_state.string_pool = tmp;
203 }
204 lmt_run_memory_callback("pool", tmp ? 1 : 0);
205 if (! tmp) {
206 tex_overflow_error("pool", top);
207 return 0;
208 }
209 }
210 }
211 return 1;
212}
213
214
220
221strnumber tex_make_string(void)
222{
223 if (tex_aux_room_in_string(1)) {
224 int ptr = lmt_string_pool_state.string_pool_data.ptr;
225 lmt_string_pool_state.string_temp[lmt_string_pool_state.string_temp_top] = '\0';
226 str_string(ptr) = lmt_string_pool_state.string_temp;
227 str_length(ptr) = lmt_string_pool_state.string_temp_top;
228 tex_aux_increment_pool_string(lmt_string_pool_state.string_temp_top);
229 tex_reset_cur_string();
230 if (tex_aux_room_in_string_pool(1)) {
231 lmt_string_pool_state.string_pool_data.ptr++;
232 }
233 return ptr;
234 } else {
235 return get_nullstr();
236 }
237}
238
239strnumber tex_push_string(const unsigned char *s, int l)
240{
241 if (tex_aux_room_in_string_pool(1)) {
242 unsigned char *t = lmt_memory_malloc(sizeof(char) * ((size_t) l + 1));
243 if (t) {
244 int ptr = lmt_string_pool_state.string_pool_data.ptr;
245 memcpy(t, s, l);
246 t[l] = '\0';
247 str_string(ptr) = t;
248 str_length(ptr) = l;
249 lmt_string_pool_state.string_pool_data.ptr++;
250 tex_aux_increment_pool_string(l);
251 return ptr;
252 }
253 }
254 return get_nullstr();
255}
256
257char *tex_take_string(int *len)
258{
259 char* ptr = NULL;
260 if (tex_aux_room_in_string(1)) {
261 lmt_string_pool_state.string_temp[lmt_string_pool_state.string_temp_top] = '\0';
262 if (len) {
263 *len = lmt_string_pool_state.string_temp_top;
264 }
265 ptr = (char *) lmt_string_pool_state.string_temp;
266 tex_reset_cur_string();
267 }
268 return ptr;
269}
270
271
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309int tex_str_eq_buf(strnumber s, int k, int n)
310{
311 return (s >= cs_offset_value) ? (memcmp(str_string(s), &lmt_fileio_state.io_buffer[k], n) == 0) : (buffer_to_unichar(k) == (unsigned int) s);
312}
313
314
329
330int tex_str_eq_str(strnumber s, strnumber t)
331{
332 if (s >= cs_offset_value) {
333 if (t >= cs_offset_value) {
334
335 return (str_length(s) == str_length(t)) && ! memcmp(str_string(s), str_string(t), str_length(s));
336 } else {
337
338 return (strnumber) aux_str2uni(str_string(s)) == t;
339 }
340 } else if (t >= cs_offset_value) {
341
342 return (strnumber) aux_str2uni(str_string(t)) == s;
343 } else {
344
345 return s == t;
346 }
347}
348
349
350
351int tex_str_eq_cstr(strnumber r, const char *s, size_t l)
352{
353 return (l == str_length(r)) && ! strncmp((const char *) (str_string(r)), s, l);
354}
355
356
364
365int tex_get_strings_started(void)
366{
367 tex_reset_cur_string();
368 return 1;
369}
370
371
380
381strnumber tex_maketexstring(const char *s)
382{
383 if (s && *s) {
384 return tex_maketexlstring(s, strlen(s));
385 } else {
386 return get_nullstr();
387 }
388}
389
390strnumber tex_maketexlstring(const char *s, size_t l)
391{
392 if (s && l > 0) {
393 int ptr = lmt_string_pool_state.string_pool_data.ptr;
394 size_t len = l + 1;
395 unsigned char *tmp = lmt_memory_malloc(len);
396 if (tmp) {
397 str_length(ptr) = l;
398 str_string(ptr) = tmp;
399 tex_aux_increment_pool_string((int) l);
400 memcpy(tmp, s, len);
401 if (tex_aux_room_in_string_pool(1)) {
402 lmt_string_pool_state.string_pool_data.ptr += 1;
403 }
404 return ptr;
405 } else {
406 tex_overflow_error("string pool", (int) len);
407 }
408 }
409 return get_nullstr();
410}
411
412
417
418void tex_append_string(const unsigned char *s, unsigned l)
419{
420 if (s && l > 0 && tex_aux_room_in_string(l)) {
421 memcpy(lmt_string_pool_state.string_temp + lmt_string_pool_state.string_temp_top, s, l);
422 lmt_string_pool_state.string_temp_top += l;
423 }
424}
425
426void tex_append_char(unsigned char c)
427{
428 if (tex_aux_room_in_string(1)) {
429 lmt_string_pool_state.string_temp[lmt_string_pool_state.string_temp_top++] = (unsigned char) c;
430 }
431}
432
433char *tex_makeclstring(int s, size_t *len)
434{
435 if (s < cs_offset_value) {
436 *len = (size_t) utf8_size(s);
437 return (char *) aux_uni2str((unsigned) s);
438 } else {
439 size_t l = (size_t) str_length(s);
440 char *tmp = lmt_memory_malloc(l + 1);
441 if (tmp) {
442 memcpy(tmp, str_string(s), l);
443 tmp[l] = '\0';
444 *len = l;
445 return tmp;
446 } else {
447 tex_overflow_error("string pool", (int) l);
448 *len = 0;
449 return NULL;
450 }
451 }
452}
453
454
464
465
470
471char *tex_makecstring(int s, int *allocated)
472{
473 *allocated = s < cs_offset_value;
474 if (*allocated) {
475 return (char *) aux_uni2str((unsigned) s);
476 } else {
477 return str_length(s) > 0 ? (char *) str_string(s) : "";
478 }
479}
480
481
490
491
492
493void tex_compact_string_pool(void)
494{
495 int n_of_strings = lmt_string_pool_state.string_pool_data.ptr - cs_offset_value;
496 int max_length = 0;
497 for (int j = 1; j < n_of_strings; j++) {
498 if (lmt_string_pool_state.string_pool[j].l > (unsigned int) max_length) {
499 max_length = (int) lmt_string_pool_state.string_pool[j].l;
500 }
501 }
502 lmt_string_pool_state.string_max_length = max_length;
503 tex_print_format("max string length %i, ", max_length);
504}
505
506void tex_dump_string_pool(dumpstream f)
507{
508 int n_of_strings = lmt_string_pool_state.string_pool_data.ptr - cs_offset_value;
509 int total_length = lmt_string_pool_state.string_body_data.allocated;
510 int max_length = lmt_string_pool_state.string_max_length;
511 dump_via_int(f, lmt_string_pool_state.string_pool_data.allocated);
512 dump_via_int(f, lmt_string_pool_state.string_pool_data.top);
513 dump_via_int(f, lmt_string_pool_state.string_pool_data.ptr);
514 dump_via_int(f, n_of_strings);
515 dump_via_int(f, max_length);
516 dump_via_int(f, total_length);
517 if (max_length > 0 && max_length < 126) {
518
519 for (int j = 0; j < n_of_strings; j++) {
520 int l = (int) lmt_string_pool_state.string_pool[j].l;
521 char c;
522 if (! lmt_string_pool_state.string_pool[j].s) {
523 l = -1;
524 }
525 c = (char) l;
526 dump_things(f, c, 1);
527 if (l > 0) {
528 dump_things(f, *lmt_string_pool_state.string_pool[j].s, l);
529 }
530 }
531 } else {
532
533 for (int j = 0; j < n_of_strings; j++) {
534 int l = (int) lmt_string_pool_state.string_pool[j].l;
535 if (! lmt_string_pool_state.string_pool[j].s) {
536 l = -1;
537 }
538 dump_int(f, l);
539 if (l > 0) {
540 dump_things(f, *lmt_string_pool_state.string_pool[j].s, l);
541 }
542 }
543 }
544}
545
546void tex_undump_string_pool(dumpstream f)
547{
548 int n_of_strings;
549 int max_length;
550 int total_length;
551 undump_int(f, lmt_string_pool_state.string_pool_data.allocated);
552 undump_int(f, lmt_string_pool_state.string_pool_data.top);
553 undump_int(f, lmt_string_pool_state.string_pool_data.ptr);
554 undump_int(f, n_of_strings);
555 undump_int(f, max_length);
556 undump_int(f, total_length);
557 lmt_string_pool_state.string_max_length = max_length;
558 tex_initialize_string_mem();
559 {
560 int a = 0;
561 int compact = max_length > 0 && max_length < 126;
562 for (int j = 0; j < n_of_strings; j++) {
563 int x;
564 if (compact) {
565
566 char c;
567 undump_things(f, c, 1);
568 x = c;
569 } else {
570
571 undump_int(f, x);
572 }
573 if (x >= 0) {
574
575 int n = x + 1;
576 unsigned char *s = aux_allocate_clear_array(sizeof(unsigned char), n, reserved_string_slots);
577 if (s) {
578 lmt_string_pool_state.string_pool[j].s = s;
579 undump_things(f, s[0], x);
580 s[x] = '\0';
581 a += n;
582 } else {
583 tex_overflow_error("string pool", n);
584 x = 0;
585 }
586 } else {
587 x = 0;
588 }
589 lmt_string_pool_state.string_pool[j].l = x;
590 }
591 lmt_string_pool_state.string_body_data.allocated = a;
592 lmt_string_pool_state.string_body_data.initial = a;
593 }
594}
595
596
597
598void tex_flush_str(strnumber s)
599{
600 if (s > cs_offset_value) {
601
602 tex_aux_decrement_pool_string((int) str_length(s));
603 str_length(s) = 0;
604 lmt_memory_free(str_string(s));
605 str_string(s) = NULL;
606
607 }
608
609 while (! str_string((lmt_string_pool_state.string_pool_data.ptr - 1))) {
610 lmt_string_pool_state.string_pool_data.ptr--;
611 }
612}
613
614
622
623strnumber tex_save_cur_string(void)
624{
625 return (lmt_string_pool_state.string_temp_top > 0 ? tex_make_string() : 0);
626}
627
628void tex_restore_cur_string(strnumber u)
629{
630 if (u) {
631
632 int ul = (int) str_length(u);
633 tex_aux_flush_cur_string();
634 if (tex_aux_room_in_string(u)) {
635 memcpy(lmt_string_pool_state.string_temp, str_string(u), ul);
636 lmt_string_pool_state.string_temp_allocated = ul;
637 lmt_string_pool_state.string_temp_top = ul;
638 tex_flush_str(u);
639 }
640 }
641}
642 |