teptris 0.3.23.0 → 0.3.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/teptris_ext/engine/README.md +1 -1
- data/ext/teptris_ext/engine/src/include/teptris/version.h +2 -2
- data/ext/teptris_ext/engine/src/teptris/schema/regex.c +143 -7
- data/ext/teptris_ext/engine/src/teptris/schema/unicode_props.c +5508 -0
- data/ext/teptris_ext/engine/src/teptris/schema/unicode_props.h +20 -0
- data/ext/teptris_ext/engine/src/teptris/schema/validate.c +112 -4
- data/lib/teptris/version.rb +1 -1
- metadata +4 -2
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/* Unicode property ranges for the schema regex \p{...}. Generated. */
|
|
2
|
+
#ifndef TEPTRIS_SCHEMA_UNICODE_PROPS_H
|
|
3
|
+
#define TEPTRIS_SCHEMA_UNICODE_PROPS_H
|
|
4
|
+
|
|
5
|
+
#include <stdint.h>
|
|
6
|
+
|
|
7
|
+
typedef struct {
|
|
8
|
+
uint32_t lo, hi;
|
|
9
|
+
} teptris_uc_range;
|
|
10
|
+
|
|
11
|
+
typedef struct {
|
|
12
|
+
const char *name;
|
|
13
|
+
const teptris_uc_range *ranges;
|
|
14
|
+
int n;
|
|
15
|
+
} teptris_uc_prop;
|
|
16
|
+
|
|
17
|
+
extern const teptris_uc_prop teptris_unicode_props[];
|
|
18
|
+
extern const int teptris_n_unicode_props;
|
|
19
|
+
|
|
20
|
+
#endif
|
|
@@ -41,6 +41,13 @@ typedef struct {
|
|
|
41
41
|
size_t n_keys, cap_keys;
|
|
42
42
|
size_t *idx;
|
|
43
43
|
size_t n_idx, cap_idx;
|
|
44
|
+
/* stamp-validated open-addressing indexes: a slot holds the
|
|
45
|
+
* entry's position when inserted, so a trial's truncate
|
|
46
|
+
* (n_keys rewind) self-invalidates without a rebuild */
|
|
47
|
+
struct { const char *key; size_t stamp; } *khash;
|
|
48
|
+
size_t khash_cap; /* power of two, 0 = absent */
|
|
49
|
+
struct { size_t val; size_t stamp; } *ihash;
|
|
50
|
+
size_t ihash_cap;
|
|
44
51
|
} *frames;
|
|
45
52
|
int n_frames, cap_frames;
|
|
46
53
|
/* dynamic-scope stack for $dynamicRef / $recursiveRef: one frame
|
|
@@ -206,6 +213,9 @@ static bool frame_grow(vctx *vc) {
|
|
|
206
213
|
return true;
|
|
207
214
|
}
|
|
208
215
|
|
|
216
|
+
static void frame_khash_insert(struct eval_frame *f, const char *key);
|
|
217
|
+
static void frame_ihash_insert(struct eval_frame *f, size_t idx);
|
|
218
|
+
|
|
209
219
|
static bool frame_push(vctx *vc, const sch_svalue *v) {
|
|
210
220
|
if (!frame_grow(vc)) return false;
|
|
211
221
|
struct eval_frame *f = &vc->frames[vc->n_frames++];
|
|
@@ -233,6 +243,9 @@ static void frame_merge_up(vctx *vc) {
|
|
|
233
243
|
}
|
|
234
244
|
memcpy(p->keys + p->n_keys, f->keys, f->n_keys * sizeof(*f->keys));
|
|
235
245
|
p->n_keys += f->n_keys;
|
|
246
|
+
for (size_t i = p->n_keys - f->n_keys; i < p->n_keys; i++) {
|
|
247
|
+
frame_khash_insert(p, p->keys[i]);
|
|
248
|
+
}
|
|
236
249
|
}
|
|
237
250
|
if (f->n_idx > 0) {
|
|
238
251
|
if (p->n_idx + f->n_idx > p->cap_idx) {
|
|
@@ -245,6 +258,9 @@ static void frame_merge_up(vctx *vc) {
|
|
|
245
258
|
}
|
|
246
259
|
memcpy(p->idx + p->n_idx, f->idx, f->n_idx * sizeof(*f->idx));
|
|
247
260
|
p->n_idx += f->n_idx;
|
|
261
|
+
for (size_t i = p->n_idx - f->n_idx; i < p->n_idx; i++) {
|
|
262
|
+
frame_ihash_insert(p, p->idx[i]);
|
|
263
|
+
}
|
|
248
264
|
}
|
|
249
265
|
}
|
|
250
266
|
|
|
@@ -256,23 +272,111 @@ static void frame_pop(vctx *vc) {
|
|
|
256
272
|
struct eval_frame *f = &vc->frames[vc->n_frames - 1];
|
|
257
273
|
free(f->keys);
|
|
258
274
|
free(f->idx);
|
|
275
|
+
free(f->khash);
|
|
276
|
+
free(f->ihash);
|
|
259
277
|
vc->n_frames--;
|
|
260
278
|
}
|
|
261
279
|
|
|
262
|
-
static
|
|
280
|
+
static uint64_t frame_mix(uint64_t x) {
|
|
281
|
+
x ^= x >> 33;
|
|
282
|
+
x *= 0xff51afd7ed558ccdULL;
|
|
283
|
+
x ^= x >> 33;
|
|
284
|
+
x *= 0xc4ceb9fe1a85ec53ULL;
|
|
285
|
+
x ^= x >> 33;
|
|
286
|
+
return x;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
static uint64_t frame_str_hash(const char *s) {
|
|
290
|
+
uint64_t h = 1469598103934665603ULL;
|
|
291
|
+
for (; *s != '\0'; s++) {
|
|
292
|
+
h ^= (unsigned char)*s;
|
|
293
|
+
h *= 1099511628211ULL;
|
|
294
|
+
}
|
|
295
|
+
return h;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/* rebuild a key index from the frame's valid entries */
|
|
299
|
+
static void frame_khash_build(struct eval_frame *f) {
|
|
300
|
+
size_t cap = 16;
|
|
301
|
+
while (cap * 7 / 10 < f->n_keys + 1) cap *= 2;
|
|
302
|
+
void *nh = realloc(f->khash, cap * sizeof(*f->khash));
|
|
303
|
+
if (nh == NULL) return;
|
|
304
|
+
f->khash = nh;
|
|
305
|
+
f->khash_cap = cap;
|
|
306
|
+
for (size_t i = 0; i < cap; i++) f->khash[i].stamp = (size_t)-1;
|
|
263
307
|
for (size_t i = 0; i < f->n_keys; i++) {
|
|
264
|
-
|
|
308
|
+
size_t slot = frame_mix(frame_str_hash(f->keys[i])) & (cap - 1);
|
|
309
|
+
while (f->khash[slot].stamp != (size_t)-1) {
|
|
310
|
+
slot = (slot + 1) & (cap - 1);
|
|
311
|
+
}
|
|
312
|
+
f->khash[slot].key = f->keys[i];
|
|
313
|
+
f->khash[slot].stamp = i;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
static bool frame_key_seen(const struct eval_frame *f, const char *key) {
|
|
318
|
+
if (f->khash_cap == 0) return false;
|
|
319
|
+
size_t slot = frame_mix(frame_str_hash(key)) & (f->khash_cap - 1);
|
|
320
|
+
while (f->khash[slot].stamp != (size_t)-1) {
|
|
321
|
+
if (f->khash[slot].stamp < f->n_keys &&
|
|
322
|
+
strcmp(f->khash[slot].key, key) == 0) {
|
|
323
|
+
return true;
|
|
324
|
+
}
|
|
325
|
+
slot = (slot + 1) & (f->khash_cap - 1);
|
|
265
326
|
}
|
|
266
327
|
return false;
|
|
267
328
|
}
|
|
268
329
|
|
|
269
|
-
static
|
|
330
|
+
static void frame_khash_insert(struct eval_frame *f, const char *key) {
|
|
331
|
+
if (f->n_keys + 1 > f->khash_cap * 7 / 10) frame_khash_build(f);
|
|
332
|
+
size_t slot = frame_mix(frame_str_hash(key)) & (f->khash_cap - 1);
|
|
333
|
+
while (f->khash[slot].stamp != (size_t)-1) {
|
|
334
|
+
slot = (slot + 1) & (f->khash_cap - 1);
|
|
335
|
+
}
|
|
336
|
+
f->khash[slot].key = key;
|
|
337
|
+
f->khash[slot].stamp = f->n_keys - 1;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
static void frame_ihash_build(struct eval_frame *f) {
|
|
341
|
+
size_t cap = 16;
|
|
342
|
+
while (cap * 7 / 10 < f->n_idx + 1) cap *= 2;
|
|
343
|
+
void *nh = realloc(f->ihash, cap * sizeof(*f->ihash));
|
|
344
|
+
if (nh == NULL) return;
|
|
345
|
+
f->ihash = nh;
|
|
346
|
+
f->ihash_cap = cap;
|
|
347
|
+
for (size_t i = 0; i < cap; i++) f->ihash[i].stamp = (size_t)-1;
|
|
270
348
|
for (size_t i = 0; i < f->n_idx; i++) {
|
|
271
|
-
|
|
349
|
+
size_t slot = frame_mix((uint64_t)f->idx[i]) & (cap - 1);
|
|
350
|
+
while (f->ihash[slot].stamp != (size_t)-1) {
|
|
351
|
+
slot = (slot + 1) & (cap - 1);
|
|
352
|
+
}
|
|
353
|
+
f->ihash[slot].val = f->idx[i];
|
|
354
|
+
f->ihash[slot].stamp = i;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
static bool frame_idx_seen(const struct eval_frame *f, size_t idx) {
|
|
359
|
+
if (f->ihash_cap == 0) return false;
|
|
360
|
+
size_t slot = frame_mix((uint64_t)idx) & (f->ihash_cap - 1);
|
|
361
|
+
while (f->ihash[slot].stamp != (size_t)-1) {
|
|
362
|
+
if (f->ihash[slot].stamp < f->n_idx && f->ihash[slot].val == idx) {
|
|
363
|
+
return true;
|
|
364
|
+
}
|
|
365
|
+
slot = (slot + 1) & (f->ihash_cap - 1);
|
|
272
366
|
}
|
|
273
367
|
return false;
|
|
274
368
|
}
|
|
275
369
|
|
|
370
|
+
static void frame_ihash_insert(struct eval_frame *f, size_t idx) {
|
|
371
|
+
if (f->n_idx + 1 > f->ihash_cap * 7 / 10) frame_ihash_build(f);
|
|
372
|
+
size_t slot = frame_mix((uint64_t)idx) & (f->ihash_cap - 1);
|
|
373
|
+
while (f->ihash[slot].stamp != (size_t)-1) {
|
|
374
|
+
slot = (slot + 1) & (f->ihash_cap - 1);
|
|
375
|
+
}
|
|
376
|
+
f->ihash[slot].val = idx;
|
|
377
|
+
f->ihash[slot].stamp = f->n_idx - 1;
|
|
378
|
+
}
|
|
379
|
+
|
|
276
380
|
static void frame_add_key(vctx *vc, const char *key) {
|
|
277
381
|
if (vc->n_frames == 0) return;
|
|
278
382
|
struct eval_frame *f = &vc->frames[vc->n_frames - 1];
|
|
@@ -284,6 +388,7 @@ static void frame_add_key(vctx *vc, const char *key) {
|
|
|
284
388
|
f->keys = nk;
|
|
285
389
|
}
|
|
286
390
|
f->keys[f->n_keys++] = key;
|
|
391
|
+
frame_khash_insert(f, key);
|
|
287
392
|
}
|
|
288
393
|
|
|
289
394
|
static void frame_add_idx(vctx *vc, size_t idx) {
|
|
@@ -297,6 +402,7 @@ static void frame_add_idx(vctx *vc, size_t idx) {
|
|
|
297
402
|
f->idx = ni;
|
|
298
403
|
}
|
|
299
404
|
f->idx[f->n_idx++] = idx;
|
|
405
|
+
frame_ihash_insert(f, idx);
|
|
300
406
|
}
|
|
301
407
|
|
|
302
408
|
/* drop the annotations a trial contributed to its merge target (the
|
|
@@ -313,6 +419,8 @@ static void frames_free(vctx *vc) {
|
|
|
313
419
|
for (int i = 0; i < vc->n_frames; i++) {
|
|
314
420
|
free(vc->frames[i].keys);
|
|
315
421
|
free(vc->frames[i].idx);
|
|
422
|
+
free(vc->frames[i].khash);
|
|
423
|
+
free(vc->frames[i].ihash);
|
|
316
424
|
}
|
|
317
425
|
free(vc->frames);
|
|
318
426
|
}
|
data/lib/teptris/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: teptris
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.24.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- teptris contributors
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-11-
|
|
11
|
+
date: 2026-11-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: A native C extension over libteptris, a C99 TOML 1.1 parser/emitter.
|
|
14
14
|
API shape mirrors the tomlib gem.
|
|
@@ -64,6 +64,8 @@ files:
|
|
|
64
64
|
- ext/teptris_ext/engine/src/teptris/schema/regex.h
|
|
65
65
|
- ext/teptris_ext/engine/src/teptris/schema/schema.c
|
|
66
66
|
- ext/teptris_ext/engine/src/teptris/schema/schema_internal.h
|
|
67
|
+
- ext/teptris_ext/engine/src/teptris/schema/unicode_props.c
|
|
68
|
+
- ext/teptris_ext/engine/src/teptris/schema/unicode_props.h
|
|
67
69
|
- ext/teptris_ext/engine/src/teptris/schema/validate.c
|
|
68
70
|
- ext/teptris_ext/engine/src/teptris/version.c
|
|
69
71
|
- ext/teptris_ext/extconf.rb
|