yeptris 0.6.23.1-arm-linux-eabihf → 0.6.26.1-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/document.rb +10 -0
- data/lib/yeptris.rb +1 -1
- data/libyeptris.so +0 -0
- data/vendor/libyeptris/CMakeLists.txt +1 -1
- data/vendor/libyeptris/src/yeptris/events/recorder.c +6 -0
- data/vendor/libyeptris/src/yeptris/events/values.c +5 -0
- data/vendor/libyeptris/src/yeptris/parse/engine.c +58 -7
- data/vendor/libyeptris/src/yeptris/parse/engine.h +18 -0
- data/vendor/libyeptris/src/yeptris/parse.c +26 -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: e47e094203051044900e0b675f67289e3b86c751c0ad2762751f57fae9f21f65
|
|
4
|
+
data.tar.gz: ae6b25e84793e88d8d86698df20fc17e3fd5ad19d8a52f79e7b44c36ff5a358a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eec0297f6dd573f5d9fd3bc1ad4bc78d553197b7b9c7129b2bf8259d47feebe72c8f2a3b130926412cbb38130fb881dba4c46695597c1f19768320b6e6287354
|
|
7
|
+
data.tar.gz: 800c7a3984dc1ffac1c7d61be602f6d3890ccdf595601c220bf26a66bf6b931eaccfabfa4fa030454a0ecaeb23bf7549ca4ea7c77458d824759f76a0e222b95b
|
data/lib/yeptris/document.rb
CHANGED
|
@@ -17,6 +17,16 @@ class Yeptris::Document
|
|
|
17
17
|
attr_reader :parse_schema
|
|
18
18
|
|
|
19
19
|
def initialize(c_ptr = nil, freed = Freed.new(:alive), parse_schema = :core_12)
|
|
20
|
+
# The pointer is produced by the FFI parse/create calls; a nil (or
|
|
21
|
+
# non-pointer) argument is an API misuse — Document.parse and
|
|
22
|
+
# Document.create are the entry points. Fail with that guidance
|
|
23
|
+
# instead of a NoMethodError from the finalizer guard below (the
|
|
24
|
+
# FFI::Pointer#null? probe does not exist on nil).
|
|
25
|
+
unless c_ptr.is_a?(::FFI::Pointer)
|
|
26
|
+
raise ArgumentError,
|
|
27
|
+
"a document FFI pointer is required — build documents with " \
|
|
28
|
+
"Yeptris::Document.parse or Yeptris::Document.create"
|
|
29
|
+
end
|
|
20
30
|
@c_ptr = c_ptr
|
|
21
31
|
@freed = freed
|
|
22
32
|
@parse_schema = parse_schema
|
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.26.1".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
|
|
@@ -52,6 +52,12 @@ YEPTRIS_API YeptrisStatus yeptris_recorder_feed(YeptrisRecorder rec, const char*
|
|
|
52
52
|
}
|
|
53
53
|
yep_engine_set_resolver(rec->eng,
|
|
54
54
|
rec->compat11 ? yep_resolver_compat11() : yep_resolver_core12());
|
|
55
|
+
/* the compat schema is the psych/libyaml surface: its grammar
|
|
56
|
+
* must accept what libyaml accepts (the flow indent floor is
|
|
57
|
+
* suite-strict, not libyaml — see yep_engine_set_compat_grammar;
|
|
58
|
+
* the recorder is the py safe_load path, which rode the floor
|
|
59
|
+
* and rejected multi-line flows #431 fixed everywhere else) */
|
|
60
|
+
yep_engine_set_compat_grammar(rec->eng, rec->compat11);
|
|
55
61
|
}
|
|
56
62
|
if (final) {
|
|
57
63
|
rec->final_fed = 1;
|
|
@@ -389,6 +389,11 @@ int yep_values_from_input(const char* yaml, size_t len, int schema_compat, yep_v
|
|
|
389
389
|
return -1;
|
|
390
390
|
}
|
|
391
391
|
yep_engine_set_resolver(eng, schema_compat ? yep_resolver_compat11() : yep_resolver_core12());
|
|
392
|
+
if (schema_compat) {
|
|
393
|
+
yep_engine_set_compat_grammar(eng, 1); /* libyaml grammar parity
|
|
394
|
+
* (the value drains ride the
|
|
395
|
+
* same compat contract) */
|
|
396
|
+
}
|
|
392
397
|
|
|
393
398
|
yep_value_ctx* c = ctx_create();
|
|
394
399
|
if (c == NULL) {
|
|
@@ -124,6 +124,13 @@ struct yep_engine {
|
|
|
124
124
|
int doc_inline; /* content node opened on the --- line */
|
|
125
125
|
uint16_t flow_floor; /* parent column of the current block-level flow */
|
|
126
126
|
int flow_enforce; /* flow continuation lines must out-indent it */
|
|
127
|
+
int compat_grammar; /* 11-COMPAT: libyaml/psych grammar parity —
|
|
128
|
+
* the flow indent floor (9C9N/VJP3) is a
|
|
129
|
+
* yaml-test-suite rule libyaml never
|
|
130
|
+
* enforced, and real-world locale files
|
|
131
|
+
* close multi-line flows at the parent's
|
|
132
|
+
* column; the floor stays on for the
|
|
133
|
+
* strict 1.2 engine the suite runs */
|
|
127
134
|
};
|
|
128
135
|
|
|
129
136
|
/* ------------------------------------------------------------ forwards */
|
|
@@ -2308,7 +2315,7 @@ static int e_shape_flow_value(yep_engine* e, const yep_line_shape* sh, uint16_t
|
|
|
2308
2315
|
yep_view none = {NULL, 0};
|
|
2309
2316
|
e->pos = sh->val_start;
|
|
2310
2317
|
e->flow_floor = floor;
|
|
2311
|
-
e->flow_enforce = (e->depth > 0);
|
|
2318
|
+
e->flow_enforce = (e->depth > 0) && !e->compat_grammar;
|
|
2312
2319
|
int fast = e_flow_json(e, none, none, 0);
|
|
2313
2320
|
e->flow_enforce = 0;
|
|
2314
2321
|
if (fast == -2) {
|
|
@@ -2735,7 +2742,7 @@ static int e_node(yep_engine* e, yep_ctx ctx, uint16_t floor_col) {
|
|
|
2735
2742
|
/* JSON fast path first: its validating scan already finds the
|
|
2736
2743
|
* close, replacing e_skip_flow's pre-scan when it applies. */
|
|
2737
2744
|
e->flow_floor = floor_col;
|
|
2738
|
-
e->flow_enforce = (e->depth > 0);
|
|
2745
|
+
e->flow_enforce = (e->depth > 0) && !e->compat_grammar;
|
|
2739
2746
|
int fast = e_flow_json(e, node_a, node_t, anchor_ordinal);
|
|
2740
2747
|
e->flow_enforce = 0;
|
|
2741
2748
|
if (fast == 1) {
|
|
@@ -2780,7 +2787,7 @@ static int e_node(yep_engine* e, yep_ctx ctx, uint16_t floor_col) {
|
|
|
2780
2787
|
}
|
|
2781
2788
|
{
|
|
2782
2789
|
e->flow_floor = floor_col;
|
|
2783
|
-
e->flow_enforce = (e->depth > 0);
|
|
2790
|
+
e->flow_enforce = (e->depth > 0) && !e->compat_grammar;
|
|
2784
2791
|
int rc = e_flow(e, node_a, node_t, node_aid);
|
|
2785
2792
|
e->flow_enforce = 0;
|
|
2786
2793
|
if (rc != 0) {
|
|
@@ -3112,6 +3119,12 @@ void yep_engine_set_resolver(yep_engine* e, const yep_resolver* r) {
|
|
|
3112
3119
|
}
|
|
3113
3120
|
}
|
|
3114
3121
|
|
|
3122
|
+
void yep_engine_set_compat_grammar(yep_engine* e, int on) {
|
|
3123
|
+
if (e != NULL) {
|
|
3124
|
+
e->compat_grammar = on != 0;
|
|
3125
|
+
}
|
|
3126
|
+
}
|
|
3127
|
+
|
|
3115
3128
|
void yep_engine_set_max_depth(yep_engine* e, int depth) {
|
|
3116
3129
|
if (e != NULL && depth > 0) {
|
|
3117
3130
|
e->max_depth = depth > YEP_MAX_DEPTH ? YEP_MAX_DEPTH : depth;
|
|
@@ -3166,10 +3179,46 @@ yep_engine* yep_engine_create(const yep_allocator* sys) {
|
|
|
3166
3179
|
* input is copied with each normalized to a single '\n' (libyaml reader
|
|
3167
3180
|
* behavior); inputs without them keep the zero-copy path. */
|
|
3168
3181
|
static const char* e_normalize_breaks(yep_engine* e, const char* p, size_t len) {
|
|
3182
|
+
char* out = yep_engine_normalize_breaks(e->sys, p, len, NULL);
|
|
3183
|
+
if (out == NULL) {
|
|
3184
|
+
return p;
|
|
3185
|
+
}
|
|
3186
|
+
e->norm_buf = out;
|
|
3187
|
+
return out;
|
|
3188
|
+
}
|
|
3189
|
+
|
|
3190
|
+
/* The NEL/LS/PS -> '\n' copy (the one-shot path rides this BEFORE the
|
|
3191
|
+
* engine so the normalized bytes own the document's `transcoded` slot;
|
|
3192
|
+
* the engine's per-feed copy stays for the streaming feeds). Returns
|
|
3193
|
+
* NULL when the input has no exotic break. */
|
|
3194
|
+
/* The two possible LEAD bytes of a Unicode break (NEL = C2 85; LS/PS =
|
|
3195
|
+
* E2 80 A8/A9). The whole-document probe rides the SIMD stopset kernel
|
|
3196
|
+
* and only candidates get the byte check — the per-byte walk was 11%
|
|
3197
|
+
* of every parse (exclusive profile, block-heavy DOM, 2026-09-27).
|
|
3198
|
+
* Pinned against yep_stopset_init by Parse.NormBreakLeadsMatchRuntimeBuild. */
|
|
3199
|
+
const yep_stopset yep_norm_break_leads = {
|
|
3200
|
+
.bitmap = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
3201
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
3202
|
+
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00},
|
|
3203
|
+
.groups = 1,
|
|
3204
|
+
.lo = {{0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
3205
|
+
0x00, 0x00}},
|
|
3206
|
+
.hi = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
|
3207
|
+
0x02, 0x00}},
|
|
3208
|
+
};
|
|
3209
|
+
|
|
3210
|
+
char* yep_engine_normalize_breaks(const yep_allocator* sys, const char* p, size_t len,
|
|
3211
|
+
size_t* out_len) {
|
|
3169
3212
|
const unsigned char* q = (const unsigned char*)p;
|
|
3213
|
+
const yep_text_kernels* k = yep_text_active();
|
|
3170
3214
|
size_t i = 0;
|
|
3171
3215
|
int found = 0;
|
|
3172
3216
|
while (i < len) {
|
|
3217
|
+
ptrdiff_t hit = k->stopset_find(&yep_norm_break_leads, (const char*)q + i, len - i);
|
|
3218
|
+
if (hit < 0) {
|
|
3219
|
+
break;
|
|
3220
|
+
}
|
|
3221
|
+
i += (size_t)hit;
|
|
3173
3222
|
if (q[i] == 0xC2 && i + 1 < len && q[i + 1] == 0x85) {
|
|
3174
3223
|
found = 1;
|
|
3175
3224
|
break;
|
|
@@ -3182,11 +3231,11 @@ static const char* e_normalize_breaks(yep_engine* e, const char* p, size_t len)
|
|
|
3182
3231
|
i++;
|
|
3183
3232
|
}
|
|
3184
3233
|
if (!found) {
|
|
3185
|
-
return
|
|
3234
|
+
return NULL;
|
|
3186
3235
|
}
|
|
3187
|
-
char* out = yep_alloc(
|
|
3236
|
+
char* out = yep_alloc(sys, len + 1);
|
|
3188
3237
|
if (out == NULL) {
|
|
3189
|
-
return
|
|
3238
|
+
return NULL;
|
|
3190
3239
|
}
|
|
3191
3240
|
size_t o = 0;
|
|
3192
3241
|
for (size_t j = 0; j < len;) {
|
|
@@ -3202,7 +3251,9 @@ static const char* e_normalize_breaks(yep_engine* e, const char* p, size_t len)
|
|
|
3202
3251
|
}
|
|
3203
3252
|
}
|
|
3204
3253
|
out[o] = '\0';
|
|
3205
|
-
|
|
3254
|
+
if (out_len != NULL) {
|
|
3255
|
+
*out_len = o;
|
|
3256
|
+
}
|
|
3206
3257
|
return out;
|
|
3207
3258
|
}
|
|
3208
3259
|
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
#include "common/error.h"
|
|
13
13
|
#include "common/simd_text.h"
|
|
14
|
+
|
|
14
15
|
#include "memory/allocator.h"
|
|
15
16
|
#include "memory/pool.h"
|
|
16
17
|
#include "parse/events.h"
|
|
@@ -19,6 +20,9 @@
|
|
|
19
20
|
extern "C" {
|
|
20
21
|
#endif
|
|
21
22
|
|
|
23
|
+
/* Pinned by Parse.NormBreakLeadsMatchRuntimeBuild (test_parse.cpp). */
|
|
24
|
+
extern const yep_stopset yep_norm_break_leads;
|
|
25
|
+
|
|
22
26
|
typedef struct yep_engine yep_engine;
|
|
23
27
|
|
|
24
28
|
yep_engine* yep_engine_create(const yep_allocator* sys);
|
|
@@ -52,12 +56,26 @@ struct yep_resolver;
|
|
|
52
56
|
void yep_engine_set_resolver(yep_engine* e, const struct yep_resolver* r);
|
|
53
57
|
void yep_engine_set_max_depth(yep_engine* e, int depth);
|
|
54
58
|
|
|
59
|
+
/* The 1.1-compat grammar (libyaml/psych parity): the block-level flow
|
|
60
|
+
* indent floor (9C9N, VJP3) is a yaml-test-suite rule libyaml never
|
|
61
|
+
* enforced — real-world locale files close multi-line flow collections
|
|
62
|
+
* at their parent's column ("k: {\n a: b\n}"). Off by default (the
|
|
63
|
+
* strict 1.2 engine the conformance suite runs keeps the floor). */
|
|
64
|
+
void yep_engine_set_compat_grammar(yep_engine* e, int on);
|
|
65
|
+
|
|
55
66
|
/* Byte offset the last run reached (into that run's buffer); used by
|
|
56
67
|
* consumers that stop the engine at a boundary and resume. */
|
|
57
68
|
size_t yep_engine_pos(const yep_engine* e);
|
|
58
69
|
|
|
59
70
|
const yep_error* yep_engine_error(const yep_engine* e);
|
|
60
71
|
|
|
72
|
+
/* The NEL/LS/PS -> '\n' copy; NULL when the input is clean (probe rides
|
|
73
|
+
* the stopset kernel). One-shot parse runs this BEFORE the engine so
|
|
74
|
+
* the copy owns the document's transcoded slot; the engine's per-feed
|
|
75
|
+
* copy (norm_buf) stays for the streaming feeds. */
|
|
76
|
+
char* yep_engine_normalize_breaks(const yep_allocator* sys, const char* p, size_t len,
|
|
77
|
+
size_t* out_len);
|
|
78
|
+
|
|
61
79
|
#ifdef __cplusplus
|
|
62
80
|
}
|
|
63
81
|
#endif
|
|
@@ -293,6 +293,26 @@ static YeptrisDocument parse_impl(const char* buf, size_t len, const YeptrisPars
|
|
|
293
293
|
}
|
|
294
294
|
}
|
|
295
295
|
|
|
296
|
+
/* Unicode breaks (NEL/LS/PS) normalize to '\n' BEFORE the engine:
|
|
297
|
+
* the copy rides `transcoded`, whose ownership plumbing (input_base
|
|
298
|
+
* views, doc free, fail paths) already exists. Letting the engine's
|
|
299
|
+
* per-feed copy fire here returned views into ENGINE-owned memory
|
|
300
|
+
* that dies at yeptris_parse teardown — every one-shot NEL document
|
|
301
|
+
* dangled (no test ever covered one; found by the NormBreakLeads
|
|
302
|
+
* slice, 2026-09-27). JSON mode skips this: the JSON reader keeps
|
|
303
|
+
* U+0085 raw inside strings, only the YAML reader normalizes. */
|
|
304
|
+
{
|
|
305
|
+
size_t nlen = 0;
|
|
306
|
+
char* norm = yep_engine_normalize_breaks(sys, data, data_len, &nlen);
|
|
307
|
+
if (norm != NULL) {
|
|
308
|
+
yep_free(sys, transcoded);
|
|
309
|
+
transcoded = (unsigned char*)norm;
|
|
310
|
+
transcoded_len = nlen;
|
|
311
|
+
data = norm;
|
|
312
|
+
data_len = nlen;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
296
316
|
/* Engine → DOM. */
|
|
297
317
|
yep_engine* eng = NULL;
|
|
298
318
|
engine_enter:
|
|
@@ -301,6 +321,12 @@ engine_enter:
|
|
|
301
321
|
yep_engine_set_resolver(eng, opts->schema == YEPTRIS_SCHEMA_11_COMPAT
|
|
302
322
|
? yep_resolver_compat11()
|
|
303
323
|
: yep_resolver_core12());
|
|
324
|
+
if (opts->schema == YEPTRIS_SCHEMA_11_COMPAT) {
|
|
325
|
+
/* the compat schema is the psych/libyaml surface: its grammar
|
|
326
|
+
* must accept what libyaml accepts (the flow floor is suite-
|
|
327
|
+
* strict, not libyaml — see yep_engine_set_compat_grammar) */
|
|
328
|
+
yep_engine_set_compat_grammar(eng, 1);
|
|
329
|
+
}
|
|
304
330
|
if (opts->max_depth > 0) {
|
|
305
331
|
yep_engine_set_max_depth(eng, opts->max_depth);
|
|
306
332
|
}
|