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.
- checksums.yaml +7 -0
- data/README.adoc +141 -0
- data/ext/build_windows_native.rb +41 -0
- data/ext/libyeptris/extconf.rb +57 -0
- data/ext/yeptris_native/cbor_ruby.c +193 -0
- data/ext/yeptris_native/extconf.rb +47 -0
- data/ext/yeptris_native/json_ruby.c +354 -0
- data/ext/yeptris_native/yeptris_native.c +497 -0
- data/lib/yeptris/cbor.rb +130 -0
- data/lib/yeptris/document.rb +255 -0
- data/lib/yeptris/ffi.rb +426 -0
- data/lib/yeptris/json/descriptor.rb +266 -0
- data/lib/yeptris/json.rb +394 -0
- data/lib/yeptris/materializer.rb +354 -0
- data/lib/yeptris/native-3.4.so +0 -0
- data/lib/yeptris/node.rb +453 -0
- data/lib/yeptris/psych/class_loader.rb +24 -0
- data/lib/yeptris/psych/coder_shim.rb +55 -0
- data/lib/yeptris/psych/drop_in.rb +63 -0
- data/lib/yeptris/psych/encodable.rb +14 -0
- data/lib/yeptris/psych/handler.rb +90 -0
- data/lib/yeptris/psych/parser.rb +105 -0
- data/lib/yeptris/psych/scalar_scanner.rb +149 -0
- data/lib/yeptris/psych/visitors.rb +545 -0
- data/lib/yeptris/psych.rb +622 -0
- data/lib/yeptris/schema.rb +253 -0
- data/lib/yeptris/valueml.rb +455 -0
- data/lib/yeptris/yaml/descriptor.rb +56 -0
- data/lib/yeptris/yaml.rb +422 -0
- data/lib/yeptris.rb +113 -0
- data/libyeptris.so +0 -0
- data/vendor/libyeptris/CMakeLists.txt +254 -0
- data/vendor/libyeptris/cmake/yeptris-config.cmake.in +5 -0
- data/vendor/libyeptris/cmake/yeptris.pc.in +11 -0
- data/vendor/libyeptris/src/CMakeLists.txt +167 -0
- data/vendor/libyeptris/src/include/yeptris/api.h +32 -0
- data/vendor/libyeptris/src/include/yeptris/cbor.h +101 -0
- data/vendor/libyeptris/src/include/yeptris/dom.h +190 -0
- data/vendor/libyeptris/src/include/yeptris/emit.h +81 -0
- data/vendor/libyeptris/src/include/yeptris/error.h +41 -0
- data/vendor/libyeptris/src/include/yeptris/events.h +157 -0
- data/vendor/libyeptris/src/include/yeptris/json.h +45 -0
- data/vendor/libyeptris/src/include/yeptris/json.hpp +258 -0
- data/vendor/libyeptris/src/include/yeptris/jsonc_compat.h +115 -0
- data/vendor/libyeptris/src/include/yeptris/marshal.h +52 -0
- data/vendor/libyeptris/src/include/yeptris/parse.h +48 -0
- data/vendor/libyeptris/src/include/yeptris/plan.h +100 -0
- data/vendor/libyeptris/src/include/yeptris/resolve.h +71 -0
- data/vendor/libyeptris/src/include/yeptris/schema.h +121 -0
- data/vendor/libyeptris/src/include/yeptris/tape.h +123 -0
- data/vendor/libyeptris/src/include/yeptris/types.h +38 -0
- data/vendor/libyeptris/src/include/yeptris/values.h +102 -0
- data/vendor/libyeptris/src/include/yeptris/version.h.in +29 -0
- data/vendor/libyeptris/src/include/yeptris/visit.h +77 -0
- data/vendor/libyeptris/src/include/yeptris/yajl_compat.h +135 -0
- data/vendor/libyeptris/src/include/yeptris.h +23 -0
- data/vendor/libyeptris/src/yeptris/build.c +376 -0
- data/vendor/libyeptris/src/yeptris/cbor/cbor.h +25 -0
- data/vendor/libyeptris/src/yeptris/cbor/decode.c +981 -0
- data/vendor/libyeptris/src/yeptris/cbor/encode.c +835 -0
- data/vendor/libyeptris/src/yeptris/cbor/sink.h +58 -0
- data/vendor/libyeptris/src/yeptris/common/chartype.c +41 -0
- data/vendor/libyeptris/src/yeptris/common/chartype.h +77 -0
- data/vendor/libyeptris/src/yeptris/common/cpu.c +81 -0
- data/vendor/libyeptris/src/yeptris/common/cpu.h +40 -0
- data/vendor/libyeptris/src/yeptris/common/error.c +65 -0
- data/vendor/libyeptris/src/yeptris/common/error.h +79 -0
- data/vendor/libyeptris/src/yeptris/common/mutex.h +45 -0
- data/vendor/libyeptris/src/yeptris/common/nametab.c +275 -0
- data/vendor/libyeptris/src/yeptris/common/nametab.h +68 -0
- data/vendor/libyeptris/src/yeptris/common/port.h +74 -0
- data/vendor/libyeptris/src/yeptris/common/simd_text.c +49 -0
- data/vendor/libyeptris/src/yeptris/common/simd_text.h +295 -0
- data/vendor/libyeptris/src/yeptris/common/simd_text_avx2.c +534 -0
- data/vendor/libyeptris/src/yeptris/common/simd_text_neon.c +662 -0
- data/vendor/libyeptris/src/yeptris/common/simd_text_scalar.c +298 -0
- data/vendor/libyeptris/src/yeptris/common/string_view.c +34 -0
- data/vendor/libyeptris/src/yeptris/common/string_view.h +93 -0
- data/vendor/libyeptris/src/yeptris/doc.h +56 -0
- data/vendor/libyeptris/src/yeptris/dom/dom.c +1192 -0
- data/vendor/libyeptris/src/yeptris/dom/dom.h +312 -0
- data/vendor/libyeptris/src/yeptris/dom/hpool.c +107 -0
- data/vendor/libyeptris/src/yeptris/dom/mapindex.c +173 -0
- data/vendor/libyeptris/src/yeptris/dom/mapindex.h +61 -0
- data/vendor/libyeptris/src/yeptris/dom/mutate.c +431 -0
- data/vendor/libyeptris/src/yeptris/emit/emit.c +434 -0
- data/vendor/libyeptris/src/yeptris/emit/float/api.h +38 -0
- data/vendor/libyeptris/src/yeptris/emit/float/dragon.c +405 -0
- data/vendor/libyeptris/src/yeptris/emit/float/floatint.h +231 -0
- data/vendor/libyeptris/src/yeptris/emit/float/print.c +396 -0
- data/vendor/libyeptris/src/yeptris/emit/style.c +81 -0
- data/vendor/libyeptris/src/yeptris/emit/style.h +24 -0
- data/vendor/libyeptris/src/yeptris/emit/writer.c +816 -0
- data/vendor/libyeptris/src/yeptris/emit/writer.h +76 -0
- data/vendor/libyeptris/src/yeptris/encoding/bom.c +31 -0
- data/vendor/libyeptris/src/yeptris/encoding/encoding.h +63 -0
- data/vendor/libyeptris/src/yeptris/encoding/transcode.c +148 -0
- data/vendor/libyeptris/src/yeptris/encoding/utf8_validate.c +178 -0
- data/vendor/libyeptris/src/yeptris/events/capture.c +150 -0
- data/vendor/libyeptris/src/yeptris/events/capture.h +39 -0
- data/vendor/libyeptris/src/yeptris/events/iterparse.c +208 -0
- data/vendor/libyeptris/src/yeptris/events/pull.c +97 -0
- data/vendor/libyeptris/src/yeptris/events/push.c +104 -0
- data/vendor/libyeptris/src/yeptris/events/recorder.c +107 -0
- data/vendor/libyeptris/src/yeptris/events/values.c +527 -0
- data/vendor/libyeptris/src/yeptris/events/values_priv.h +51 -0
- data/vendor/libyeptris/src/yeptris/events/yaml_compat.c +86 -0
- data/vendor/libyeptris/src/yeptris/events/yaml_compat.h +90 -0
- data/vendor/libyeptris/src/yeptris/jsonapi/jsonc_compat.c +687 -0
- data/vendor/libyeptris/src/yeptris/jsonapi/yajl_compat.c +728 -0
- data/vendor/libyeptris/src/yeptris/marshal.c +782 -0
- data/vendor/libyeptris/src/yeptris/memory/allocator.c +20 -0
- data/vendor/libyeptris/src/yeptris/memory/allocator.h +43 -0
- data/vendor/libyeptris/src/yeptris/memory/arena.c +134 -0
- data/vendor/libyeptris/src/yeptris/memory/arena.h +52 -0
- data/vendor/libyeptris/src/yeptris/memory/pool.c +122 -0
- data/vendor/libyeptris/src/yeptris/memory/pool.h +36 -0
- data/vendor/libyeptris/src/yeptris/parse/engine.c +3698 -0
- data/vendor/libyeptris/src/yeptris/parse/engine.h +65 -0
- data/vendor/libyeptris/src/yeptris/parse/events.h +124 -0
- data/vendor/libyeptris/src/yeptris/parse/numbers.c +349 -0
- data/vendor/libyeptris/src/yeptris/parse/numbers.h +33 -0
- data/vendor/libyeptris/src/yeptris/parse/scalars.c +416 -0
- data/vendor/libyeptris/src/yeptris/parse/scalars.h +75 -0
- data/vendor/libyeptris/src/yeptris/parse.c +737 -0
- data/vendor/libyeptris/src/yeptris/plan.c +824 -0
- data/vendor/libyeptris/src/yeptris/resolve/compat11.c +334 -0
- data/vendor/libyeptris/src/yeptris/resolve/core12.c +143 -0
- data/vendor/libyeptris/src/yeptris/resolve/resolver.h +56 -0
- data/vendor/libyeptris/src/yeptris/resolve/tags.c +58 -0
- data/vendor/libyeptris/src/yeptris/scan/json.c +792 -0
- data/vendor/libyeptris/src/yeptris/scan/json.h +109 -0
- data/vendor/libyeptris/src/yeptris/scan/scan.c +463 -0
- data/vendor/libyeptris/src/yeptris/scan/scan.h +150 -0
- data/vendor/libyeptris/src/yeptris/schema.c +308 -0
- data/vendor/libyeptris/src/yeptris/tape.c +1308 -0
- data/vendor/libyeptris/src/yeptris/tape_in.h +19 -0
- data/vendor/libyeptris/src/yeptris/version.c +7 -0
- data/vendor/libyeptris/src/yeptris/visit/dom_visit.c +115 -0
- data/vendor/libyeptris/src/yeptris/visit/json_visit.c +293 -0
- data/vendor/libyeptris/src/yeptris/visit/yaml_visit.c +127 -0
- metadata +199 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/* json.h — the strict-JSON grammar interface (TODO.impl/08C/21).
|
|
2
|
+
*
|
|
3
|
+
* Kernels are exported (YEPTRIS_API) so host materializers (the Ruby
|
|
4
|
+
* native extension's fused JSON→VALUE path) can call them without
|
|
5
|
+
* pulling the whole static archive. */
|
|
6
|
+
#ifndef YEP_JSON_H
|
|
7
|
+
#define YEP_JSON_H
|
|
8
|
+
|
|
9
|
+
#include <stddef.h>
|
|
10
|
+
#include <yeptris/api.h>
|
|
11
|
+
|
|
12
|
+
#ifdef __cplusplus
|
|
13
|
+
extern "C" {
|
|
14
|
+
#endif
|
|
15
|
+
|
|
16
|
+
YEPTRIS_API int yep_json_ws(const char* p, size_t len, size_t* i, int* saw_tab);
|
|
17
|
+
|
|
18
|
+
/* Token-stream walker over a JSON-class flow span (TODO.restructure/53):
|
|
19
|
+
* the ONE grammar walk, shared by the engine's validator and the DOM's
|
|
20
|
+
* fused builder — validate and build ride the same state machine. */
|
|
21
|
+
#define YEP_JSON_WALK_DEPTH 256
|
|
22
|
+
|
|
23
|
+
typedef enum {
|
|
24
|
+
YEP_JW_OK = 0, /* token delivered in *t */
|
|
25
|
+
YEP_JW_DONE = 1, /* the span's matching close was consumed */
|
|
26
|
+
YEP_JW_REJECT = 2, /* not JSON-class: the general kernel judges */
|
|
27
|
+
} yep_jw_status;
|
|
28
|
+
|
|
29
|
+
typedef struct yep_json_tok {
|
|
30
|
+
size_t at; /* token start (the quote/opener/digit) */
|
|
31
|
+
size_t end; /* token end (past the closing quote for strings) */
|
|
32
|
+
char cls; /* '"' string, '#' number, 'a' literal, '[', '{', ']', '}' */
|
|
33
|
+
int has_escape; /* strings: a backslash escape is present */
|
|
34
|
+
int is_float; /* numbers (cls '#'): the text has '.' or an exponent */
|
|
35
|
+
/* numbers: the ONE conversion (the walker's number arm runs
|
|
36
|
+
* yep_json_number_scan — validate, advance, convert in a single
|
|
37
|
+
* pass; consumers read the values instead of rescanning). nshape:
|
|
38
|
+
* 0 int (ival exact), 1 float text (dval), 2 integer text beyond
|
|
39
|
+
* int64 (dval approximate — the number-kernel contract). */
|
|
40
|
+
int nshape;
|
|
41
|
+
int64_t ival;
|
|
42
|
+
double dval;
|
|
43
|
+
} yep_json_tok;
|
|
44
|
+
|
|
45
|
+
/* Walker states (the reference machine in scan/json.c and the tape's
|
|
46
|
+
* fused specialization share one set — same grammar, same rejects). */
|
|
47
|
+
enum {
|
|
48
|
+
JW_VALUE_OR_CLOSE = 0,
|
|
49
|
+
JW_VALUE,
|
|
50
|
+
JW_KEY_OR_CLOSE,
|
|
51
|
+
JW_KEY,
|
|
52
|
+
JW_COLON,
|
|
53
|
+
JW_COMMA_OR_CLOSE,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
typedef struct yep_json_walk {
|
|
57
|
+
const char* p;
|
|
58
|
+
size_t len;
|
|
59
|
+
int max_depth; /* the engine's runtime nesting limit */
|
|
60
|
+
size_t i; /* cursor: one past the opener */
|
|
61
|
+
size_t close; /* valid once DONE */
|
|
62
|
+
int long_key; /* a map key over the 1024-char simple-key limit */
|
|
63
|
+
int saw_tab;
|
|
64
|
+
/* strict JSON (RFC 8259): map keys are STRINGS only, including
|
|
65
|
+
* the first entry — the lenient flow class accepts YAML keys
|
|
66
|
+
* (TODO.restructure/81 stage 2: the strict build's walk IS the
|
|
67
|
+
* validator; reject falls to yep_json_document's error path). */
|
|
68
|
+
int strict;
|
|
69
|
+
uint8_t kind[YEP_JSON_WALK_DEPTH]; /* 0 seq, 1 map */
|
|
70
|
+
uint8_t expect[YEP_JSON_WALK_DEPTH]; /* walker states */
|
|
71
|
+
int depth;
|
|
72
|
+
} yep_json_walk;
|
|
73
|
+
|
|
74
|
+
/* Opens over p[open] ('[' or '{'); call _next until DONE/REJECT. */
|
|
75
|
+
void yep_json_walk_init(yep_json_walk* w, const char* p, size_t len, size_t open, int max_depth);
|
|
76
|
+
yep_jw_status yep_json_walk_next(yep_json_walk* w, yep_json_tok* t);
|
|
77
|
+
YEPTRIS_API int yep_json_number(const char* p, size_t len, size_t* i);
|
|
78
|
+
/* The grammar walk fused with conversion (TODO.restructure/26): one
|
|
79
|
+
* scan validates and converts. *is_float reports the TEXT shape:
|
|
80
|
+
* 0 = integer (*iv exact, INT64_MIN included), 1 = float text
|
|
81
|
+
* (*dv converted via the number-kernel SSOT), 2 = integer text
|
|
82
|
+
* beyond int64 (*dv approximate; exact hosts rebuild from the span
|
|
83
|
+
* start..*i). Out params may be NULL. */
|
|
84
|
+
YEPTRIS_API int yep_json_number_scan(const char* p, size_t len, size_t* i, int* is_float,
|
|
85
|
+
int64_t* iv, double* dv);
|
|
86
|
+
/* Same grammar, same rejects, same advance — NO conversion: reports
|
|
87
|
+
* the text shape only (0 int / 1 float). The lazy tape's arm. */
|
|
88
|
+
YEPTRIS_API int yep_json_number_shape(const char* p, size_t len, size_t* i, int* is_float);
|
|
89
|
+
YEPTRIS_API int yep_json_literal(const char* p, size_t len, size_t* i, const char* word);
|
|
90
|
+
YEPTRIS_API int yep_json_string(const char* p, size_t len, size_t* i, size_t* close_out,
|
|
91
|
+
int* has_esc);
|
|
92
|
+
/* Stage 1 of the token-contract tape front: the structural indexer
|
|
93
|
+
* (scalar reference; the kernels table's json_stage1 slot carries the
|
|
94
|
+
* ISA twins). Writes the token positions stage 2 dispatches on —
|
|
95
|
+
* operators, string OPEN quotes, scalar-run starts — and returns 0
|
|
96
|
+
* only for an unterminated string. idx holds len+2 entries. */
|
|
97
|
+
YEPTRIS_API int yep_json_stage1_scalar(const char* p, size_t len, uint32_t* idx, size_t* nidx);
|
|
98
|
+
|
|
99
|
+
/* The per-chunk byte-class classifier behind the flow kernels: the
|
|
100
|
+
* kernels table's json_chunk slot (common/simd_text.h) — yep_chunk_masks
|
|
101
|
+
* is defined there; the differential suite pins the ISAs to it. */
|
|
102
|
+
|
|
103
|
+
YEPTRIS_API int yep_json_document(const char* p, size_t len, size_t* err);
|
|
104
|
+
|
|
105
|
+
#ifdef __cplusplus
|
|
106
|
+
}
|
|
107
|
+
#endif
|
|
108
|
+
|
|
109
|
+
#endif /* YEP_JSON_H */
|
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
/* scan.c — line facts and span location (TODO.impl/06).
|
|
2
|
+
*
|
|
3
|
+
* Byte classification truth lives in chartype; SIMD kernels accelerate
|
|
4
|
+
* the span scans; this module owns YAML's line/span semantics only.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
#include <string.h>
|
|
8
|
+
|
|
9
|
+
#include "common/chartype.h"
|
|
10
|
+
#include "common/simd_text.h"
|
|
11
|
+
#include "scan.h"
|
|
12
|
+
|
|
13
|
+
size_t yep_scan_break_len(const char* p, size_t len, size_t pos) {
|
|
14
|
+
if (pos >= len) {
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
|
17
|
+
if (p[pos] == '\n') {
|
|
18
|
+
return 1;
|
|
19
|
+
}
|
|
20
|
+
if (p[pos] == '\r') {
|
|
21
|
+
return (pos + 1 < len && p[pos + 1] == '\n') ? 2 : 1;
|
|
22
|
+
}
|
|
23
|
+
return 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
void yep_scan_advance_line(const char* p, size_t* from, size_t to, uint32_t* line,
|
|
27
|
+
size_t* line_start) {
|
|
28
|
+
for (size_t i = *from; i < to; i++) {
|
|
29
|
+
if (p[i] == '\n') {
|
|
30
|
+
(*line)++;
|
|
31
|
+
*line_start = i + 1;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
*from = to;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* ONE home for the \n/\r break class (scan owns the concept): the
|
|
38
|
+
* engine's multiline walk shares it — it had rebuilt a duplicate per
|
|
39
|
+
* quoted scalar. Prebuilt nibble-class tables (TODO.restructure/68);
|
|
40
|
+
* the StopsetLiterals spec pins them against yep_stopset_init. */
|
|
41
|
+
const yep_stopset yep_break_stopset = {
|
|
42
|
+
.bitmap = {0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
43
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
44
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
45
|
+
.groups = 1,
|
|
46
|
+
.lo = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02,
|
|
47
|
+
0x00, 0x00}},
|
|
48
|
+
.hi = {{0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
49
|
+
0x00, 0x00}},
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
void yep_scan_facts(const char* p, size_t len, size_t pos, yep_line_facts* out) {
|
|
53
|
+
yep_text_active()->line_facts(p, len, pos, out);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* Line facts -> line info (the flags/marker derivation, facts-free).
|
|
57
|
+
* One kernel pass feeds BOTH this and the shape classifier via the
|
|
58
|
+
* engine's combined memo (TODO.restructure/76). */
|
|
59
|
+
void yep_scan_line_f(const char* p, size_t len, size_t pos, const yep_line_facts* f,
|
|
60
|
+
yep_line_info* out) {
|
|
61
|
+
yep_line_info li;
|
|
62
|
+
li.offset = (uint32_t)pos;
|
|
63
|
+
li.indent = 0;
|
|
64
|
+
li.flags = 0;
|
|
65
|
+
li.first = 0;
|
|
66
|
+
li.end = f->end;
|
|
67
|
+
size_t j = f->indent;
|
|
68
|
+
li.indent = (uint16_t)(j - pos);
|
|
69
|
+
if (j < li.end && p[j] == '\t') {
|
|
70
|
+
size_t k = j;
|
|
71
|
+
while (k < li.end && (p[k] == ' ' || p[k] == '\t')) {
|
|
72
|
+
k++;
|
|
73
|
+
}
|
|
74
|
+
if (k >= li.end) {
|
|
75
|
+
li.flags |= YEP_LF_BLANK;
|
|
76
|
+
if (li.indent == 0) {
|
|
77
|
+
li.flags |= YEP_LF_TAB;
|
|
78
|
+
}
|
|
79
|
+
*out = li;
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
li.flags |= YEP_LF_TAB;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (j >= li.end) {
|
|
86
|
+
li.flags |= YEP_LF_BLANK;
|
|
87
|
+
*out = li;
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
li.first = (unsigned char)p[j];
|
|
92
|
+
if (li.first == '#') {
|
|
93
|
+
li.flags |= YEP_LF_COMMENT;
|
|
94
|
+
*out = li;
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (li.first == '%' && li.indent == 0) {
|
|
98
|
+
li.flags |= YEP_LF_DIRECTIVE;
|
|
99
|
+
*out = li;
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* "---" / "..." at column 0, followed by EOL/space/tab/comment —
|
|
104
|
+
* content may follow on the same line ("--- > folded"). */
|
|
105
|
+
if (li.indent == 0 && li.end - j >= 3 && memcmp(p + j, "---", 3) == 0 &&
|
|
106
|
+
(li.end - j == 3 || p[j + 3] == ' ' || p[j + 3] == '\t')) {
|
|
107
|
+
li.flags |= YEP_LF_DOC_START;
|
|
108
|
+
} else if (li.indent == 0 && li.end - j >= 3 && memcmp(p + j, "...", 3) == 0 &&
|
|
109
|
+
(li.end - j == 3 || p[j + 3] == ' ' || p[j + 3] == '\t')) {
|
|
110
|
+
li.flags |= YEP_LF_DOC_END;
|
|
111
|
+
}
|
|
112
|
+
*out = li;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
yep_line_info yep_scan_line(const char* p, size_t len, size_t pos) {
|
|
116
|
+
yep_line_info li;
|
|
117
|
+
yep_line_facts f;
|
|
118
|
+
yep_scan_facts(p, len, pos, &f);
|
|
119
|
+
yep_scan_line_f(p, len, pos, &f, &li);
|
|
120
|
+
return li;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* Terminator check for ':' — blank, EOL, or (in flow) a flow indicator. */
|
|
124
|
+
static int yep_colon_terminates(const char* p, size_t len, size_t colon, int flow) {
|
|
125
|
+
size_t next = colon + 1;
|
|
126
|
+
if (next >= len) {
|
|
127
|
+
return 1; /* ':' at EOF terminates */
|
|
128
|
+
}
|
|
129
|
+
unsigned char c = (unsigned char)p[next];
|
|
130
|
+
if (c == ' ' || c == '\t' || c == '\n' || c == '\r') {
|
|
131
|
+
return 1;
|
|
132
|
+
}
|
|
133
|
+
if (flow && yep_ct_is(c, YEP_CT_FLOW_IND)) {
|
|
134
|
+
return 1;
|
|
135
|
+
}
|
|
136
|
+
return 0;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
int yep_plain_first_ok(unsigned char c) {
|
|
140
|
+
return !(c == ',' || c == ']' || c == '}' || c == '%' || c == '@' || c == '`');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
int yep_scan_prop_char(unsigned char c) {
|
|
144
|
+
return !yep_ct_any(c, YEP_CT_BLANK | YEP_CT_LBREAK | YEP_CT_FLOW_IND) && c != ',' && c != '#';
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
size_t yep_scan_prop_end(const char* p, size_t len, size_t pos) {
|
|
148
|
+
while (pos < len && yep_scan_prop_char((unsigned char)p[pos])) {
|
|
149
|
+
pos++;
|
|
150
|
+
}
|
|
151
|
+
return pos;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* ---- line-shape classification (TODO.restructure/49) ---- */
|
|
155
|
+
|
|
156
|
+
/* blank/EOL/EOF directly after p[at] (the dash / explicit-key rule). */
|
|
157
|
+
static int shape_blank_next(const char* p, size_t len, size_t at) {
|
|
158
|
+
return at + 1 >= len || p[at + 1] == ' ' || p[at + 1] == '\t' || p[at + 1] == '\n' ||
|
|
159
|
+
p[at + 1] == '\r';
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/* Value bytes the fast arms do not own: quoted/tagged/block/flow
|
|
163
|
+
* scalars and the compact-syntax leads whose semantics belong to the
|
|
164
|
+
* general chain. */
|
|
165
|
+
static int shape_val_bail(unsigned char c, const char* p, size_t len, size_t at) {
|
|
166
|
+
switch (c) {
|
|
167
|
+
case '"':
|
|
168
|
+
case '\'':
|
|
169
|
+
case '!':
|
|
170
|
+
case '|':
|
|
171
|
+
case '>':
|
|
172
|
+
case '[':
|
|
173
|
+
case '{':
|
|
174
|
+
case '*': /* an alias after an anchor is an error shape (SR86) */
|
|
175
|
+
return 1;
|
|
176
|
+
case '-':
|
|
177
|
+
case '?':
|
|
178
|
+
return shape_blank_next(p, len, at);
|
|
179
|
+
default:
|
|
180
|
+
return 0;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
static void shape_value(const char* p, size_t len, const yep_line_info* li, size_t vt,
|
|
185
|
+
yep_line_shape* s) {
|
|
186
|
+
s->val_start = (uint32_t)vt;
|
|
187
|
+
if (vt >= li->end || p[vt] == '#') { /* '#' here follows a blank by construction */
|
|
188
|
+
s->val = YEP_LVAL_EMPTY;
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
unsigned char c = (unsigned char)p[vt];
|
|
192
|
+
if (c == '*') {
|
|
193
|
+
s->val = YEP_LVAL_ALIAS; /* the engine's alias walk owns name semantics */
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
if (c == '[' || c == '{') {
|
|
197
|
+
s->val = YEP_LVAL_FLOW;
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
if (c == '&') {
|
|
201
|
+
size_t a_end = yep_scan_prop_end(p, len, vt + 1);
|
|
202
|
+
size_t t = a_end;
|
|
203
|
+
while (t < len && (p[t] == ' ' || p[t] == '\t')) {
|
|
204
|
+
t++;
|
|
205
|
+
}
|
|
206
|
+
if (t < li->end && p[t] != '#' && !shape_val_bail((unsigned char)p[t], p, len, t) &&
|
|
207
|
+
yep_plain_first_ok((unsigned char)p[t])) {
|
|
208
|
+
yep_span v = yep_scan_plain(p, len, t, 0);
|
|
209
|
+
if (v.term != YEP_TERM_COLON && v.end > v.start) {
|
|
210
|
+
s->val = YEP_LVAL_ANCHOR_PLAIN;
|
|
211
|
+
s->anchor_end = (uint32_t)a_end;
|
|
212
|
+
s->val_span = v;
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return; /* anchor with a following-lines value / odd content: bail */
|
|
217
|
+
}
|
|
218
|
+
if (shape_val_bail(c, p, len, vt) || !yep_plain_first_ok(c)) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
yep_span v = yep_scan_plain(p, len, vt, 0);
|
|
222
|
+
if (v.term == YEP_TERM_COLON) {
|
|
223
|
+
return; /* a second terminating ':' is compact/error territory */
|
|
224
|
+
}
|
|
225
|
+
s->val = YEP_LVAL_PLAIN;
|
|
226
|
+
s->val_span = v;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/* The key span straight from the fused facts (TODO.restructure/76):
|
|
230
|
+
* the common line's key scan becomes zero byte-walking. Rare shapes
|
|
231
|
+
* (interior ':', embedded '#') fall back to the walking scan — the
|
|
232
|
+
* two must agree, and the LineShape spec pins them together. */
|
|
233
|
+
static yep_span shape_key_span(const char* p, size_t len, size_t t, const yep_line_facts* f) {
|
|
234
|
+
yep_span k;
|
|
235
|
+
k.start = (uint32_t)t;
|
|
236
|
+
k.term = YEP_TERM_EOF;
|
|
237
|
+
if (f->stop_set && f->stop >= t) {
|
|
238
|
+
unsigned char c = (unsigned char)p[f->stop];
|
|
239
|
+
if (c == ':') {
|
|
240
|
+
if (yep_colon_terminates(p, len, f->stop, 0)) {
|
|
241
|
+
k.term = YEP_TERM_COLON;
|
|
242
|
+
k.end = f->stop;
|
|
243
|
+
while (k.end > k.start && (p[k.end - 1] == ' ' || p[k.end - 1] == '\t')) {
|
|
244
|
+
k.end--;
|
|
245
|
+
}
|
|
246
|
+
return k;
|
|
247
|
+
}
|
|
248
|
+
} else if (c == '#' && (f->stop == t || p[f->stop - 1] == ' ' || p[f->stop - 1] == '\t')) {
|
|
249
|
+
k.term = YEP_TERM_COMMENT;
|
|
250
|
+
k.end = f->stop;
|
|
251
|
+
while (k.end > k.start && (p[k.end - 1] == ' ' || p[k.end - 1] == '\t')) {
|
|
252
|
+
k.end--;
|
|
253
|
+
}
|
|
254
|
+
return k;
|
|
255
|
+
}
|
|
256
|
+
return yep_scan_plain(p, len, t, 0); /* non-terminating stop: the walk owns it */
|
|
257
|
+
}
|
|
258
|
+
/* no stop byte before EOL: the span runs to the line end */
|
|
259
|
+
k.end = f->end;
|
|
260
|
+
while (k.end > k.start && (p[k.end - 1] == ' ' || p[k.end - 1] == '\t')) {
|
|
261
|
+
k.end--;
|
|
262
|
+
}
|
|
263
|
+
k.term = f->end < len ? YEP_TERM_EOL : YEP_TERM_EOF;
|
|
264
|
+
return k;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
void yep_scan_shape_f(const char* p, size_t len, const yep_line_info* li, const yep_line_facts* f,
|
|
268
|
+
yep_line_shape* s) {
|
|
269
|
+
memset(s, 0, sizeof(*s));
|
|
270
|
+
s->kind = YEP_LSHAPE_NONE;
|
|
271
|
+
s->val = YEP_LVAL_NONE;
|
|
272
|
+
if (li->flags != 0) {
|
|
273
|
+
return; /* blank/comment/doc/directive/tab lines: general paths */
|
|
274
|
+
}
|
|
275
|
+
size_t t = li->offset + li->indent;
|
|
276
|
+
unsigned char c = (unsigned char)p[t];
|
|
277
|
+
|
|
278
|
+
if (c == '-' && shape_blank_next(p, len, t)) {
|
|
279
|
+
size_t vt = t + 1;
|
|
280
|
+
while (vt < len && (p[vt] == ' ' || p[vt] == '\t')) {
|
|
281
|
+
vt++;
|
|
282
|
+
}
|
|
283
|
+
s->kind = YEP_LSHAPE_DASH;
|
|
284
|
+
s->dash = (uint32_t)t;
|
|
285
|
+
shape_value(p, len, li, vt, s);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/* '?' / ':' followed by a blank are the explicit-key and bare-colon
|
|
290
|
+
* lines (the general paths own them); followed by content they are
|
|
291
|
+
* ordinary plain-first bytes. A dash + blank returned as DASH above. */
|
|
292
|
+
if (yep_plain_first_ok(c) && c != '&' && c != '!' && c != '*' && c != '\'' && c != '"' &&
|
|
293
|
+
c != '[' && c != '{' && !((c == '?' || c == ':') && shape_blank_next(p, len, t))) {
|
|
294
|
+
yep_span k = shape_key_span(p, len, t, f);
|
|
295
|
+
if (k.term == YEP_TERM_COLON) {
|
|
296
|
+
/* k.end is the TRIMMED span end: the ':' sits past the
|
|
297
|
+
* trimmed blanks (or past interior stops on the fallback
|
|
298
|
+
* path) — the forward walk is over spaces, a few bytes */
|
|
299
|
+
size_t colon = k.end;
|
|
300
|
+
while (p[colon] != ':') {
|
|
301
|
+
colon++;
|
|
302
|
+
}
|
|
303
|
+
size_t vt = colon + 1;
|
|
304
|
+
while (vt < len && (p[vt] == ' ' || p[vt] == '\t')) {
|
|
305
|
+
vt++;
|
|
306
|
+
}
|
|
307
|
+
s->kind = YEP_LSHAPE_KEY;
|
|
308
|
+
s->key_start = k.start;
|
|
309
|
+
s->key_end = k.end;
|
|
310
|
+
s->colon = (uint32_t)colon;
|
|
311
|
+
shape_value(p, len, li, vt, s);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
void yep_scan_shape(const char* p, size_t len, const yep_line_info* li, yep_line_shape* s) {
|
|
317
|
+
yep_line_facts f;
|
|
318
|
+
yep_scan_facts(p, len, li->offset, &f);
|
|
319
|
+
yep_scan_shape_f(p, len, li, &f, s);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/* The two plain-scalar stop classes are constants — they were rebuilt
|
|
323
|
+
on EVERY scan (~2 per line; clear + 4-9 adds ≈ 3M ops on a 100k-line
|
|
324
|
+
document), then became static bitmaps, now prebuilt nibble-class
|
|
325
|
+
tables (TODO.restructure/68). Generated: set[c>>3] |= 1 << (c&7) for
|
|
326
|
+
the stop chars below; lo/hi pinned by the StopsetLiterals spec. */
|
|
327
|
+
const yep_stopset yep_plain_stop_block = {
|
|
328
|
+
.bitmap = {0x00, 0x24, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
|
329
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
330
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
331
|
+
/* members: \n \r # : */
|
|
332
|
+
.groups = 1,
|
|
333
|
+
.lo = {{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x02,
|
|
334
|
+
0x00, 0x00}},
|
|
335
|
+
.hi = {{0x03, 0x00, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
336
|
+
0x00, 0x00}},
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
const yep_stopset yep_plain_stop_flow = {
|
|
340
|
+
.bitmap = {0x00, 0x24, 0x00, 0x00, 0x08, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
|
|
341
|
+
0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
342
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
343
|
+
/* members: \n \r # , : [ ] { } */
|
|
344
|
+
.groups = 2,
|
|
345
|
+
.lo = {{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x08, 0x42,
|
|
346
|
+
0x00, 0x00},
|
|
347
|
+
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
|
348
|
+
0x00, 0x00}},
|
|
349
|
+
.hi = {{0x03, 0x00, 0x0C, 0x10, 0x00, 0x60, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
350
|
+
0x00, 0x00},
|
|
351
|
+
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
352
|
+
0x00, 0x00}},
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
yep_span yep_scan_plain(const char* p, size_t len, size_t pos, int flow) {
|
|
356
|
+
const yep_text_kernels* k = yep_text_active();
|
|
357
|
+
const yep_stopset* stop = flow ? &yep_plain_stop_flow : &yep_plain_stop_block;
|
|
358
|
+
/* Short spans keep the scalar walk: the kernel dispatch costs more
|
|
359
|
+
* than it saves below a vector (block keys run 2-8 bytes — the
|
|
360
|
+
* same gate scan_line uses for its end-find). */
|
|
361
|
+
const int tiny = (len - pos) < 64;
|
|
362
|
+
|
|
363
|
+
yep_span s;
|
|
364
|
+
s.start = (uint32_t)pos;
|
|
365
|
+
s.end = (uint32_t)pos;
|
|
366
|
+
s.term = YEP_TERM_EOF;
|
|
367
|
+
|
|
368
|
+
size_t i = pos;
|
|
369
|
+
while (i < len) {
|
|
370
|
+
ptrdiff_t hit;
|
|
371
|
+
if (tiny) {
|
|
372
|
+
size_t at = i;
|
|
373
|
+
while (at < len && !yep_stopset_test(stop->bitmap, (unsigned char)p[at])) {
|
|
374
|
+
at++;
|
|
375
|
+
}
|
|
376
|
+
hit = (at < len) ? (ptrdiff_t)(at - i) : -1;
|
|
377
|
+
} else {
|
|
378
|
+
hit = k->stopset_find(stop, p + i, len - i);
|
|
379
|
+
}
|
|
380
|
+
size_t at = (hit < 0) ? len : i + (size_t)hit;
|
|
381
|
+
unsigned char c = (at < len) ? (unsigned char)p[at] : 0;
|
|
382
|
+
|
|
383
|
+
if (at == len) {
|
|
384
|
+
i = len;
|
|
385
|
+
s.term = YEP_TERM_EOF;
|
|
386
|
+
break;
|
|
387
|
+
}
|
|
388
|
+
if (c == '\n' || c == '\r') {
|
|
389
|
+
i = at;
|
|
390
|
+
s.term = YEP_TERM_EOL;
|
|
391
|
+
break;
|
|
392
|
+
}
|
|
393
|
+
if (c == ':') {
|
|
394
|
+
if (yep_colon_terminates(p, len, at, flow)) {
|
|
395
|
+
i = at;
|
|
396
|
+
s.term = YEP_TERM_COLON;
|
|
397
|
+
break;
|
|
398
|
+
}
|
|
399
|
+
i = at + 1;
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
if (c == '#') {
|
|
403
|
+
/* '#' starts a comment after a blank or at span start */
|
|
404
|
+
if (at == s.start || (at > s.start && (p[at - 1] == ' ' || p[at - 1] == '\t'))) {
|
|
405
|
+
i = at;
|
|
406
|
+
s.term = YEP_TERM_COMMENT;
|
|
407
|
+
break;
|
|
408
|
+
}
|
|
409
|
+
i = at + 1;
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
412
|
+
/* flow indicator (flow context only) */
|
|
413
|
+
i = at;
|
|
414
|
+
s.term = YEP_TERM_FLOW;
|
|
415
|
+
break;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/* Trim trailing spaces/tabs from the span. */
|
|
419
|
+
size_t e = i;
|
|
420
|
+
while (e > s.start && (p[e - 1] == ' ' || p[e - 1] == '\t')) {
|
|
421
|
+
e--;
|
|
422
|
+
}
|
|
423
|
+
s.end = (uint32_t)e;
|
|
424
|
+
if (e == s.start && s.term == YEP_TERM_EOF) {
|
|
425
|
+
s.term = YEP_TERM_EOF;
|
|
426
|
+
}
|
|
427
|
+
return s;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
yep_span yep_scan_quoted(const char* p, size_t len, size_t pos, int* has_escape) {
|
|
431
|
+
const yep_text_kernels* k = yep_text_active();
|
|
432
|
+
unsigned char q = (unsigned char)p[pos];
|
|
433
|
+
int esc = 0;
|
|
434
|
+
ptrdiff_t r = k->quote_scan(p + pos + 1, len - pos - 1, (char)q, &esc);
|
|
435
|
+
if (has_escape != NULL) {
|
|
436
|
+
*has_escape = esc;
|
|
437
|
+
}
|
|
438
|
+
yep_span s;
|
|
439
|
+
s.start = (uint32_t)(pos + 1);
|
|
440
|
+
if (r < 0) {
|
|
441
|
+
s.end = (uint32_t)len;
|
|
442
|
+
s.term = YEP_TERM_EOL; /* unterminated — caller reports the error */
|
|
443
|
+
} else {
|
|
444
|
+
s.end = (uint32_t)(pos + 1 + (size_t)r);
|
|
445
|
+
s.term = YEP_TERM_EOF;
|
|
446
|
+
}
|
|
447
|
+
return s;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
int yep_scan_is_key_start(unsigned char c) {
|
|
451
|
+
/* Quotes and flow openers always start a potential key; plain-first
|
|
452
|
+
* excludes most indicators. */
|
|
453
|
+
if (c == '\'' || c == '"' || c == '[' || c == '{' || c == '?') {
|
|
454
|
+
return 1;
|
|
455
|
+
}
|
|
456
|
+
if (c == '&' || c == '!' || c == '*') {
|
|
457
|
+
return 1; /* properties or an alias may open a key node */
|
|
458
|
+
}
|
|
459
|
+
if (yep_ct_is(c, YEP_CT_INDICATOR)) {
|
|
460
|
+
return 0; /* the remaining indicators cannot start a plain scalar */
|
|
461
|
+
}
|
|
462
|
+
return yep_ct_is_ns(c);
|
|
463
|
+
}
|