/* tectonic/xetex-stringpool.c: preloaded "string pool" constants Copyright 2017-2018 the Tectonic Project Licensed under the MIT License. */ #include "xetex-core.h" #include "xetex-xetexd.h" #include static const char *string_constants[] = { // this catches code that relies on magic stringpool constants "this marks the start of the stringpool", "", NULL }; int load_pool_strings(int32_t spare_size) { const char *s; int i = 0; size_t total_len = 0; str_number g = 0; while ((s = string_constants[i++]) != NULL) { size_t len = strlen(s); total_len += len; if (total_len >= spare_size) return 0; while (len-- > 0) str_pool[pool_ptr++] = *s++; g = make_string(); /* Returns 0 on error. */ } return g; } int32_t length(str_number s) { if (s >= 65536L) return str_start[s + 1 - 65536L] - str_start[s - 65536L]; if (s >= 32 && s < 127) return 1; if (s <= 127) return 3; if (s < 256) return 4; return 8; } str_number make_string(void) { if (str_ptr == max_strings) overflow("number of strings", max_strings - init_str_ptr); str_ptr++; str_start[str_ptr - TOO_BIG_CHAR] = pool_ptr; return str_ptr - 1; } void append_str(str_number s) { int32_t i; pool_pointer j; i = length(s); if (pool_ptr + i > pool_size) overflow("pool size", pool_size - init_pool_ptr); j = str_start[s - 65536L]; while (i > 0) { str_pool[pool_ptr] = str_pool[j]; pool_ptr++; j++; i--; } } bool str_eq_buf(str_number s, int32_t k) { pool_pointer j; j = str_start[s - 65536L]; while (j < str_start[s + 1 - 65536L]) { if (buffer[k] >= 65536L) { if (str_pool[j] != 55296L + (buffer[k] - 65536L) / 1024) { return false; } else if (str_pool[j + 1] != 56320L + (buffer[k] - 65536L) % 1024) { return false; } else { j++; } } else if (str_pool[j] != buffer[k]) { return false; } j++; k++; } return true; } bool str_eq_str(str_number s, str_number t) { pool_pointer j, k; if (length(s) != length(t)) return false; if (length(s) == 1) { if (s < 65536L) { if (t < 65536L) { if (s != t) return false; } else { if (s != str_pool[str_start[t - 65536L]]) return false; } } else { if (t < 65536L) { if (str_pool[str_start[s - 65536L]] != t) return false; } else { if (str_pool[str_start[s - 65536L]] != str_pool[str_start[t - 65536L]]) return false; } } } else { j = str_start[s - 65536L]; k = str_start[t - 65536L]; while (j < str_start[s + 1 - 65536L]) { if (str_pool[j] != str_pool[k]) return false; j++; k++; } } return true; } str_number search_string(str_number search) { str_number s; int32_t len; len = length(search); if (len == 0) { return EMPTY_STRING; } else { s = search - 1; while (s > 65535L) { if (length(s) == len) { if (str_eq_str(s, search)) { return s; } } s--; } } return 0; } str_number slow_make_string(void) { str_number s; str_number t; t = make_string(); s = search_string(t); if (s > 0) { str_ptr--; pool_ptr = str_start[str_ptr - TOO_BIG_CHAR]; return s; } return t; }