Coverage Report

Created: 2026-02-14 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/mupdf/thirdparty/mujs/jsintern.c
Line
Count
Source
1
#include "jsi.h"
2
3
/* Dynamically grown string buffer */
4
5
void js_putc(js_State *J, js_Buffer **sbp, int c)
6
0
{
7
0
  js_Buffer *sb = *sbp;
8
0
  if (!sb) {
9
0
    sb = js_malloc(J, sizeof *sb);
10
0
    sb->n = 0;
11
0
    sb->m = sizeof sb->s;
12
0
    *sbp = sb;
13
0
  } else if (sb->n == sb->m) {
14
0
    sb = js_realloc(J, sb, (sb->m *= 2) + soffsetof(js_Buffer, s));
15
0
    *sbp = sb;
16
0
  }
17
0
  sb->s[sb->n++] = c;
18
0
}
19
20
void js_puts(js_State *J, js_Buffer **sb, const char *s)
21
0
{
22
0
  while (*s)
23
0
    js_putc(J, sb, *s++);
24
0
}
25
26
void js_putm(js_State *J, js_Buffer **sb, const char *s, const char *e)
27
0
{
28
0
  while (s < e)
29
0
    js_putc(J, sb, *s++);
30
0
}
31
32
/* Use an AA-tree to quickly look up interned strings. */
33
34
struct js_StringNode
35
{
36
  js_StringNode *left, *right;
37
  int level;
38
  char string[1];
39
};
40
41
static js_StringNode jsS_sentinel = { &jsS_sentinel, &jsS_sentinel, 0, ""};
42
43
static js_StringNode *jsS_newstringnode(js_State *J, const char *string, const char **result)
44
0
{
45
0
  size_t n = strlen(string);
46
0
  if (n > JS_STRLIMIT)
47
0
    js_rangeerror(J, "invalid string length");
48
0
  js_StringNode *node = js_malloc(J, soffsetof(js_StringNode, string) + n + 1);
49
0
  node->left = node->right = &jsS_sentinel;
50
0
  node->level = 1;
51
0
  memcpy(node->string, string, n + 1);
52
0
  return *result = node->string, node;
53
0
}
54
55
static js_StringNode *jsS_skew(js_StringNode *node)
56
0
{
57
0
  if (node->left->level == node->level) {
58
0
    js_StringNode *temp = node;
59
0
    node = node->left;
60
0
    temp->left = node->right;
61
0
    node->right = temp;
62
0
  }
63
0
  return node;
64
0
}
65
66
static js_StringNode *jsS_split(js_StringNode *node)
67
0
{
68
0
  if (node->right->right->level == node->level) {
69
0
    js_StringNode *temp = node;
70
0
    node = node->right;
71
0
    temp->right = node->left;
72
0
    node->left = temp;
73
0
    ++node->level;
74
0
  }
75
0
  return node;
76
0
}
77
78
static js_StringNode *jsS_insert(js_State *J, js_StringNode *node, const char *string, const char **result)
79
0
{
80
0
  if (node != &jsS_sentinel) {
81
0
    int c = strcmp(string, node->string);
82
0
    if (c < 0)
83
0
      node->left = jsS_insert(J, node->left, string, result);
84
0
    else if (c > 0)
85
0
      node->right = jsS_insert(J, node->right, string, result);
86
0
    else
87
0
      return *result = node->string, node;
88
0
    node = jsS_skew(node);
89
0
    node = jsS_split(node);
90
0
    return node;
91
0
  }
92
0
  return jsS_newstringnode(J, string, result);
93
0
}
94
95
static void dumpstringnode(js_StringNode *node, int level)
96
0
{
97
0
  int i;
98
0
  if (node->left != &jsS_sentinel)
99
0
    dumpstringnode(node->left, level + 1);
100
0
  printf("%d: ", node->level);
101
0
  for (i = 0; i < level; ++i)
102
0
    putchar('\t');
103
0
  printf("'%s'\n", node->string);
104
0
  if (node->right != &jsS_sentinel)
105
0
    dumpstringnode(node->right, level + 1);
106
0
}
107
108
void jsS_dumpstrings(js_State *J)
109
0
{
110
0
  js_StringNode *root = J->strings;
111
0
  printf("interned strings {\n");
112
0
  if (root && root != &jsS_sentinel)
113
0
    dumpstringnode(root, 1);
114
0
  printf("}\n");
115
0
}
116
117
static void jsS_freestringnode(js_State *J, js_StringNode *node)
118
0
{
119
0
  if (node->left != &jsS_sentinel) jsS_freestringnode(J, node->left);
120
0
  if (node->right != &jsS_sentinel) jsS_freestringnode(J, node->right);
121
0
  js_free(J, node);
122
0
}
123
124
void jsS_freestrings(js_State *J)
125
0
{
126
0
  if (J->strings && J->strings != &jsS_sentinel)
127
0
    jsS_freestringnode(J, J->strings);
128
0
}
129
130
const char *js_intern(js_State *J, const char *s)
131
0
{
132
0
  const char *result;
133
0
  if (!J->strings)
134
0
    J->strings = &jsS_sentinel;
135
0
  J->strings = jsS_insert(J, J->strings, s, &result);
136
0
  return result;
137
0
}