Mercurial > hgrepos > Python2 > PyMuPDF
diff mupdf-source/thirdparty/mujs/jsintern.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mupdf-source/thirdparty/mujs/jsintern.c Mon Sep 15 11:43:07 2025 +0200 @@ -0,0 +1,137 @@ +#include "jsi.h" + +/* Dynamically grown string buffer */ + +void js_putc(js_State *J, js_Buffer **sbp, int c) +{ + js_Buffer *sb = *sbp; + if (!sb) { + sb = js_malloc(J, sizeof *sb); + sb->n = 0; + sb->m = sizeof sb->s; + *sbp = sb; + } else if (sb->n == sb->m) { + sb = js_realloc(J, sb, (sb->m *= 2) + soffsetof(js_Buffer, s)); + *sbp = sb; + } + sb->s[sb->n++] = c; +} + +void js_puts(js_State *J, js_Buffer **sb, const char *s) +{ + while (*s) + js_putc(J, sb, *s++); +} + +void js_putm(js_State *J, js_Buffer **sb, const char *s, const char *e) +{ + while (s < e) + js_putc(J, sb, *s++); +} + +/* Use an AA-tree to quickly look up interned strings. */ + +struct js_StringNode +{ + js_StringNode *left, *right; + int level; + char string[1]; +}; + +static js_StringNode jsS_sentinel = { &jsS_sentinel, &jsS_sentinel, 0, ""}; + +static js_StringNode *jsS_newstringnode(js_State *J, const char *string, const char **result) +{ + size_t n = strlen(string); + if (n > JS_STRLIMIT) + js_rangeerror(J, "invalid string length"); + js_StringNode *node = js_malloc(J, soffsetof(js_StringNode, string) + n + 1); + node->left = node->right = &jsS_sentinel; + node->level = 1; + memcpy(node->string, string, n + 1); + return *result = node->string, node; +} + +static js_StringNode *jsS_skew(js_StringNode *node) +{ + if (node->left->level == node->level) { + js_StringNode *temp = node; + node = node->left; + temp->left = node->right; + node->right = temp; + } + return node; +} + +static js_StringNode *jsS_split(js_StringNode *node) +{ + if (node->right->right->level == node->level) { + js_StringNode *temp = node; + node = node->right; + temp->right = node->left; + node->left = temp; + ++node->level; + } + return node; +} + +static js_StringNode *jsS_insert(js_State *J, js_StringNode *node, const char *string, const char **result) +{ + if (node != &jsS_sentinel) { + int c = strcmp(string, node->string); + if (c < 0) + node->left = jsS_insert(J, node->left, string, result); + else if (c > 0) + node->right = jsS_insert(J, node->right, string, result); + else + return *result = node->string, node; + node = jsS_skew(node); + node = jsS_split(node); + return node; + } + return jsS_newstringnode(J, string, result); +} + +static void dumpstringnode(js_StringNode *node, int level) +{ + int i; + if (node->left != &jsS_sentinel) + dumpstringnode(node->left, level + 1); + printf("%d: ", node->level); + for (i = 0; i < level; ++i) + putchar('\t'); + printf("'%s'\n", node->string); + if (node->right != &jsS_sentinel) + dumpstringnode(node->right, level + 1); +} + +void jsS_dumpstrings(js_State *J) +{ + js_StringNode *root = J->strings; + printf("interned strings {\n"); + if (root && root != &jsS_sentinel) + dumpstringnode(root, 1); + printf("}\n"); +} + +static void jsS_freestringnode(js_State *J, js_StringNode *node) +{ + if (node->left != &jsS_sentinel) jsS_freestringnode(J, node->left); + if (node->right != &jsS_sentinel) jsS_freestringnode(J, node->right); + js_free(J, node); +} + +void jsS_freestrings(js_State *J) +{ + if (J->strings && J->strings != &jsS_sentinel) + jsS_freestringnode(J, J->strings); +} + +const char *js_intern(js_State *J, const char *s) +{ + const char *result; + if (!J->strings) + J->strings = &jsS_sentinel; + J->strings = jsS_insert(J, J->strings, s, &result); + return result; +}
