yeptris 0.6.34.3-arm-linux-eabihf → 0.6.35.2-arm-linux-eabihf
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/lib/yeptris/3.4/native.so +0 -0
- data/lib/yeptris/cbor.rb +8 -1
- data/lib/yeptris/document.rb +10 -2
- data/lib/yeptris/ffi.rb +1 -0
- data/lib/yeptris/json.rb +2 -0
- data/lib/yeptris/psych/visitors.rb +2 -2
- data/lib/yeptris.rb +1 -1
- data/libyeptris.so +0 -0
- data/vendor/libyeptris/CMakeLists.txt +1 -1
- data/vendor/libyeptris/src/include/yeptris/dom.h +6 -0
- data/vendor/libyeptris/src/yeptris/build.c +16 -0
- data/vendor/libyeptris/src/yeptris/dom/dom.c +6 -6
- data/vendor/libyeptris/src/yeptris/dom/dom.h +5 -0
- data/vendor/libyeptris/src/yeptris/dom/mutate.c +2 -2
- data/vendor/libyeptris/src/yeptris/emit/style.c +15 -0
- data/vendor/libyeptris/src/yeptris/emit/writer.c +7 -1
- data/vendor/libyeptris/src/yeptris/marshal.c +79 -29
- data/vendor/libyeptris/src/yeptris/parse/engine.c +567 -48
- data/vendor/libyeptris/src/yeptris/parse/scalars.c +22 -3
- data/vendor/libyeptris/src/yeptris/resolve/compat11.c +10 -3
- data/vendor/libyeptris/src/yeptris/scan/scan.c +1 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 39d19e8c082b1f9234137c1bf9c0d7c9ea25ec15fa9513926c5a557c7af0f97f
|
|
4
|
+
data.tar.gz: c3280dce6a09e4bd579bf70019b0ba16c831bd6ade7861807895eb8ea64b70f9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c4481147a45a7afeda38a63c7f2b68552a0592481675c9e74d56f9747378b1dc59c5cc62c55c6a0cfcb440200bbde1b071948644ceb202648d164a1c3e11e28d
|
|
7
|
+
data.tar.gz: d16cbeea08e065ff0594760045c2e0e345caa5b007c8e2b68d88640b0ce0308ee57ffb281357e3c51bbde2881836e9ce5306f99ca5b14ec02fa61394ed0c63e4
|
data/lib/yeptris/3.4/native.so
CHANGED
|
Binary file
|
data/lib/yeptris/cbor.rb
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "yeptris"
|
|
4
|
+
require "yeptris/psych" # the encode path builds through the psych YAMLTree
|
|
5
|
+
|
|
3
6
|
module Yeptris
|
|
4
7
|
# CBOR (RFC 8949) over the same FFI document the rest of the
|
|
5
8
|
# binding rides (TODO.cbor/04). Decode materializes through the
|
|
@@ -103,8 +106,12 @@ module Yeptris
|
|
|
103
106
|
def build_documents(objects)
|
|
104
107
|
# ONE document per object: a visitor's tree is a single
|
|
105
108
|
# document and push sets its root — reuse would overwrite
|
|
109
|
+
# compat_11 types the documents' plain scalars through the
|
|
110
|
+
# Psych-compatible resolver — the same law the tree builder's
|
|
111
|
+
# plain-safety check rides, so a host String stays a CBOR text
|
|
112
|
+
# string ("1e0" resolved as a float through core-12: #293).
|
|
106
113
|
objects.map do |obj|
|
|
107
|
-
visitor = ::Yeptris::Psych::Visitors::YAMLTree.new
|
|
114
|
+
visitor = ::Yeptris::Psych::Visitors::YAMLTree.new(schema: :compat_11)
|
|
108
115
|
visitor.push(obj)
|
|
109
116
|
visitor.document
|
|
110
117
|
end
|
data/lib/yeptris/document.rb
CHANGED
|
@@ -75,8 +75,16 @@ class Yeptris::Document
|
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
# An empty document for from-scratch construction (TODO.impl/11 p3).
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
# schema: :compat_11 types its plain scalars through the Psych-
|
|
79
|
+
# compatible resolver — the dump faces build with it so a host String
|
|
80
|
+
# the tree builder kept plain ("1e0") stays a string (#293).
|
|
81
|
+
def self.create(schema: nil)
|
|
82
|
+
doc =
|
|
83
|
+
if schema == :compat_11
|
|
84
|
+
Yeptris::FFI.yeptris_document_new_schema(Yeptris::FFI::SCHEMA_11_COMPAT)
|
|
85
|
+
else
|
|
86
|
+
Yeptris::FFI.yeptris_document_new
|
|
87
|
+
end
|
|
80
88
|
raise Yeptris::Error, "yeptris_document_new failed" if doc.null?
|
|
81
89
|
|
|
82
90
|
wrap(doc)
|
data/lib/yeptris/ffi.rb
CHANGED
|
@@ -141,6 +141,7 @@ module Yeptris
|
|
|
141
141
|
|
|
142
142
|
# construction (TODO.impl/11 phase 3)
|
|
143
143
|
attach_function :yeptris_document_new, [], :yeptris_document
|
|
144
|
+
attach_function :yeptris_document_new_schema, [:int], :yeptris_document
|
|
144
145
|
attach_function :yeptris_document_set_root,
|
|
145
146
|
%i[yeptris_document yeptris_node], :int
|
|
146
147
|
attach_function :yeptris_node_new_mapping, [:yeptris_document], :yeptris_node
|
data/lib/yeptris/json.rb
CHANGED
data/lib/yeptris.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module Yeptris
|
|
4
4
|
# The gem's version lives in the parent namespace's file — the last
|
|
5
5
|
# internal require (yeptris/version) retired with it.
|
|
6
|
-
VERSION = "0.6.
|
|
6
|
+
VERSION = "0.6.35.2".freeze
|
|
7
7
|
|
|
8
8
|
# Informational notices are OPT-IN (yeptris-ruby#217): consumers
|
|
9
9
|
# embed yeptris inside CLIs that assert clean stderr, and a
|
data/libyeptris.so
CHANGED
|
Binary file
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
#include <yeptris/api.h>
|
|
11
11
|
#include <yeptris/error.h>
|
|
12
|
+
#include <yeptris/resolve.h> /* YeptrisSchema */
|
|
12
13
|
#include <yeptris/types.h>
|
|
13
14
|
|
|
14
15
|
#ifdef __cplusplus
|
|
@@ -99,6 +100,11 @@ YEPTRIS_API size_t yeptris_node_children(YeptrisNode node, YeptrisNode* out, siz
|
|
|
99
100
|
/* An empty document with no input; build nodes and set the root. */
|
|
100
101
|
YEPTRIS_API YeptrisDocument yeptris_document_new(void);
|
|
101
102
|
|
|
103
|
+
/* The same, with the schema resolver plain scalars type through
|
|
104
|
+
* (YEPTRIS_SCHEMA_12_CORE is yeptris_document_new's default). Additive
|
|
105
|
+
* ABI. */
|
|
106
|
+
YEPTRIS_API YeptrisDocument yeptris_document_new_schema(YeptrisSchema schema);
|
|
107
|
+
|
|
102
108
|
/* Records a detached node as document i's root. */
|
|
103
109
|
YEPTRIS_API int yeptris_document_set_root(YeptrisDocument doc, YeptrisNode root);
|
|
104
110
|
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
#include "doc.h"
|
|
12
12
|
#include "dom/dom.h"
|
|
13
13
|
#include "memory/allocator.h"
|
|
14
|
+
#include "resolve/resolver.h"
|
|
14
15
|
|
|
15
16
|
static yeptris_document* doc_of(YeptrisDocument handle) {
|
|
16
17
|
return (yeptris_document*)handle;
|
|
@@ -38,6 +39,21 @@ YEPTRIS_API YeptrisDocument yeptris_document_new(void) {
|
|
|
38
39
|
return (YeptrisDocument)doc;
|
|
39
40
|
}
|
|
40
41
|
|
|
42
|
+
/* An empty document whose plain scalars type through the given
|
|
43
|
+
* schema's resolver (yeptris_document_new rides the core-12 default).
|
|
44
|
+
* The CBOR/dump faces create compat-11 documents so a host String the
|
|
45
|
+
* tree builder kept plain ("1e0" — Psych's dot-required float law)
|
|
46
|
+
* stays a text string instead of resolving as a float (#293's shape). */
|
|
47
|
+
YEPTRIS_API YeptrisDocument yeptris_document_new_schema(YeptrisSchema schema) {
|
|
48
|
+
YeptrisDocument doc = yeptris_document_new();
|
|
49
|
+
if (doc != NULL) {
|
|
50
|
+
yeptris_document* d = (yeptris_document*)doc;
|
|
51
|
+
d->dom->resolver =
|
|
52
|
+
schema == YEPTRIS_SCHEMA_11_COMPAT ? yep_resolver_compat11() : yep_resolver_core12();
|
|
53
|
+
}
|
|
54
|
+
return doc;
|
|
55
|
+
}
|
|
56
|
+
|
|
41
57
|
YEPTRIS_API int yeptris_document_set_root(YeptrisDocument handle, YeptrisNode root) {
|
|
42
58
|
yeptris_document* doc = doc_of(handle);
|
|
43
59
|
yeptris_node* n = node_of(root);
|
|
@@ -630,7 +630,7 @@ void yep_dom_destroy(yep_dom* d) {
|
|
|
630
630
|
#include "scan/json.h"
|
|
631
631
|
#include "scan/scan.h"
|
|
632
632
|
|
|
633
|
-
|
|
633
|
+
const yep_resolver* yep_dom_resolver(const yep_dom* d) {
|
|
634
634
|
return d->resolver != NULL ? d->resolver : yep_resolver_core12();
|
|
635
635
|
}
|
|
636
636
|
|
|
@@ -682,7 +682,7 @@ static int jb_scalar_node(jbuilder* b) {
|
|
|
682
682
|
yep_dnode* n = &b->d->nodes[id];
|
|
683
683
|
size_t start = b->i;
|
|
684
684
|
size_t i = b->i;
|
|
685
|
-
const yep_resolver* r =
|
|
685
|
+
const yep_resolver* r = yep_dom_resolver(b->d);
|
|
686
686
|
if (b->p[i] == 't') {
|
|
687
687
|
if (!yep_json_literal(b->p, b->len, &i, "true")) {
|
|
688
688
|
return -2;
|
|
@@ -846,7 +846,7 @@ int dom_on_flow_build(void* ctx, const char* p, size_t open, size_t len, uint32_
|
|
|
846
846
|
d->map_pending_key[d->depth] = 0;
|
|
847
847
|
d->stack[d->depth++] = root;
|
|
848
848
|
|
|
849
|
-
const yep_resolver* r =
|
|
849
|
+
const yep_resolver* r = yep_dom_resolver(d);
|
|
850
850
|
yep_json_walk w;
|
|
851
851
|
yep_json_tok t;
|
|
852
852
|
yep_json_walk_init(&w, p, len, open, max_depth);
|
|
@@ -1126,7 +1126,7 @@ int dom_on_block_open(void* ctx, const yep_view* key, uint32_t line, uint16_t ke
|
|
|
1126
1126
|
if (d->depth >= YEP_DOM_MAX_DEPTH) {
|
|
1127
1127
|
return 0;
|
|
1128
1128
|
}
|
|
1129
|
-
const yep_resolver* r =
|
|
1129
|
+
const yep_resolver* r = yep_dom_resolver(d);
|
|
1130
1130
|
uint32_t mid = dom_open_node(d, YEP_DOM_MAPPING, NULL, NULL, 0, 0, 0, 0);
|
|
1131
1131
|
if (mid == UINT32_MAX) {
|
|
1132
1132
|
return -1;
|
|
@@ -1151,7 +1151,7 @@ int dom_on_block_open(void* ctx, const yep_view* key, uint32_t line, uint16_t ke
|
|
|
1151
1151
|
* opened before offering — node-for-node the event path's item. */
|
|
1152
1152
|
int dom_on_block_item(void* ctx, const yep_block_value* v) {
|
|
1153
1153
|
yep_dom* d = (yep_dom*)ctx;
|
|
1154
|
-
const yep_resolver* r =
|
|
1154
|
+
const yep_resolver* r = yep_dom_resolver(d);
|
|
1155
1155
|
uint32_t vid = dom_open_node(d, YEP_DOM_SCALAR, NULL, NULL, 0, YEP_STYLE_PLAIN, 1, 0);
|
|
1156
1156
|
if (vid == UINT32_MAX) {
|
|
1157
1157
|
return -1;
|
|
@@ -1178,7 +1178,7 @@ int dom_on_block_pair(void* ctx, const yep_view* key, const yep_block_value* v,
|
|
|
1178
1178
|
return 0;
|
|
1179
1179
|
}
|
|
1180
1180
|
}
|
|
1181
|
-
const yep_resolver* r =
|
|
1181
|
+
const yep_resolver* r = yep_dom_resolver(d);
|
|
1182
1182
|
uint32_t kid = dom_open_node(d, YEP_DOM_SCALAR, NULL, NULL, 0, YEP_STYLE_PLAIN, 1, 0);
|
|
1183
1183
|
if (kid == UINT32_MAX) {
|
|
1184
1184
|
return -1;
|
|
@@ -300,6 +300,11 @@ yep_sview yep_dom_str_put(yep_dom* d, const char* p, uint32_t len);
|
|
|
300
300
|
char* yep_dom_str_tail(yep_dom* d, uint32_t cap);
|
|
301
301
|
yep_sview yep_dom_str_commit(yep_dom* d, uint32_t written);
|
|
302
302
|
void yep_dom_destroy(yep_dom* d);
|
|
303
|
+
|
|
304
|
+
/* The document's implicit-typing resolver (its own, or the core-12
|
|
305
|
+
* default) — the SSOT the mutation and build paths must share. */
|
|
306
|
+
struct yep_resolver;
|
|
307
|
+
const struct yep_resolver* yep_dom_resolver(const yep_dom* d);
|
|
303
308
|
int yep_dom_on_event(void* ctx, const yep_event* ev);
|
|
304
309
|
|
|
305
310
|
/* Node id accessor for the public API layer. */
|
|
@@ -54,8 +54,8 @@ uint32_t yep_mut_scalar(yep_dom* d, const char* value, size_t len, uint8_t style
|
|
|
54
54
|
}
|
|
55
55
|
n->value = yep_dom_str_put(d, v.p ? (const char*)v.p : "", v.len);
|
|
56
56
|
n->style = style;
|
|
57
|
-
n->tag_id =
|
|
58
|
-
|
|
57
|
+
n->tag_id =
|
|
58
|
+
style == YEP_STYLE_PLAIN ? yep_dom_resolver(d)->resolve(NULL, v.p, v.len) : YEPTRIS_TAG_STR;
|
|
59
59
|
return id;
|
|
60
60
|
}
|
|
61
61
|
|
|
@@ -80,6 +80,14 @@ int yep_style_plain_safe(const char* p, uint32_t len) {
|
|
|
80
80
|
while (i + 8 <= len) {
|
|
81
81
|
uint64_t w;
|
|
82
82
|
memcpy(&w, p + i, 8);
|
|
83
|
+
if (w & HIGH) {
|
|
84
|
+
/* multibyte content: the byte loop owns the rest — a raw
|
|
85
|
+
* LS/PS/NEL rides in a scalar value since the quote-aware
|
|
86
|
+
* normalizer (#638) and is a line break on re-parse, so
|
|
87
|
+
* the value must be quoted, not plain (the nightly's
|
|
88
|
+
* round 18, crash-1e79b2e3) */
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
83
91
|
uint64_t space = YST_ZDET(w, ' ');
|
|
84
92
|
uint64_t tab = YST_ZDET(w, '\t');
|
|
85
93
|
uint64_t blank = space | tab;
|
|
@@ -113,6 +121,13 @@ int yep_style_plain_safe(const char* p, uint32_t len) {
|
|
|
113
121
|
if (is_break(c) || c == '\t') {
|
|
114
122
|
return 0;
|
|
115
123
|
}
|
|
124
|
+
if ((unsigned char)c == 0xE2 && i + 2 < len && (unsigned char)p[i + 1] == 0x80 &&
|
|
125
|
+
((unsigned char)p[i + 2] & 0xFE) == 0xA8) {
|
|
126
|
+
return 0; /* a raw LS/PS re-parses as a line break */
|
|
127
|
+
}
|
|
128
|
+
if ((unsigned char)c == 0xC2 && i + 1 < len && (unsigned char)p[i + 1] == 0x85) {
|
|
129
|
+
return 0; /* a raw NEL ditto */
|
|
130
|
+
}
|
|
116
131
|
if (c == ':') {
|
|
117
132
|
if (i + 1 >= len || is_blank(p[i + 1])) {
|
|
118
133
|
return 0;
|
|
@@ -847,7 +847,13 @@ static int key_written_over_limit(yep_writer* w, const yep_dnode* kn) {
|
|
|
847
847
|
* 38200627503") */
|
|
848
848
|
if (q != NULL) {
|
|
849
849
|
for (uint32_t i = 0; i < n; i++) {
|
|
850
|
-
|
|
850
|
+
/* a single-quoted render DOUBLES every apostrophe; without
|
|
851
|
+
* it the estimate missed a 892-char key carrying 137
|
|
852
|
+
* quotes (rendered 1031, re-parse rejected the simple
|
|
853
|
+
* key — the nightly's crash-b8a18e43) */
|
|
854
|
+
est += (q[i] < 0x20 || q[i] >= 0x7F || q[i] == '"' || q[i] == '\\' || q[i] == '\'')
|
|
855
|
+
? 4u
|
|
856
|
+
: 1u;
|
|
851
857
|
}
|
|
852
858
|
}
|
|
853
859
|
if (kn->anchor.len > 0) {
|
|
@@ -668,9 +668,13 @@ static YeptrisStatus map_fail(int rc) {
|
|
|
668
668
|
* contract.
|
|
669
669
|
*
|
|
670
670
|
* Key identity is the record's typed payload: span kinds compare the
|
|
671
|
-
* arena bytes, the rest compare (kind, b, payload).
|
|
672
|
-
*
|
|
673
|
-
*
|
|
671
|
+
* arena bytes, the rest compare (kind, b, payload). Duplicates are
|
|
672
|
+
* per-map by definition, so the scan keeps ONE open-addressing table
|
|
673
|
+
* per open container on a frame stack: a key registers in the
|
|
674
|
+
* innermost frame and frames pop on CLOSE. A single table cleared on
|
|
675
|
+
* open cannot express this — a parent key equal to a key in an
|
|
676
|
+
* earlier child object was a false duplicate, and a parent duplicate
|
|
677
|
+
* after a nested object went unseen.
|
|
674
678
|
*/
|
|
675
679
|
|
|
676
680
|
typedef struct {
|
|
@@ -682,8 +686,13 @@ typedef struct {
|
|
|
682
686
|
typedef struct {
|
|
683
687
|
dup_slot* slots;
|
|
684
688
|
size_t cap; /* power of two */
|
|
689
|
+
size_t count;
|
|
685
690
|
} dup_set;
|
|
686
691
|
|
|
692
|
+
typedef struct {
|
|
693
|
+
dup_set keys;
|
|
694
|
+
} dup_frame;
|
|
695
|
+
|
|
687
696
|
static uint64_t dup_hash(const dup_slot* k, const char* arena) {
|
|
688
697
|
uint64_t h = 1469598103934665603ull;
|
|
689
698
|
if (k->len != UINT32_MAX && (k->kind == YEP_V_STR || k->kind == YEP_V_TIMESTAMP ||
|
|
@@ -717,61 +726,102 @@ static int dup_eq(const dup_slot* a, const dup_slot* b, const char* arena) {
|
|
|
717
726
|
return a->len == 0 || memcmp(arena + a->off, arena + b->off, a->len) == 0;
|
|
718
727
|
}
|
|
719
728
|
|
|
720
|
-
static int dup_set_grow(dup_set* s) {
|
|
729
|
+
static int dup_set_grow(dup_set* s, const char* arena) {
|
|
721
730
|
size_t ncap = s->cap ? s->cap * 2 : 16;
|
|
722
731
|
dup_slot* ns = calloc(ncap, sizeof(*ns));
|
|
723
732
|
if (ns == NULL) {
|
|
724
733
|
return -1;
|
|
725
734
|
}
|
|
726
|
-
|
|
727
|
-
|
|
735
|
+
for (size_t i = 0; i < s->cap; i++) {
|
|
736
|
+
dup_slot* old = &s->slots[i];
|
|
737
|
+
if (old->p == 0) {
|
|
738
|
+
continue;
|
|
739
|
+
}
|
|
740
|
+
uint64_t h = dup_hash(old, arena);
|
|
741
|
+
while (ns[h & (ncap - 1)].p != 0) {
|
|
742
|
+
h++;
|
|
743
|
+
}
|
|
744
|
+
ns[h & (ncap - 1)] = *old;
|
|
728
745
|
}
|
|
746
|
+
free(s->slots);
|
|
729
747
|
s->slots = ns;
|
|
730
748
|
s->cap = ncap;
|
|
731
749
|
return 0;
|
|
732
750
|
}
|
|
733
751
|
|
|
752
|
+
/* 1 = duplicate, 0 = inserted, -1 = oom. Load factor stays <= 1/2. */
|
|
753
|
+
static int dup_set_insert(dup_set* s, const dup_slot* k, const char* arena) {
|
|
754
|
+
if ((s->count + 1) * 2 > s->cap && dup_set_grow(s, arena) != 0) {
|
|
755
|
+
return -1;
|
|
756
|
+
}
|
|
757
|
+
uint64_t h = dup_hash(k, arena);
|
|
758
|
+
for (;;) {
|
|
759
|
+
dup_slot* slot = &s->slots[h & (s->cap - 1)];
|
|
760
|
+
if (slot->p == 0) {
|
|
761
|
+
*slot = *k;
|
|
762
|
+
s->count++;
|
|
763
|
+
return 0;
|
|
764
|
+
}
|
|
765
|
+
if (dup_eq(slot, k, arena)) {
|
|
766
|
+
return 1;
|
|
767
|
+
}
|
|
768
|
+
h++;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
|
|
734
772
|
/* 1 = duplicate found (TLS error set), 0 = clean, -1 = oom */
|
|
735
773
|
static int strict_dup_scan(const yep_value_ctx* c) {
|
|
736
|
-
|
|
774
|
+
dup_frame* frames = NULL;
|
|
775
|
+
size_t depth = 0, cap = 0;
|
|
737
776
|
int rc = 0;
|
|
738
777
|
const YeptrisValue* vals = c->vals;
|
|
739
778
|
for (size_t i = 0; i < c->n && rc == 0; i++) {
|
|
740
779
|
const YeptrisValue* v = &vals[i];
|
|
741
|
-
if (v->kind == YEP_V_MAP_OPEN) {
|
|
742
|
-
if (
|
|
743
|
-
|
|
780
|
+
if (v->kind == YEP_V_MAP_OPEN || v->kind == YEP_V_SEQ_OPEN) {
|
|
781
|
+
if (depth == cap) {
|
|
782
|
+
size_t ncap = cap ? cap * 2 : 16;
|
|
783
|
+
dup_frame* nf = realloc(frames, ncap * sizeof(*nf));
|
|
784
|
+
if (nf == NULL) {
|
|
785
|
+
rc = -1;
|
|
786
|
+
break;
|
|
787
|
+
}
|
|
788
|
+
frames = nf;
|
|
789
|
+
cap = ncap;
|
|
744
790
|
}
|
|
791
|
+
frames[depth].keys.slots = NULL;
|
|
792
|
+
frames[depth].keys.cap = 0;
|
|
793
|
+
frames[depth].keys.count = 0;
|
|
794
|
+
depth++;
|
|
745
795
|
continue;
|
|
746
796
|
}
|
|
747
|
-
if (v->kind == YEP_V_CLOSE
|
|
797
|
+
if (v->kind == YEP_V_CLOSE) {
|
|
798
|
+
if (depth > 0) {
|
|
799
|
+
depth--;
|
|
800
|
+
free(frames[depth].keys.slots);
|
|
801
|
+
}
|
|
802
|
+
continue;
|
|
803
|
+
}
|
|
804
|
+
if (v->is_key != 1 || depth == 0) {
|
|
748
805
|
continue;
|
|
749
806
|
}
|
|
750
807
|
dup_slot k = {v->p, v->off, v->len, v->kind, v->b};
|
|
751
808
|
if (k.p == 0) {
|
|
752
809
|
k.p = 1; /* never aliases the empty-slot sentinel */
|
|
753
810
|
}
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
uint64_t h = dup_hash(&k, c->arena);
|
|
759
|
-
for (;;) {
|
|
760
|
-
dup_slot* slot = &s.slots[h & (s.cap - 1)];
|
|
761
|
-
if (slot->p == 0) {
|
|
762
|
-
*slot = k;
|
|
763
|
-
break;
|
|
764
|
-
}
|
|
765
|
-
if (dup_eq(slot, &k, c->arena)) {
|
|
766
|
-
yep_error_set(yep_error_tls(), YEP_ERR_UNEXPECTED, 0, 0, 0,
|
|
767
|
-
"duplicate key in object");
|
|
768
|
-
rc = 1;
|
|
769
|
-
break;
|
|
811
|
+
int irc = dup_set_insert(&frames[depth - 1].keys, &k, c->arena);
|
|
812
|
+
if (irc != 1) {
|
|
813
|
+
if (irc < 0) {
|
|
814
|
+
rc = -1;
|
|
770
815
|
}
|
|
771
|
-
|
|
816
|
+
continue;
|
|
772
817
|
}
|
|
818
|
+
yep_error_set(yep_error_tls(), YEP_ERR_UNEXPECTED, 0, 0, 0, "duplicate key in object");
|
|
819
|
+
rc = 1;
|
|
820
|
+
}
|
|
821
|
+
for (size_t j = 0; j < depth; j++) {
|
|
822
|
+
free(frames[j].keys.slots);
|
|
773
823
|
}
|
|
774
|
-
free(
|
|
824
|
+
free(frames);
|
|
775
825
|
return rc;
|
|
776
826
|
}
|
|
777
827
|
|