yeptris 0.6.57.1-arm-linux-eabihf → 0.6.59.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/ext/yeptris_native/version.h +2 -2
- data/lib/yeptris/3.4/native.so +0 -0
- data/lib/yeptris/document.rb +15 -0
- data/lib/yeptris/ffi.rb +93 -0
- data/lib/yeptris/psych/visitors.rb +16 -6
- data/lib/yeptris/psych.rb +11 -5
- data/lib/yeptris/validation.rb +320 -0
- data/lib/yeptris/yaml.rb +67 -6
- data/lib/yeptris.rb +2 -1
- data/libyeptris.so +0 -0
- data/vendor/libyeptris/CMakeLists.txt +1 -1
- data/vendor/libyeptris/src/CMakeLists.txt +6 -0
- data/vendor/libyeptris/src/include/yeptris/error.h +2 -1
- data/vendor/libyeptris/src/include/yeptris/resolve.h +3 -1
- data/vendor/libyeptris/src/include/yeptris/validate.h +200 -0
- data/vendor/libyeptris/src/include/yeptris.h +1 -0
- data/vendor/libyeptris/src/yeptris/parse.c +24 -10
- data/vendor/libyeptris/src/yeptris/resolve/json12.c +103 -0
- data/vendor/libyeptris/src/yeptris/resolve/resolver.h +9 -0
- data/vendor/libyeptris/src/yeptris/validate/compile.c +270 -0
- data/vendor/libyeptris/src/yeptris/validate/internal.h +131 -0
- data/vendor/libyeptris/src/yeptris/validate/jsonschema.c +1392 -0
- data/vendor/libyeptris/src/yeptris/validate/regexp.c +1134 -0
- data/vendor/libyeptris/src/yeptris/validate/validate.c +900 -0
- metadata +9 -1
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/* compile.c — the compiled-schema economy (#885 item 3).
|
|
2
|
+
*
|
|
3
|
+
* The leptris-XSD shape (~/src/leptris/leptris/src/leptris/xsd/):
|
|
4
|
+
* parse the schema ONCE, retain the DOM and the derived state, validate
|
|
5
|
+
* many instance streams against the retained model. The handle owns
|
|
6
|
+
* everything it reads — the schema bytes (copied: the DOM's scalar
|
|
7
|
+
* views borrow them), the parsed document (its DOM, pools and finish
|
|
8
|
+
* pool die with yeptris_document_free), and the compiled pattern
|
|
9
|
+
* programs (the XSD content-model analog: `(a+)+$` compiles once at
|
|
10
|
+
* compile time, not once per validated string). One free call releases
|
|
11
|
+
* it all — no refcounting, the document-ownership law.
|
|
12
|
+
*
|
|
13
|
+
* The pattern programs are populated EAGERLY by a DFS over the schema
|
|
14
|
+
* tree (`pattern` values and `patternProperties` keys — the kernel's
|
|
15
|
+
* only two consumers), so the handle is immutable after compile and
|
|
16
|
+
* `yeptris_schema_validate` is a pure reader: one schema handle per
|
|
17
|
+
* thread like documents; read-only sharing across threads is safe.
|
|
18
|
+
* An invalid pattern is simply not retained — every use then recompiles
|
|
19
|
+
* to the one-shot's -1 (ignored keyword), never a guess.
|
|
20
|
+
*
|
|
21
|
+
* The one-shot face (yeptris_json_schema_validate) routes through the
|
|
22
|
+
* same compile+validate machinery internally: identical parse, walk
|
|
23
|
+
* and report code paths, so its observable statuses and byte-for-byte
|
|
24
|
+
* verdicts are preserved (the 1298-case suite port is the referee).
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
#include <string.h>
|
|
28
|
+
|
|
29
|
+
#include <yeptris/dom.h>
|
|
30
|
+
#include <yeptris/validate.h>
|
|
31
|
+
|
|
32
|
+
#include "../common/error.h"
|
|
33
|
+
#include "../doc.h"
|
|
34
|
+
#include "../memory/allocator.h"
|
|
35
|
+
#include "../tape_in.h"
|
|
36
|
+
#include "internal.h"
|
|
37
|
+
|
|
38
|
+
/* The compiled schema. Opaque at the face (validate.h); everything it
|
|
39
|
+
* reads dies with it. */
|
|
40
|
+
struct yeptris_schema {
|
|
41
|
+
char* bytes; /* owned: the schema bytes (the DOM's input views borrow them) */
|
|
42
|
+
yeptris_document* doc; /* owned: the parsed schema document */
|
|
43
|
+
const yep_dom* dom; /* borrowed from doc (yep_doc_dom) */
|
|
44
|
+
uint32_t sroot; /* the schema document's root (docs[0]) */
|
|
45
|
+
yep_re_cache* cache; /* owned: pattern source -> compiled NFA; immutable after compile */
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/* ---- the pattern collection (compile-time, eager) ----------------------- */
|
|
49
|
+
|
|
50
|
+
static int collect_patterns(yep_re_cache* t, const yep_dom* d, uint32_t id, int depth);
|
|
51
|
+
|
|
52
|
+
/* Collects every pattern source of one mapping pair set. 0 ok, -1 OOM. */
|
|
53
|
+
static int collect_map(yep_re_cache* t, const yep_dom* d, uint32_t map_id, int depth) {
|
|
54
|
+
const yep_dnode* m = yep_dom_node(d, map_id);
|
|
55
|
+
uint32_t k = m->first_child;
|
|
56
|
+
while (k != UINT32_MAX) {
|
|
57
|
+
uint32_t v = yep_dom_node(d, k) ? yep_dom_node(d, k)->next_sibling : UINT32_MAX;
|
|
58
|
+
const yep_dnode* kn = yep_dom_node(d, k);
|
|
59
|
+
const yep_dnode* vn = v != UINT32_MAX ? yep_dom_node(d, v) : NULL;
|
|
60
|
+
if (kn != NULL && kn->kind == YEP_DOM_SCALAR) {
|
|
61
|
+
yep_view kv = yep_dom_view(d, kn->value);
|
|
62
|
+
/* the keyword names, matched by bytes like the walk's kw_get */
|
|
63
|
+
if (kv.len == 7 && memcmp(kv.p, "pattern", 7) == 0) {
|
|
64
|
+
/* "pattern": the value is the pattern source (a string
|
|
65
|
+
* scalar, schema_word's exact read) */
|
|
66
|
+
if (vn != NULL && vn->kind == YEP_DOM_SCALAR &&
|
|
67
|
+
yep_validate_scalar_tag(vn) == YEPTRIS_TAG_STR) {
|
|
68
|
+
yep_view vv = yep_dom_view(d, vn->value);
|
|
69
|
+
if (vv.p != NULL && yep_re_cache_add(t, vv.p, vv.len) < 0) {
|
|
70
|
+
return -1;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
} else if (kv.len == 17 && memcmp(kv.p, "patternProperties", 17) == 0) {
|
|
74
|
+
/* "patternProperties": its KEYS are the pattern sources */
|
|
75
|
+
if (vn != NULL && vn->kind == YEP_DOM_MAPPING) {
|
|
76
|
+
uint32_t pk = vn->first_child;
|
|
77
|
+
while (pk != UINT32_MAX) {
|
|
78
|
+
uint32_t pv =
|
|
79
|
+
yep_dom_node(d, pk) ? yep_dom_node(d, pk)->next_sibling : UINT32_MAX;
|
|
80
|
+
const yep_dnode* pkn = yep_dom_node(d, pk);
|
|
81
|
+
if (pkn != NULL && pkn->kind == YEP_DOM_SCALAR &&
|
|
82
|
+
yep_validate_scalar_tag(pkn) == YEPTRIS_TAG_STR) {
|
|
83
|
+
yep_view pw = yep_dom_view(d, pkn->value);
|
|
84
|
+
if (pw.p != NULL && yep_re_cache_add(t, pw.p, pw.len) < 0) {
|
|
85
|
+
return -1;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
pk = pv;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/* the rest of the schema rides the values (keys are scalars —
|
|
94
|
+
* nothing under them; the walk reaches nodes the same way) */
|
|
95
|
+
if (v != UINT32_MAX && collect_patterns(t, d, v, depth + 1) != 0) {
|
|
96
|
+
return -1;
|
|
97
|
+
}
|
|
98
|
+
k = v != UINT32_MAX && yep_dom_node(d, v) ? yep_dom_node(d, v)->next_sibling : UINT32_MAX;
|
|
99
|
+
}
|
|
100
|
+
return 0;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* Depth-bounded DFS gathering every pattern the walk can reach. 0 ok,
|
|
104
|
+
* -1 OOM. Aliases are skipped: the walk sees an alias node as opaque
|
|
105
|
+
* (never a mapping), so no reachable pattern hides behind one. */
|
|
106
|
+
static int collect_patterns(yep_re_cache* t, const yep_dom* d, uint32_t id, int depth) {
|
|
107
|
+
if (depth > YEP_DOM_MAX_DEPTH) {
|
|
108
|
+
return 0; /* the walk's own guard: deeper nodes are unreachable to it too */
|
|
109
|
+
}
|
|
110
|
+
const yep_dnode* n = yep_dom_node(d, id);
|
|
111
|
+
if (n == NULL) {
|
|
112
|
+
return 0;
|
|
113
|
+
}
|
|
114
|
+
if (n->kind == YEP_DOM_MAPPING) {
|
|
115
|
+
return collect_map(t, d, id, depth);
|
|
116
|
+
}
|
|
117
|
+
if (n->kind == YEP_DOM_SEQUENCE) {
|
|
118
|
+
uint32_t ch = n->first_child;
|
|
119
|
+
while (ch != UINT32_MAX) {
|
|
120
|
+
uint32_t next = yep_dom_node(d, ch) ? yep_dom_node(d, ch)->next_sibling : UINT32_MAX;
|
|
121
|
+
if (collect_patterns(t, d, ch, depth + 1) != 0) {
|
|
122
|
+
return -1;
|
|
123
|
+
}
|
|
124
|
+
ch = next;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return 0;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/* ---- the seam with the explicit status (internal.h) --------------------- */
|
|
131
|
+
|
|
132
|
+
yeptris_schema* yep_schema_compile_st(const char* bytes, size_t n, YeptrisStatus* st) {
|
|
133
|
+
*st = YEPTRIS_OK;
|
|
134
|
+
if (bytes == NULL && n != 0) {
|
|
135
|
+
*st = YEPTRIS_ERROR_ARG;
|
|
136
|
+
return NULL;
|
|
137
|
+
}
|
|
138
|
+
const yep_allocator* sys = yep_system_allocator();
|
|
139
|
+
|
|
140
|
+
/* the schema bytes are COPIED: the DOM's scalar views borrow its
|
|
141
|
+
* input, and the handle outlives this call */
|
|
142
|
+
char* copy = NULL;
|
|
143
|
+
if (n > 0) {
|
|
144
|
+
copy = yep_alloc(sys, n);
|
|
145
|
+
if (copy == NULL) {
|
|
146
|
+
*st = YEPTRIS_ERROR_MEMORY;
|
|
147
|
+
return NULL;
|
|
148
|
+
}
|
|
149
|
+
memcpy(copy, bytes, n);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/* document 0 of the stream is the schema (the one-shot's exact rule) */
|
|
153
|
+
YeptrisParseOptions opts;
|
|
154
|
+
memset(&opts, 0, sizeof(opts)); /* core12: the YAML->JSON data model */
|
|
155
|
+
YeptrisStatus ps = YEPTRIS_OK;
|
|
156
|
+
yeptris_document* doc = (yeptris_document*)yeptris_parse_eager_ex(copy, n, &opts, &ps);
|
|
157
|
+
if (doc == NULL) {
|
|
158
|
+
yep_free(sys, copy);
|
|
159
|
+
if (ps == YEPTRIS_OK) { /* empty bytes: the stream holds no document */
|
|
160
|
+
yep_error_set(yep_error_tls(), YEP_ERR_UNEXPECTED, 0, 0, 0,
|
|
161
|
+
"the schema bytes hold no document");
|
|
162
|
+
*st = YEPTRIS_ERROR_ARG;
|
|
163
|
+
} else {
|
|
164
|
+
*st = ps; /* the schema did not parse — the engine's own status */
|
|
165
|
+
}
|
|
166
|
+
return NULL;
|
|
167
|
+
}
|
|
168
|
+
const yep_dom* dom = yep_doc_dom(doc);
|
|
169
|
+
if (dom == NULL || dom->dcount == 0) {
|
|
170
|
+
yeptris_document_free(doc);
|
|
171
|
+
yep_free(sys, copy);
|
|
172
|
+
yep_error_set(yep_error_tls(), YEP_ERR_UNEXPECTED, 0, 0, 0,
|
|
173
|
+
"the schema bytes hold no document");
|
|
174
|
+
*st = YEPTRIS_ERROR_ARG;
|
|
175
|
+
return NULL;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/* the pattern programs: compiled once, here (a failure to retain is
|
|
179
|
+
* an allocation failure — loud, like every constructor's OOM) */
|
|
180
|
+
yep_re_cache* cache = yep_re_cache_new();
|
|
181
|
+
if (cache == NULL || collect_patterns(cache, dom, dom->docs[0], 0) != 0) {
|
|
182
|
+
yep_re_cache_free(cache);
|
|
183
|
+
yeptris_document_free(doc);
|
|
184
|
+
yep_free(sys, copy);
|
|
185
|
+
yep_error_set(yep_error_tls(), YEP_ERR_MEMORY, 0, 0, 0,
|
|
186
|
+
"the schema's pattern programs failed to compile");
|
|
187
|
+
*st = YEPTRIS_ERROR_MEMORY;
|
|
188
|
+
return NULL;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
yeptris_schema* s = yep_alloc(sys, sizeof(*s));
|
|
192
|
+
if (s == NULL) {
|
|
193
|
+
yep_re_cache_free(cache);
|
|
194
|
+
yeptris_document_free(doc);
|
|
195
|
+
yep_free(sys, copy);
|
|
196
|
+
*st = YEPTRIS_ERROR_MEMORY;
|
|
197
|
+
return NULL;
|
|
198
|
+
}
|
|
199
|
+
s->bytes = copy;
|
|
200
|
+
s->doc = doc;
|
|
201
|
+
s->dom = dom;
|
|
202
|
+
s->sroot = dom->docs[0];
|
|
203
|
+
s->cache = cache;
|
|
204
|
+
return s;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/* ---- the public face (validate.h) --------------------------------------- */
|
|
208
|
+
|
|
209
|
+
YEPTRIS_API yeptris_schema* yeptris_schema_compile(const char* bytes, size_t n) {
|
|
210
|
+
YeptrisStatus st = YEPTRIS_OK;
|
|
211
|
+
return yep_schema_compile_st(bytes, n, &st); /* the error channel carries the why */
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
YEPTRIS_API void yeptris_schema_free(yeptris_schema* s) {
|
|
215
|
+
if (s == NULL) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
const yep_allocator* sys = yep_system_allocator();
|
|
219
|
+
yep_re_cache_free(s->cache);
|
|
220
|
+
yeptris_document_free(s->doc); /* the DOM and every pool under it */
|
|
221
|
+
yep_free(sys, s->bytes); /* the views' home: freed after its readers */
|
|
222
|
+
yep_free(sys, s);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
YEPTRIS_API YeptrisStatus yeptris_schema_validate(yeptris_schema* s, const char* buf, size_t len,
|
|
226
|
+
yeptris_validate_report** out) {
|
|
227
|
+
if (out == NULL || s == NULL || (buf == NULL && len != 0)) {
|
|
228
|
+
return YEPTRIS_ERROR_ARG;
|
|
229
|
+
}
|
|
230
|
+
*out = NULL;
|
|
231
|
+
|
|
232
|
+
/* the instance stream (core12, the one-shot's exact parse) */
|
|
233
|
+
YeptrisParseOptions opts;
|
|
234
|
+
memset(&opts, 0, sizeof(opts));
|
|
235
|
+
YeptrisStatus st = YEPTRIS_OK;
|
|
236
|
+
YeptrisDocument idoc = yeptris_parse_eager_ex(buf, len, &opts, &st);
|
|
237
|
+
if (idoc == NULL) {
|
|
238
|
+
if (st == YEPTRIS_OK) {
|
|
239
|
+
/* an empty instance stream: nothing to invalidate */
|
|
240
|
+
yeptris_validate_report* r = yep_validate_report_new();
|
|
241
|
+
if (r == NULL) {
|
|
242
|
+
return YEPTRIS_ERROR_MEMORY;
|
|
243
|
+
}
|
|
244
|
+
*out = r;
|
|
245
|
+
return YEPTRIS_OK;
|
|
246
|
+
}
|
|
247
|
+
return st; /* the parse's own error */
|
|
248
|
+
}
|
|
249
|
+
yep_dom* idom = yep_doc_dom((yeptris_document*)idoc);
|
|
250
|
+
if (idom == NULL) {
|
|
251
|
+
yeptris_document_free(idoc);
|
|
252
|
+
return YEPTRIS_ERROR_MEMORY;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
yeptris_validate_report* r = yep_validate_report_new();
|
|
256
|
+
if (r == NULL) {
|
|
257
|
+
yeptris_document_free(idoc);
|
|
258
|
+
return YEPTRIS_ERROR_MEMORY;
|
|
259
|
+
}
|
|
260
|
+
/* the handle is a pure reader here (its cache is immutable): the
|
|
261
|
+
* same walk, the same report shape, the one-shot's verdicts */
|
|
262
|
+
int rc = yep_jsonschema_run(s->dom, s->sroot, idom, idom->docs, idom->dcount, r, s->cache);
|
|
263
|
+
yeptris_document_free(idoc);
|
|
264
|
+
if (rc != 0) {
|
|
265
|
+
yeptris_validate_report_free(r);
|
|
266
|
+
return YEPTRIS_ERROR_MEMORY;
|
|
267
|
+
}
|
|
268
|
+
*out = r;
|
|
269
|
+
return r->count > 0 ? YEPTRIS_ERROR_SCHEMA : YEPTRIS_OK;
|
|
270
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/* validate/internal.h — the validation face's shared internals (#882).
|
|
2
|
+
*
|
|
3
|
+
* Private to src/yeptris/validate/: the report shape, the diagnostic
|
|
4
|
+
* emitter (path capture + line/col resolution), and the JSON-pointer
|
|
5
|
+
* scratch path. The two walks (validate.c's schema family and
|
|
6
|
+
* jsonschema.c's keyword subset) share only this — MECE keeps the
|
|
7
|
+
* checks themselves in their own TUs.
|
|
8
|
+
*/
|
|
9
|
+
#ifndef YEP_VALIDATE_INTERNAL_H
|
|
10
|
+
#define YEP_VALIDATE_INTERNAL_H
|
|
11
|
+
|
|
12
|
+
#include <stdarg.h>
|
|
13
|
+
#include <stddef.h>
|
|
14
|
+
#include <stdint.h>
|
|
15
|
+
|
|
16
|
+
#include <yeptris/validate.h>
|
|
17
|
+
|
|
18
|
+
#include "../dom/dom.h"
|
|
19
|
+
|
|
20
|
+
#ifdef __cplusplus
|
|
21
|
+
extern "C" {
|
|
22
|
+
#endif
|
|
23
|
+
|
|
24
|
+
/* The report cap: a hostile document can carry O(nodes) violations, so
|
|
25
|
+
* the walk stops here and the LIMIT sentinel replaces the last slot. */
|
|
26
|
+
#define YEP_VALIDATE_MAX_DIAGS 256
|
|
27
|
+
|
|
28
|
+
struct yeptris_validate_report {
|
|
29
|
+
yeptris_diagnostic* diags;
|
|
30
|
+
uint32_t count;
|
|
31
|
+
int truncated;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
typedef struct yep_vctx {
|
|
35
|
+
const yep_dom* dom;
|
|
36
|
+
yeptris_validate_report* rep;
|
|
37
|
+
/* line/col resolution over the node bytes (lazy: built on the
|
|
38
|
+
* first positioned diagnostic; valid documents never pay) */
|
|
39
|
+
const char* input;
|
|
40
|
+
size_t input_len;
|
|
41
|
+
uint32_t* line_off; /* byte offset of every line start */
|
|
42
|
+
uint32_t line_cnt, line_cap;
|
|
43
|
+
/* JSON-pointer path under construction (DFS scratch) */
|
|
44
|
+
char* path;
|
|
45
|
+
size_t path_len, path_cap;
|
|
46
|
+
int depth; /* the walk's nesting guard (never exceeds the DOM's) */
|
|
47
|
+
int oom; /* an allocation failed: stop diagnosing */
|
|
48
|
+
/* JSON Schema trial suppression (anyOf/oneOf/not probes) */
|
|
49
|
+
int suppress;
|
|
50
|
+
int trial_hit;
|
|
51
|
+
int ref_depth; /* consecutive $ref expansions */
|
|
52
|
+
} yep_vctx;
|
|
53
|
+
|
|
54
|
+
/* Offset of a node's first positioned byte (the value span of the node
|
|
55
|
+
* itself, or of its first scalar leaf for collections; UINT32_MAX when
|
|
56
|
+
* everything reachable lives in the arena — line/col unknown). */
|
|
57
|
+
uint32_t yep_validate_node_off(const yep_dom* d, uint32_t id);
|
|
58
|
+
|
|
59
|
+
/* Emits one diagnostic at the current path. line/col resolve from
|
|
60
|
+
* `off` through the lazy line index; 0/0 when unknown. Detail is
|
|
61
|
+
* printf-composed into the bounded slot. Never fails the caller: the
|
|
62
|
+
* report cap turns the last slot into the LIMIT sentinel. */
|
|
63
|
+
void yep_validate_emit(yep_vctx* c, int code, uint32_t off, const char* detail_fmt, ...);
|
|
64
|
+
|
|
65
|
+
/* JSON-pointer path scratch: push an escaped segment / a decimal
|
|
66
|
+
* index, pop to a mark. 0 ok, -1 OOM (ctx.oom set; the walk unwinds). */
|
|
67
|
+
int yep_validate_path_push(yep_vctx* c, const char* seg, size_t seg_len);
|
|
68
|
+
int yep_validate_path_push_index(yep_vctx* c, uint32_t idx);
|
|
69
|
+
void yep_validate_path_pop(yep_vctx* c, size_t mark);
|
|
70
|
+
|
|
71
|
+
/* The bounded ECMA-regex subset behind `pattern` (jsonschema.c):
|
|
72
|
+
* literals, '.', classes, groups, alternation, the greedy/lazy
|
|
73
|
+
* quantifiers, anchors, \d\w\s\D\W\S\b\B and \xHH. Byte-oriented
|
|
74
|
+
* (ASCII classes; UTF-8 literals match byte-wise). A Thompson NFA —
|
|
75
|
+
* O(len * m), no backtracking blowup, no recursion over the subject.
|
|
76
|
+
* Patterns over the program budget are invalid. 1 match, 0 no match,
|
|
77
|
+
* -1 invalid pattern. */
|
|
78
|
+
int yep_re_search(const char* pat, uint32_t pat_len, const char* s, uint32_t s_len);
|
|
79
|
+
|
|
80
|
+
/* The retained-program cache behind the compiled schema (#885 item 3):
|
|
81
|
+
* pattern source -> compiled NFA, populated at compile time, immutable
|
|
82
|
+
* afterwards (read-only sharing, the document law). A miss — a NULL
|
|
83
|
+
* cache included — compiles fresh with yep_re_search's exact verdicts;
|
|
84
|
+
* cache_add returns 1 stored, 0 not retained (invalid pattern, empty,
|
|
85
|
+
* table full — misses recompile), -1 allocation failure (loud). */
|
|
86
|
+
typedef struct yep_re_cache yep_re_cache;
|
|
87
|
+
yep_re_cache* yep_re_cache_new(void);
|
|
88
|
+
void yep_re_cache_free(yep_re_cache* t);
|
|
89
|
+
int yep_re_cache_add(yep_re_cache* t, const char* pat, uint32_t plen);
|
|
90
|
+
int yep_re_cache_search(const yep_re_cache* t, const char* pat, uint32_t plen, const char* s,
|
|
91
|
+
uint32_t s_len);
|
|
92
|
+
|
|
93
|
+
/* Canonical scalar tag of a DOM node (explicit tag, then the parse
|
|
94
|
+
* resolver's plain verdict, then str): the value model both walks
|
|
95
|
+
* compare under. */
|
|
96
|
+
uint8_t yep_validate_scalar_tag(const yep_dnode* n);
|
|
97
|
+
|
|
98
|
+
/* Canonical-form hash and equality over DOM subtrees (spec 3.2.1.3:
|
|
99
|
+
* same tag + canonical form; numbers numerically within a tag). The
|
|
100
|
+
* equality may cross documents — the schema's enum/const live in a
|
|
101
|
+
* different DOM than the instance. Depth-bounded. */
|
|
102
|
+
uint64_t yep_validate_node_hash(const yep_dom* d, uint32_t id, int depth);
|
|
103
|
+
int yep_validate_node_equal(const yep_dom* da, uint32_t a, const yep_dom* db, uint32_t b,
|
|
104
|
+
int depth);
|
|
105
|
+
|
|
106
|
+
/* jsonschema.c's driver: applies the schema tree (its own DOM) to
|
|
107
|
+
* every instance document root, emitting into `rep`. `cache` is the
|
|
108
|
+
* compiled schema's retained pattern programs (NULL: none — the
|
|
109
|
+
* one-shot face). Returns 0, -1 on OOM. */
|
|
110
|
+
int yep_jsonschema_run(const yep_dom* schema_dom, uint32_t schema_root, const yep_dom* instance_dom,
|
|
111
|
+
const uint32_t* doc_roots, uint32_t doc_count, yeptris_validate_report* rep,
|
|
112
|
+
const yep_re_cache* cache);
|
|
113
|
+
|
|
114
|
+
/* The report constructor (validate.c owns the report machinery): a
|
|
115
|
+
* fresh empty report, NULL on allocation failure. */
|
|
116
|
+
yeptris_validate_report* yep_validate_report_new(void);
|
|
117
|
+
|
|
118
|
+
/* compile.c's seam (#885 item 3): the compiled-schema constructor with
|
|
119
|
+
* an explicit status — the one-shot face preserves its exact observable
|
|
120
|
+
* statuses through it. NULL on failure with *st = YEPTRIS_ERROR_ARG
|
|
121
|
+
* (NULL bytes with length, or bytes that hold no document; the thread
|
|
122
|
+
* error channel carries the message), the failed parse's status, or
|
|
123
|
+
* YEPTRIS_ERROR_MEMORY. */
|
|
124
|
+
struct yeptris_schema;
|
|
125
|
+
yeptris_schema* yep_schema_compile_st(const char* bytes, size_t n, YeptrisStatus* st);
|
|
126
|
+
|
|
127
|
+
#ifdef __cplusplus
|
|
128
|
+
}
|
|
129
|
+
#endif
|
|
130
|
+
|
|
131
|
+
#endif /* YEP_VALIDATE_INTERNAL_H */
|