yeptris 0.6.18.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.
Files changed (142) hide show
  1. checksums.yaml +7 -0
  2. data/README.adoc +141 -0
  3. data/ext/build_windows_native.rb +41 -0
  4. data/ext/libyeptris/extconf.rb +57 -0
  5. data/ext/yeptris_native/cbor_ruby.c +193 -0
  6. data/ext/yeptris_native/extconf.rb +47 -0
  7. data/ext/yeptris_native/json_ruby.c +354 -0
  8. data/ext/yeptris_native/yeptris_native.c +497 -0
  9. data/lib/yeptris/cbor.rb +130 -0
  10. data/lib/yeptris/document.rb +255 -0
  11. data/lib/yeptris/ffi.rb +426 -0
  12. data/lib/yeptris/json/descriptor.rb +266 -0
  13. data/lib/yeptris/json.rb +394 -0
  14. data/lib/yeptris/materializer.rb +354 -0
  15. data/lib/yeptris/native-3.4.so +0 -0
  16. data/lib/yeptris/node.rb +453 -0
  17. data/lib/yeptris/psych/class_loader.rb +24 -0
  18. data/lib/yeptris/psych/coder_shim.rb +55 -0
  19. data/lib/yeptris/psych/drop_in.rb +63 -0
  20. data/lib/yeptris/psych/encodable.rb +14 -0
  21. data/lib/yeptris/psych/handler.rb +90 -0
  22. data/lib/yeptris/psych/parser.rb +105 -0
  23. data/lib/yeptris/psych/scalar_scanner.rb +149 -0
  24. data/lib/yeptris/psych/visitors.rb +545 -0
  25. data/lib/yeptris/psych.rb +622 -0
  26. data/lib/yeptris/schema.rb +253 -0
  27. data/lib/yeptris/valueml.rb +455 -0
  28. data/lib/yeptris/yaml/descriptor.rb +56 -0
  29. data/lib/yeptris/yaml.rb +422 -0
  30. data/lib/yeptris.rb +113 -0
  31. data/libyeptris.so +0 -0
  32. data/vendor/libyeptris/CMakeLists.txt +254 -0
  33. data/vendor/libyeptris/cmake/yeptris-config.cmake.in +5 -0
  34. data/vendor/libyeptris/cmake/yeptris.pc.in +11 -0
  35. data/vendor/libyeptris/src/CMakeLists.txt +167 -0
  36. data/vendor/libyeptris/src/include/yeptris/api.h +32 -0
  37. data/vendor/libyeptris/src/include/yeptris/cbor.h +101 -0
  38. data/vendor/libyeptris/src/include/yeptris/dom.h +190 -0
  39. data/vendor/libyeptris/src/include/yeptris/emit.h +81 -0
  40. data/vendor/libyeptris/src/include/yeptris/error.h +41 -0
  41. data/vendor/libyeptris/src/include/yeptris/events.h +157 -0
  42. data/vendor/libyeptris/src/include/yeptris/json.h +45 -0
  43. data/vendor/libyeptris/src/include/yeptris/json.hpp +258 -0
  44. data/vendor/libyeptris/src/include/yeptris/jsonc_compat.h +115 -0
  45. data/vendor/libyeptris/src/include/yeptris/marshal.h +52 -0
  46. data/vendor/libyeptris/src/include/yeptris/parse.h +48 -0
  47. data/vendor/libyeptris/src/include/yeptris/plan.h +100 -0
  48. data/vendor/libyeptris/src/include/yeptris/resolve.h +71 -0
  49. data/vendor/libyeptris/src/include/yeptris/schema.h +121 -0
  50. data/vendor/libyeptris/src/include/yeptris/tape.h +123 -0
  51. data/vendor/libyeptris/src/include/yeptris/types.h +38 -0
  52. data/vendor/libyeptris/src/include/yeptris/values.h +102 -0
  53. data/vendor/libyeptris/src/include/yeptris/version.h.in +29 -0
  54. data/vendor/libyeptris/src/include/yeptris/visit.h +77 -0
  55. data/vendor/libyeptris/src/include/yeptris/yajl_compat.h +135 -0
  56. data/vendor/libyeptris/src/include/yeptris.h +23 -0
  57. data/vendor/libyeptris/src/yeptris/build.c +376 -0
  58. data/vendor/libyeptris/src/yeptris/cbor/cbor.h +25 -0
  59. data/vendor/libyeptris/src/yeptris/cbor/decode.c +981 -0
  60. data/vendor/libyeptris/src/yeptris/cbor/encode.c +835 -0
  61. data/vendor/libyeptris/src/yeptris/cbor/sink.h +58 -0
  62. data/vendor/libyeptris/src/yeptris/common/chartype.c +41 -0
  63. data/vendor/libyeptris/src/yeptris/common/chartype.h +77 -0
  64. data/vendor/libyeptris/src/yeptris/common/cpu.c +81 -0
  65. data/vendor/libyeptris/src/yeptris/common/cpu.h +40 -0
  66. data/vendor/libyeptris/src/yeptris/common/error.c +65 -0
  67. data/vendor/libyeptris/src/yeptris/common/error.h +79 -0
  68. data/vendor/libyeptris/src/yeptris/common/mutex.h +45 -0
  69. data/vendor/libyeptris/src/yeptris/common/nametab.c +275 -0
  70. data/vendor/libyeptris/src/yeptris/common/nametab.h +68 -0
  71. data/vendor/libyeptris/src/yeptris/common/port.h +74 -0
  72. data/vendor/libyeptris/src/yeptris/common/simd_text.c +49 -0
  73. data/vendor/libyeptris/src/yeptris/common/simd_text.h +295 -0
  74. data/vendor/libyeptris/src/yeptris/common/simd_text_avx2.c +534 -0
  75. data/vendor/libyeptris/src/yeptris/common/simd_text_neon.c +662 -0
  76. data/vendor/libyeptris/src/yeptris/common/simd_text_scalar.c +298 -0
  77. data/vendor/libyeptris/src/yeptris/common/string_view.c +34 -0
  78. data/vendor/libyeptris/src/yeptris/common/string_view.h +93 -0
  79. data/vendor/libyeptris/src/yeptris/doc.h +56 -0
  80. data/vendor/libyeptris/src/yeptris/dom/dom.c +1192 -0
  81. data/vendor/libyeptris/src/yeptris/dom/dom.h +312 -0
  82. data/vendor/libyeptris/src/yeptris/dom/hpool.c +107 -0
  83. data/vendor/libyeptris/src/yeptris/dom/mapindex.c +173 -0
  84. data/vendor/libyeptris/src/yeptris/dom/mapindex.h +61 -0
  85. data/vendor/libyeptris/src/yeptris/dom/mutate.c +431 -0
  86. data/vendor/libyeptris/src/yeptris/emit/emit.c +434 -0
  87. data/vendor/libyeptris/src/yeptris/emit/float/api.h +38 -0
  88. data/vendor/libyeptris/src/yeptris/emit/float/dragon.c +405 -0
  89. data/vendor/libyeptris/src/yeptris/emit/float/floatint.h +231 -0
  90. data/vendor/libyeptris/src/yeptris/emit/float/print.c +396 -0
  91. data/vendor/libyeptris/src/yeptris/emit/style.c +81 -0
  92. data/vendor/libyeptris/src/yeptris/emit/style.h +24 -0
  93. data/vendor/libyeptris/src/yeptris/emit/writer.c +816 -0
  94. data/vendor/libyeptris/src/yeptris/emit/writer.h +76 -0
  95. data/vendor/libyeptris/src/yeptris/encoding/bom.c +31 -0
  96. data/vendor/libyeptris/src/yeptris/encoding/encoding.h +63 -0
  97. data/vendor/libyeptris/src/yeptris/encoding/transcode.c +148 -0
  98. data/vendor/libyeptris/src/yeptris/encoding/utf8_validate.c +178 -0
  99. data/vendor/libyeptris/src/yeptris/events/capture.c +150 -0
  100. data/vendor/libyeptris/src/yeptris/events/capture.h +39 -0
  101. data/vendor/libyeptris/src/yeptris/events/iterparse.c +208 -0
  102. data/vendor/libyeptris/src/yeptris/events/pull.c +97 -0
  103. data/vendor/libyeptris/src/yeptris/events/push.c +104 -0
  104. data/vendor/libyeptris/src/yeptris/events/recorder.c +107 -0
  105. data/vendor/libyeptris/src/yeptris/events/values.c +527 -0
  106. data/vendor/libyeptris/src/yeptris/events/values_priv.h +51 -0
  107. data/vendor/libyeptris/src/yeptris/events/yaml_compat.c +86 -0
  108. data/vendor/libyeptris/src/yeptris/events/yaml_compat.h +90 -0
  109. data/vendor/libyeptris/src/yeptris/jsonapi/jsonc_compat.c +687 -0
  110. data/vendor/libyeptris/src/yeptris/jsonapi/yajl_compat.c +728 -0
  111. data/vendor/libyeptris/src/yeptris/marshal.c +782 -0
  112. data/vendor/libyeptris/src/yeptris/memory/allocator.c +20 -0
  113. data/vendor/libyeptris/src/yeptris/memory/allocator.h +43 -0
  114. data/vendor/libyeptris/src/yeptris/memory/arena.c +134 -0
  115. data/vendor/libyeptris/src/yeptris/memory/arena.h +52 -0
  116. data/vendor/libyeptris/src/yeptris/memory/pool.c +122 -0
  117. data/vendor/libyeptris/src/yeptris/memory/pool.h +36 -0
  118. data/vendor/libyeptris/src/yeptris/parse/engine.c +3698 -0
  119. data/vendor/libyeptris/src/yeptris/parse/engine.h +65 -0
  120. data/vendor/libyeptris/src/yeptris/parse/events.h +124 -0
  121. data/vendor/libyeptris/src/yeptris/parse/numbers.c +349 -0
  122. data/vendor/libyeptris/src/yeptris/parse/numbers.h +33 -0
  123. data/vendor/libyeptris/src/yeptris/parse/scalars.c +416 -0
  124. data/vendor/libyeptris/src/yeptris/parse/scalars.h +75 -0
  125. data/vendor/libyeptris/src/yeptris/parse.c +737 -0
  126. data/vendor/libyeptris/src/yeptris/plan.c +824 -0
  127. data/vendor/libyeptris/src/yeptris/resolve/compat11.c +334 -0
  128. data/vendor/libyeptris/src/yeptris/resolve/core12.c +143 -0
  129. data/vendor/libyeptris/src/yeptris/resolve/resolver.h +56 -0
  130. data/vendor/libyeptris/src/yeptris/resolve/tags.c +58 -0
  131. data/vendor/libyeptris/src/yeptris/scan/json.c +792 -0
  132. data/vendor/libyeptris/src/yeptris/scan/json.h +109 -0
  133. data/vendor/libyeptris/src/yeptris/scan/scan.c +463 -0
  134. data/vendor/libyeptris/src/yeptris/scan/scan.h +150 -0
  135. data/vendor/libyeptris/src/yeptris/schema.c +308 -0
  136. data/vendor/libyeptris/src/yeptris/tape.c +1308 -0
  137. data/vendor/libyeptris/src/yeptris/tape_in.h +19 -0
  138. data/vendor/libyeptris/src/yeptris/version.c +7 -0
  139. data/vendor/libyeptris/src/yeptris/visit/dom_visit.c +115 -0
  140. data/vendor/libyeptris/src/yeptris/visit/json_visit.c +293 -0
  141. data/vendor/libyeptris/src/yeptris/visit/yaml_visit.c +127 -0
  142. metadata +199 -0
@@ -0,0 +1,527 @@
1
+ /* values.c — the typed value stream (TODO.impl/15 phase F).
2
+ *
3
+ * One engine run through the shared capture sink, then one C pass
4
+ * converting every scalar by its resolver tag through the number
5
+ * kernels (parse/numbers.c — the same converters the node typed
6
+ * accessors ride). The host walks a flat typed array: no per-scalar
7
+ * parsing, no pending-key bookkeeping (is_key), anchor names arrive
8
+ * as uniform YEP_V_ANCHOR entries decorating the value they bind.
9
+ *
10
+ * TODO.restructure/21: the record machinery is shared (values_priv.h)
11
+ * with the Marshal emitter, a DOM linearizer produces the same records
12
+ * from a built tree, and the input entry sniffs strict JSON to build
13
+ * through the JSON scanner — any grammar surprise defers to the engine
14
+ * so records stay byte-identical across routes. */
15
+
16
+ #include <stdlib.h>
17
+ #include <string.h>
18
+
19
+ #include "../../include/yeptris/values.h"
20
+ #include "../common/simd_text.h"
21
+ #include "../dom/dom.h"
22
+ #include "../memory/allocator.h"
23
+ #include "../parse/engine.h"
24
+ #include "../parse/numbers.h"
25
+ #include "../resolve/resolver.h"
26
+ #include "../scan/json.h"
27
+ #include "capture.h"
28
+ #include "values_priv.h"
29
+
30
+ uint32_t yep_val_arena_put(yep_value_ctx* c, const char* p, uint32_t len) {
31
+ if (c->arena_len + len + 1 > c->arena_cap) {
32
+ size_t cap = c->arena_cap ? c->arena_cap : 256;
33
+ while (cap < c->arena_len + len + 1) {
34
+ cap *= 2;
35
+ }
36
+ char* na = realloc(c->arena, cap);
37
+ if (na == NULL) {
38
+ c->oom = 1;
39
+ return 0;
40
+ }
41
+ c->arena = na;
42
+ c->arena_cap = cap;
43
+ }
44
+ if (len != 0) {
45
+ memcpy(c->arena + c->arena_len, p, len);
46
+ }
47
+ uint32_t off = (uint32_t)c->arena_len;
48
+ c->arena_len += len;
49
+ c->arena[c->arena_len++] = '\0'; /* names read as C strings */
50
+ return off;
51
+ }
52
+
53
+ void yep_val_put(yep_value_ctx* c, const YeptrisValue* v) {
54
+ if (c->n == c->cap) {
55
+ size_t cap = c->cap ? c->cap * 2 : 256;
56
+ YeptrisValue* nv = realloc(c->vals, cap * sizeof(*nv));
57
+ if (nv == NULL) {
58
+ c->oom = 1;
59
+ return;
60
+ }
61
+ c->vals = nv;
62
+ c->cap = cap;
63
+ }
64
+ c->vals[c->n++] = *v;
65
+ }
66
+
67
+ /* The map slot rule: in a mapping, entries alternate key/value — the
68
+ * entry landing in an empty key slot is the key (is_key set), the
69
+ * next completes the pair. Applies to scalars, aliases, and
70
+ * collection opens (complex keys) alike. */
71
+ void yep_val_slot(yep_value_ctx* c, YeptrisValue* v) {
72
+ if (c->depth > 0 && c->depth <= YEP_V_MAX_DEPTH) {
73
+ int di = c->depth - 1;
74
+ if (c->key_pend[di] == 0) {
75
+ v->is_key = 1;
76
+ c->key_pend[di] = 1;
77
+ } else {
78
+ c->key_pend[di] = 0;
79
+ }
80
+ }
81
+ }
82
+
83
+ static void anchor_entry(yep_value_ctx* c, const char* name, uint32_t len) {
84
+ YeptrisValue a = {YEP_V_ANCHOR, 0, 0, 0, 0, len, 0};
85
+ a.off = yep_val_arena_put(c, name, len);
86
+ yep_val_put(c, &a);
87
+ }
88
+
89
+ /* The scalar conversion SSOT: tag verdict + raw bytes → typed record.
90
+ * The engine transform and the DOM linearizer both land here, so the
91
+ * routes cannot drift. */
92
+ static void val_scalar(yep_value_ctx* c, uint8_t tag_id, int implicit_plain, const char* text,
93
+ uint32_t len) {
94
+ YeptrisValue v = {0, 0, 0, 0, 0, 0, 0};
95
+ int64_t vi = 0;
96
+ double vd = 0.0;
97
+ v.tag_id = tag_id;
98
+ /* EVERY scalar carries its raw bytes: hosts with schema quirks
99
+ * (Psych's single-char y/n, PyYAML's dot-required floats)
100
+ * re-decide from tag_id + text without re-running a conversion
101
+ * grammar */
102
+ v.off = yep_val_arena_put(c, text, len);
103
+ v.len = len;
104
+ if (tag_id != YEPTRIS_TAG_BOOL) {
105
+ /* b doubles as the implicit-plain flag for the other kinds
106
+ * (host symbol scans and friends key on it) */
107
+ v.b = implicit_plain ? 1 : 0;
108
+ }
109
+ switch (tag_id) {
110
+ case YEPTRIS_TAG_NULL:
111
+ v.kind = YEP_V_NULL;
112
+ break;
113
+ case YEPTRIS_TAG_BOOL:
114
+ v.kind = YEP_V_BOOL;
115
+ v.b = (uint8_t)yep_num_bool_ci(text, len);
116
+ break;
117
+ case YEPTRIS_TAG_INT:
118
+ v.kind = YEP_V_INT;
119
+ if (yep_num_i64(text, len, &vi) != 0) {
120
+ /* the resolver tagged it but the kernel rejects:
121
+ * degrade to STR — host policy decides */
122
+ v.kind = YEP_V_STR;
123
+ v.p = 0;
124
+ } else {
125
+ v.p = (uint64_t)vi;
126
+ }
127
+ break;
128
+ case YEPTRIS_TAG_FLOAT:
129
+ v.kind = YEP_V_FLOAT;
130
+ if (yep_num_f64(text, len, &vd) != 0) {
131
+ v.kind = YEP_V_STR;
132
+ } else {
133
+ memcpy(&v.p, &vd, sizeof(v.p));
134
+ }
135
+ break;
136
+ case YEPTRIS_TAG_TIMESTAMP:
137
+ v.kind = YEP_V_TIMESTAMP;
138
+ break;
139
+ default:
140
+ v.kind = YEP_V_STR;
141
+ break;
142
+ }
143
+ yep_val_slot(c, &v);
144
+ yep_val_put(c, &v);
145
+ }
146
+
147
+ static int transform(yep_value_ctx* c, const yep_rec_store* store) {
148
+ const YeptrisEventRecord* rs = store->recs;
149
+ const char* ra = store->arena ? store->arena : "";
150
+ for (size_t i = 0; i < store->n; i++) {
151
+ const YeptrisEventRecord* r = &rs[i];
152
+ if (r->anchor_len != 0 && r->type != YEPTRIS_EV_ALIAS) {
153
+ anchor_entry(c, ra + r->anchor_off, r->anchor_len);
154
+ }
155
+ YeptrisValue v = {0, 0, 0, 0, 0, 0, 0};
156
+ switch (r->type) {
157
+ case YEPTRIS_EV_STREAM_START:
158
+ case YEPTRIS_EV_STREAM_END:
159
+ continue;
160
+ case YEPTRIS_EV_DOCUMENT_START:
161
+ v.kind = YEP_V_DOC;
162
+ yep_val_put(c, &v);
163
+ continue;
164
+ case YEPTRIS_EV_SEQUENCE_START:
165
+ v.kind = YEP_V_SEQ_OPEN;
166
+ v.tag_id = r->tag_id;
167
+ yep_val_slot(c, &v);
168
+ yep_val_put(c, &v);
169
+ if (c->depth < YEP_V_MAX_DEPTH) {
170
+ c->key_pend[c->depth] = 0;
171
+ }
172
+ c->depth++;
173
+ continue;
174
+ case YEPTRIS_EV_MAPPING_START:
175
+ v.kind = YEP_V_MAP_OPEN;
176
+ v.tag_id = r->tag_id;
177
+ yep_val_slot(c, &v);
178
+ yep_val_put(c, &v);
179
+ if (c->depth < YEP_V_MAX_DEPTH) {
180
+ c->key_pend[c->depth] = 0;
181
+ }
182
+ c->depth++;
183
+ continue;
184
+ case YEPTRIS_EV_SEQUENCE_END:
185
+ case YEPTRIS_EV_MAPPING_END:
186
+ v.kind = YEP_V_CLOSE;
187
+ yep_val_put(c, &v);
188
+ c->depth--;
189
+ continue;
190
+ case YEPTRIS_EV_ALIAS:
191
+ v.kind = YEP_V_ALIAS;
192
+ v.off = yep_val_arena_put(c, ra + r->value_off, r->value_len);
193
+ v.len = r->value_len;
194
+ yep_val_slot(c, &v);
195
+ yep_val_put(c, &v);
196
+ continue;
197
+ case YEPTRIS_EV_SCALAR: {
198
+ const char* text = ra + r->value_off;
199
+ uint32_t len = r->value_len;
200
+ int plain = (r->flags & YEPTRIS_EF_IMPLICIT) != 0;
201
+ val_scalar(c, r->tag_id, plain, text, len);
202
+ continue;
203
+ }
204
+ default:
205
+ continue;
206
+ }
207
+ }
208
+ return c->oom ? -1 : 0;
209
+ }
210
+
211
+ static yep_value_ctx* ctx_create(void) {
212
+ return calloc(1, sizeof(yep_value_ctx));
213
+ }
214
+
215
+ void yep_value_ctx_free(yep_value_ctx* c) {
216
+ if (c == NULL) {
217
+ return;
218
+ }
219
+ free(c->vals);
220
+ free(c->arena);
221
+ free(c);
222
+ }
223
+
224
+ static int ctx_finalize(yep_value_ctx* c, yep_value_ctx** out) {
225
+ if (c->oom) {
226
+ yep_value_ctx_free(c);
227
+ return -1;
228
+ }
229
+ if (c->arena == NULL) {
230
+ c->arena = malloc(1); /* non-NULL so hosts can free blindly */
231
+ if (c->arena == NULL) {
232
+ yep_value_ctx_free(c);
233
+ return -1;
234
+ }
235
+ }
236
+ *out = c;
237
+ return 0;
238
+ }
239
+
240
+ /* ---- the DOM linearizer (21): preorder walk, same records ---- */
241
+
242
+ static int lin_node(yep_value_ctx* c, const yep_dom* d, uint32_t id);
243
+
244
+ static int lin_children(yep_value_ctx* c, const yep_dom* d, const yep_dnode* n) {
245
+ for (uint32_t cid = n->first_child; cid != UINT32_MAX; cid = d->nodes[cid].next_sibling) {
246
+ if (lin_node(c, d, cid) != 0) {
247
+ return -1;
248
+ }
249
+ }
250
+ return 0;
251
+ }
252
+
253
+ static int lin_node(yep_value_ctx* c, const yep_dom* d, uint32_t id) {
254
+ const yep_dnode* n = yep_dom_node(d, id);
255
+ if (n == NULL) {
256
+ return -1;
257
+ }
258
+ if (n->anchor.len != 0 && n->kind != YEP_DOM_ALIAS) {
259
+ yep_view a = yep_dom_view(d, n->anchor);
260
+ anchor_entry(c, a.p, (uint32_t)a.len);
261
+ }
262
+ YeptrisValue v = {0, 0, 0, 0, 0, 0, 0};
263
+ switch (n->kind) {
264
+ case YEP_DOM_SCALAR: {
265
+ yep_view s = yep_dom_view(d, n->value);
266
+ val_scalar(c, n->tag_id, n->implicit, s.p, (uint32_t)s.len);
267
+ return 0;
268
+ }
269
+ case YEP_DOM_ALIAS: {
270
+ yep_view s = yep_dom_view(d, n->value);
271
+ v.kind = YEP_V_ALIAS;
272
+ v.off = yep_val_arena_put(c, s.p, (uint32_t)s.len);
273
+ v.len = (uint32_t)s.len;
274
+ yep_val_slot(c, &v);
275
+ yep_val_put(c, &v);
276
+ return 0;
277
+ }
278
+ default:
279
+ break;
280
+ }
281
+ v.kind = n->kind == YEP_DOM_SEQUENCE ? YEP_V_SEQ_OPEN : YEP_V_MAP_OPEN;
282
+ v.tag_id = n->tag_id;
283
+ yep_val_slot(c, &v);
284
+ yep_val_put(c, &v);
285
+ if (c->depth < YEP_V_MAX_DEPTH) {
286
+ c->key_pend[c->depth] = 0;
287
+ }
288
+ c->depth++;
289
+ if (lin_children(c, d, n) != 0) {
290
+ return -1;
291
+ }
292
+ v.kind = YEP_V_CLOSE;
293
+ v.tag_id = 0;
294
+ v.is_key = 0;
295
+ yep_val_put(c, &v);
296
+ c->depth--;
297
+ return 0;
298
+ }
299
+
300
+ int yep_values_from_dom(const yep_dom* d, uint32_t root_id, int with_doc, yep_value_ctx** out) {
301
+ *out = NULL;
302
+ if (d == NULL) {
303
+ return -1;
304
+ }
305
+ yep_value_ctx* c = ctx_create();
306
+ if (c == NULL) {
307
+ return -1;
308
+ }
309
+ if (with_doc) {
310
+ YeptrisValue dv = {YEP_V_DOC, 0, 0, 0, 0, 0, 0};
311
+ yep_val_put(c, &dv);
312
+ }
313
+ if (root_id != UINT32_MAX && lin_node(c, d, root_id) != 0) {
314
+ yep_value_ctx_free(c);
315
+ return -1;
316
+ }
317
+ return ctx_finalize(c, out);
318
+ }
319
+
320
+ /* ---- the input entry: strict-JSON sniff, else the engine ---- */
321
+
322
+ static int looks_strict_json(const char* p, size_t len) {
323
+ for (size_t i = 0; i < len; i++) {
324
+ char ch = p[i];
325
+ if (ch == '{' || ch == '[') {
326
+ return 1;
327
+ }
328
+ if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') {
329
+ continue;
330
+ }
331
+ return 0;
332
+ }
333
+ return 0;
334
+ }
335
+
336
+ /* JSON route: validate + direct build + linearize. Returns 0 taken,
337
+ * 1 not applicable (grammar surprise — engine decides), -1 fatal. */
338
+ static int drain_json_route(const char* yaml, size_t len, yep_value_ctx** out) {
339
+ size_t verr = 0;
340
+ if (!yep_json_document(yaml, len, &verr)) {
341
+ return 1; /* not strict JSON: YAML flow, tags, or junk — engine */
342
+ }
343
+ const yep_allocator* sys = yep_system_allocator();
344
+ yep_dom* dom = yep_dom_create(sys);
345
+ if (dom == NULL) {
346
+ return -1;
347
+ }
348
+ dom->input_base = yaml; /* strict JSON is UTF-8 by definition */
349
+ dom->input_len = len;
350
+ yep_dom_prepare_len(dom, len);
351
+ int rc = yep_dom_build_json(dom, yaml, len);
352
+ if (rc != 0) {
353
+ /* builder/validator disagreement: belt and braces, engine wins */
354
+ yep_dom_destroy(dom);
355
+ return rc == -1 ? -1 : 1;
356
+ }
357
+ yep_value_ctx* c = ctx_create();
358
+ if (c == NULL) {
359
+ yep_dom_destroy(dom);
360
+ return -1;
361
+ }
362
+ int bad = 0;
363
+ for (uint32_t i = 0; i < dom->dcount && !bad; i++) {
364
+ YeptrisValue dv = {YEP_V_DOC, 0, 0, 0, 0, 0, 0};
365
+ yep_val_put(c, &dv);
366
+ bad = lin_node(c, dom, dom->docs[i]) != 0;
367
+ }
368
+ yep_dom_destroy(dom);
369
+ if (bad) {
370
+ yep_value_ctx_free(c);
371
+ return -1;
372
+ }
373
+ return ctx_finalize(c, out) == 0 ? 0 : -1;
374
+ }
375
+
376
+ /* Shared core of both drain flavors and the Marshal input path: one
377
+ * record array + arena, ownership moves to the caller. */
378
+ int yep_values_from_input(const char* yaml, size_t len, int schema_compat, yep_value_ctx** out) {
379
+ *out = NULL;
380
+ if (looks_strict_json(yaml, len)) {
381
+ int jrc = drain_json_route(yaml, len, out);
382
+ if (jrc <= 0) {
383
+ return jrc == 0 ? 0 : -1;
384
+ }
385
+ /* fall through: engine */
386
+ }
387
+ yep_engine* eng = yep_engine_create(yep_system_allocator());
388
+ if (eng == NULL) {
389
+ return -1;
390
+ }
391
+ yep_engine_set_resolver(eng, schema_compat ? yep_resolver_compat11() : yep_resolver_core12());
392
+
393
+ yep_value_ctx* c = ctx_create();
394
+ if (c == NULL) {
395
+ yep_engine_destroy(eng);
396
+ return -1;
397
+ }
398
+ yep_rec_store store;
399
+ yep_rec_init(&store);
400
+
401
+ int prc = -2;
402
+ yep_sink sink = {.on_event = yep_rec_on_event,
403
+ .ctx = &store,
404
+ .on_flow_build = NULL,
405
+ .on_flow_commit = NULL,
406
+ .on_flow_rollback = NULL,
407
+ .on_block_pair = NULL,
408
+ .on_block_open = NULL,
409
+ .on_block_item = NULL};
410
+ /* strict JSON carries no anchors: no nametab reserve needed */
411
+ if (yep_engine_run(eng, yaml, len, &sink) == 0 && transform(c, &store) == 0) {
412
+ prc = 0;
413
+ } else if (c->oom) {
414
+ prc = -1;
415
+ }
416
+ yep_engine_destroy(eng);
417
+ yep_rec_free(&store);
418
+ if (prc != 0) {
419
+ yep_value_ctx_free(c);
420
+ return prc == -1 ? -1 : -2;
421
+ }
422
+ return ctx_finalize(c, out) == 0 ? 0 : -1;
423
+ }
424
+
425
+ static YeptrisStatus map_status(int rc) {
426
+ return rc == 0 ? YEPTRIS_OK : (rc == -1 ? YEPTRIS_ERROR_MEMORY : YEPTRIS_ERROR_PARSE);
427
+ }
428
+
429
+ YEPTRIS_API YeptrisStatus yeptris_value_drain(const char* yaml, size_t len, YeptrisSchema schema,
430
+ YeptrisValue** vals, size_t* count, char** arena,
431
+ size_t* arena_len) {
432
+ if (vals == NULL || count == NULL || arena == NULL || arena_len == NULL ||
433
+ (yaml == NULL && len != 0)) {
434
+ return YEPTRIS_ERROR_ARG;
435
+ }
436
+ *vals = NULL;
437
+ *count = 0;
438
+ *arena = NULL;
439
+ *arena_len = 0;
440
+ yep_value_ctx* c = NULL;
441
+ int rc = yep_values_from_input(yaml, len, schema == YEPTRIS_SCHEMA_11_COMPAT, &c);
442
+ if (rc != 0) {
443
+ return map_status(rc);
444
+ }
445
+ *vals = c->vals;
446
+ *count = c->n;
447
+ *arena = c->arena;
448
+ *arena_len = c->arena_len;
449
+ free(c);
450
+ return YEPTRIS_OK;
451
+ }
452
+
453
+ YEPTRIS_API void yeptris_value_free(YeptrisValue* vals, char* arena) {
454
+ free(vals);
455
+ free(arena);
456
+ }
457
+
458
+ YEPTRIS_API YeptrisStatus yeptris_value_drain_columns(const char* yaml, size_t len,
459
+ YeptrisSchema schema,
460
+ YeptrisValueColumns* cols) {
461
+ if (cols == NULL || (yaml == NULL && len != 0)) {
462
+ return YEPTRIS_ERROR_ARG;
463
+ }
464
+ memset(cols, 0, sizeof(*cols));
465
+ yep_value_ctx* c = NULL;
466
+ int rc = yep_values_from_input(yaml, len, schema == YEPTRIS_SCHEMA_11_COMPAT, &c);
467
+ if (rc != 0) {
468
+ return map_status(rc);
469
+ }
470
+ size_t n = c->n;
471
+ /* one carved block, widest-first so every column is naturally
472
+ * aligned: payloads(8n) offs(4n) lens(4n) kinds tags is_keys bools */
473
+ size_t total = n * (8 + 4 + 4 + 1 + 1 + 1 + 1);
474
+ int64_t* block = NULL;
475
+ if (n > 0) {
476
+ block = malloc(total);
477
+ if (block == NULL) {
478
+ yep_value_ctx_free(c);
479
+ return YEPTRIS_ERROR_MEMORY;
480
+ }
481
+ }
482
+ cols->count = n;
483
+ cols->arena_len = c->arena_len;
484
+ cols->arena = c->arena;
485
+ /* a zero-entry drain keeps every column NULL (pointer arithmetic
486
+ * on a null block is UB — caught by UBSan on the empty stream) */
487
+ if (block != NULL) {
488
+ cols->payloads = block;
489
+ cols->offs = (uint32_t*)(block + n);
490
+ cols->lens = cols->offs + n;
491
+ cols->kinds = (uint8_t*)(cols->lens + n);
492
+ cols->tags = cols->kinds + n;
493
+ cols->is_keys = cols->tags + n;
494
+ cols->bools = cols->is_keys + n;
495
+ }
496
+ for (size_t i = 0; i < n; i++) {
497
+ const YeptrisValue* v = &c->vals[i];
498
+ cols->payloads[i] = (int64_t)v->p;
499
+ cols->offs[i] = v->off;
500
+ cols->lens[i] = v->len;
501
+ cols->kinds[i] = v->kind;
502
+ cols->tags[i] = v->tag_id;
503
+ cols->is_keys[i] = v->is_key;
504
+ cols->bools[i] = v->b;
505
+ }
506
+ free(c->vals);
507
+ free(c);
508
+ return YEPTRIS_OK;
509
+ }
510
+
511
+ YEPTRIS_API void yeptris_value_free_columns(YeptrisValueColumns* cols) {
512
+ if (cols == NULL) {
513
+ return;
514
+ }
515
+ free(cols->payloads); /* the carved block base */
516
+ free(cols->arena);
517
+ cols->payloads = NULL;
518
+ cols->offs = NULL;
519
+ cols->lens = NULL;
520
+ cols->kinds = NULL;
521
+ cols->tags = NULL;
522
+ cols->is_keys = NULL;
523
+ cols->bools = NULL;
524
+ cols->arena = NULL;
525
+ cols->count = 0;
526
+ cols->arena_len = 0;
527
+ }
@@ -0,0 +1,51 @@
1
+ /* values_priv.h — the record-building machinery, shared with the
2
+ * Marshal emitter (TODO.restructure/21).
3
+ *
4
+ * The value stream's SSOT lives in values.c; marshal.c consumes the
5
+ * SAME ctx (records + arena) the drains produce, and the DOM
6
+ * linearizer produces the same records the engine transform does, so
7
+ * every route through the value format is byte-identical.
8
+ */
9
+ #ifndef YEP_EVENTS_VALUES_PRIV_H
10
+ #define YEP_EVENTS_VALUES_PRIV_H
11
+
12
+ #include "../../include/yeptris/values.h"
13
+
14
+ struct yep_dom;
15
+
16
+ #define YEP_V_MAX_DEPTH 1024
17
+
18
+ typedef struct yep_value_ctx {
19
+ /* records + arena as handed to hosts by the public drains */
20
+ YeptrisValue* vals;
21
+ size_t n, cap;
22
+ char* arena;
23
+ size_t arena_len, arena_cap;
24
+ int oom;
25
+ int unsupported; /* linearize: construct the emitter cannot express */
26
+ uint8_t key_pend[YEP_V_MAX_DEPTH]; /* per open map: key slot taken */
27
+ int depth;
28
+ } yep_value_ctx;
29
+
30
+ /* values.c owns these; declared here for marshal.c and the linearizer. */
31
+ void yep_val_put(yep_value_ctx* c, const YeptrisValue* v);
32
+ uint32_t yep_val_arena_put(yep_value_ctx* c, const char* p, uint32_t len);
33
+ void yep_val_slot(yep_value_ctx* c, YeptrisValue* v);
34
+
35
+ /* engine route — now with the strict-JSON sniff: first non-space
36
+ * byte '{'/'[' builds through the JSON scanner and the linearizer,
37
+ * falling back to the engine on any grammar failure. Both routes
38
+ * produce identical records (the differential gate). Returns 0 ok,
39
+ * -1 oom, -2 parse (detail via the TLS error channel). */
40
+ int yep_values_from_input(const char* yaml, size_t len, int schema_compat, yep_value_ctx** out);
41
+
42
+ /* DOM route: preorder walk of a subtree producing the same records
43
+ * the engine transform produces (21's linearizer). root_id may be
44
+ * UINT32_MAX for an empty document; with_doc emits YEP_V_DOC records
45
+ * around the root (the input path always documents). */
46
+ int yep_values_from_dom(const struct yep_dom* d, uint32_t root_id, int with_doc,
47
+ yep_value_ctx** out);
48
+
49
+ void yep_value_ctx_free(yep_value_ctx* c); /* frees records, arena, ctx */
50
+
51
+ #endif /* YEP_EVENTS_VALUES_PRIV_H */
@@ -0,0 +1,86 @@
1
+ /* yaml_compat.c — engine events → libyaml event shape (TODO.impl/12C).
2
+ *
3
+ * The implicit-flag mapping mirrors what libyaml's own parser emits:
4
+ * a scalar without a tag carries plain_implicit (plain) or
5
+ * quoted_implicit (quoted); a collection without a tag is implicit.
6
+ */
7
+
8
+ #include "events/yaml_compat.h"
9
+
10
+ #include <string.h>
11
+
12
+ int yep_ly_translate(yep_ly_event* out, const yep_event* in) {
13
+ if (out == NULL || in == NULL) {
14
+ return -1;
15
+ }
16
+ memset(out, 0, sizeof(*out));
17
+ out->start_mark.line = in->line > 0 ? (size_t)in->line - 1 : 0;
18
+ out->start_mark.column = in->col > 0 ? (size_t)in->col - 1 : 0;
19
+ out->end_mark = out->start_mark;
20
+
21
+ switch (in->type) {
22
+ case YEP_EV_STREAM_START:
23
+ out->type = YEP_LY_STREAM_START_EVENT;
24
+ out->encoding = 1; /* UTF8 */
25
+ return 0;
26
+ case YEP_EV_STREAM_END:
27
+ out->type = YEP_LY_STREAM_END_EVENT;
28
+ return 0;
29
+ case YEP_EV_DOCUMENT_START:
30
+ out->type = YEP_LY_DOCUMENT_START_EVENT;
31
+ out->implicit = (in->style != 1); /* style 1 = explicit "---" */
32
+ return 0;
33
+ case YEP_EV_DOCUMENT_END:
34
+ out->type = YEP_LY_DOCUMENT_END_EVENT;
35
+ out->implicit = (in->style != 1); /* style 1 = explicit "..." */
36
+ return 0;
37
+ case YEP_EV_ALIAS:
38
+ out->type = YEP_LY_ALIAS_EVENT;
39
+ out->anchor = (const char*)in->value.p;
40
+ out->anchor_len = in->value.len;
41
+ return 0;
42
+ case YEP_EV_SCALAR:
43
+ out->type = YEP_LY_SCALAR_EVENT;
44
+ out->anchor = (const char*)in->anchor.p;
45
+ out->anchor_len = in->anchor.len;
46
+ out->tag = (const char*)in->tag.p;
47
+ out->tag_len = in->tag.len;
48
+ out->value = (const char*)in->value.p;
49
+ out->value_len = in->value.len;
50
+ out->style = in->style; /* YEP style values match libyaml's */
51
+ if (in->tag.len == 0) {
52
+ if (in->style == YEP_STYLE_PLAIN) {
53
+ out->plain_implicit = 1;
54
+ } else {
55
+ out->quoted_implicit = 1;
56
+ }
57
+ }
58
+ return 0;
59
+ case YEP_EV_SEQ_START:
60
+ out->type = YEP_LY_SEQUENCE_START_EVENT;
61
+ out->anchor = (const char*)in->anchor.p;
62
+ out->anchor_len = in->anchor.len;
63
+ out->tag = (const char*)in->tag.p;
64
+ out->tag_len = in->tag.len;
65
+ out->implicit = (in->tag.len == 0);
66
+ out->style = in->flow ? YEP_LY_FLOW_STYLE : YEP_LY_BLOCK_STYLE;
67
+ return 0;
68
+ case YEP_EV_SEQ_END:
69
+ out->type = YEP_LY_SEQUENCE_END_EVENT;
70
+ return 0;
71
+ case YEP_EV_MAP_START:
72
+ out->type = YEP_LY_MAPPING_START_EVENT;
73
+ out->anchor = (const char*)in->anchor.p;
74
+ out->anchor_len = in->anchor.len;
75
+ out->tag = (const char*)in->tag.p;
76
+ out->tag_len = in->tag.len;
77
+ out->implicit = (in->tag.len == 0);
78
+ out->style = in->flow ? YEP_LY_FLOW_STYLE : YEP_LY_BLOCK_STYLE;
79
+ return 0;
80
+ case YEP_EV_MAP_END:
81
+ out->type = YEP_LY_MAPPING_END_EVENT;
82
+ return 0;
83
+ default:
84
+ return -1;
85
+ }
86
+ }