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,65 @@
|
|
|
1
|
+
/* engine.h — the one parser engine (TODO.impl/07).
|
|
2
|
+
*
|
|
3
|
+
* Non-recursive block machine + iterative flow kernel, producing events
|
|
4
|
+
* into any sink (DOM builder today; pull/recorder in 12). v1 runs the
|
|
5
|
+
* whole buffer in one call; resumable stepping lands with 12's streaming
|
|
6
|
+
* (recorded as the item's open phase). Depth guard rejects pathological
|
|
7
|
+
* nesting with an error, never a crash.
|
|
8
|
+
*/
|
|
9
|
+
#ifndef YEP_ENGINE_H
|
|
10
|
+
#define YEP_ENGINE_H
|
|
11
|
+
|
|
12
|
+
#include "common/error.h"
|
|
13
|
+
#include "common/simd_text.h"
|
|
14
|
+
#include "memory/allocator.h"
|
|
15
|
+
#include "memory/pool.h"
|
|
16
|
+
#include "parse/events.h"
|
|
17
|
+
|
|
18
|
+
#ifdef __cplusplus
|
|
19
|
+
extern "C" {
|
|
20
|
+
#endif
|
|
21
|
+
|
|
22
|
+
typedef struct yep_engine yep_engine;
|
|
23
|
+
|
|
24
|
+
yep_engine* yep_engine_create(const yep_allocator* sys);
|
|
25
|
+
void yep_engine_destroy(yep_engine* e);
|
|
26
|
+
|
|
27
|
+
/* Parses [buf, buf+len) — must be validated UTF-8 (05). Returns 0 on
|
|
28
|
+
* success, -1 on parse error (see yep_engine_error), -2 sink abort. */
|
|
29
|
+
int yep_engine_run(yep_engine* e, const char* buf, size_t len, const yep_sink* sink);
|
|
30
|
+
|
|
31
|
+
/* Content-derived pre-sizing before run(): reserves the anchor interner
|
|
32
|
+
* from the stream's '&' occurrences (every anchor definition carries
|
|
33
|
+
* exactly one, so the count never undershoots). */
|
|
34
|
+
void yep_engine_prepare(yep_engine* e, const yep_text_stats* st);
|
|
35
|
+
|
|
36
|
+
/* Resumable stepping (TODO.impl/07): chunks accumulate; every feed
|
|
37
|
+
* parses the complete DOCUMENTS received so far (cut at `---` / `...`
|
|
38
|
+
* boundaries at column 0, outside quotes and flow) and keeps the
|
|
39
|
+
* trailing partial document buffered. final != 0 flushes it and ends
|
|
40
|
+
* the stream. STREAM markers bracket the whole stepped stream, not
|
|
41
|
+
* each step; each document's events arrive exactly once, in order.
|
|
42
|
+
* Returns 0, -1 parse error, -2 sink abort. */
|
|
43
|
+
int yep_engine_step(yep_engine* e, const char* chunk, size_t len, int final, const yep_sink* sink);
|
|
44
|
+
|
|
45
|
+
/* Detaches the finish pool (ownership moves to the caller; the engine
|
|
46
|
+
* allocates a fresh one if reused). Returns NULL when absent. */
|
|
47
|
+
yep_pool* yep_engine_detach_pool(yep_engine* e);
|
|
48
|
+
|
|
49
|
+
/* Implicit-typing schema for the next run (NULL: 1.2 core), and the
|
|
50
|
+
* runtime nesting limit. */
|
|
51
|
+
struct yep_resolver;
|
|
52
|
+
void yep_engine_set_resolver(yep_engine* e, const struct yep_resolver* r);
|
|
53
|
+
void yep_engine_set_max_depth(yep_engine* e, int depth);
|
|
54
|
+
|
|
55
|
+
/* Byte offset the last run reached (into that run's buffer); used by
|
|
56
|
+
* consumers that stop the engine at a boundary and resume. */
|
|
57
|
+
size_t yep_engine_pos(const yep_engine* e);
|
|
58
|
+
|
|
59
|
+
const yep_error* yep_engine_error(const yep_engine* e);
|
|
60
|
+
|
|
61
|
+
#ifdef __cplusplus
|
|
62
|
+
}
|
|
63
|
+
#endif
|
|
64
|
+
|
|
65
|
+
#endif /* YEP_ENGINE_H */
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/* events.h — the one grammar vocabulary (TODO.impl/07).
|
|
2
|
+
*
|
|
3
|
+
* Every consumption model (DOM builder, pull, push, recorder — 11/12) is
|
|
4
|
+
* a sink over these events; the engine knows none of them (OCP). Values
|
|
5
|
+
* are borrowed either from the input buffer or from the engine's finish
|
|
6
|
+
* pool (folded/escaped content) — `borrowed` says which, so the DOM
|
|
7
|
+
* builder copies exactly what must outlive the engine.
|
|
8
|
+
*/
|
|
9
|
+
#ifndef YEP_EVENTS_H
|
|
10
|
+
#define YEP_EVENTS_H
|
|
11
|
+
|
|
12
|
+
#include "common/string_view.h"
|
|
13
|
+
|
|
14
|
+
#ifdef __cplusplus
|
|
15
|
+
extern "C" {
|
|
16
|
+
#endif
|
|
17
|
+
|
|
18
|
+
typedef enum {
|
|
19
|
+
YEP_EV_NONE = 0,
|
|
20
|
+
YEP_EV_STREAM_START,
|
|
21
|
+
YEP_EV_STREAM_END,
|
|
22
|
+
YEP_EV_DOCUMENT_START,
|
|
23
|
+
YEP_EV_DOCUMENT_END,
|
|
24
|
+
YEP_EV_SEQ_START,
|
|
25
|
+
YEP_EV_SEQ_END,
|
|
26
|
+
YEP_EV_MAP_START,
|
|
27
|
+
YEP_EV_MAP_END,
|
|
28
|
+
YEP_EV_SCALAR,
|
|
29
|
+
YEP_EV_ALIAS,
|
|
30
|
+
} yep_event_type;
|
|
31
|
+
|
|
32
|
+
/* Mirrors libyaml's style set — the wire vocabulary of 12's compat layer. */
|
|
33
|
+
typedef enum {
|
|
34
|
+
YEP_STYLE_ANY = 0,
|
|
35
|
+
YEP_STYLE_PLAIN,
|
|
36
|
+
YEP_STYLE_SINGLE_QUOTED,
|
|
37
|
+
YEP_STYLE_DOUBLE_QUOTED,
|
|
38
|
+
YEP_STYLE_LITERAL,
|
|
39
|
+
YEP_STYLE_FOLDED,
|
|
40
|
+
} yep_scalar_style;
|
|
41
|
+
|
|
42
|
+
typedef struct yep_event {
|
|
43
|
+
yep_event_type type;
|
|
44
|
+
yep_view value; /* scalar content / alias name */
|
|
45
|
+
yep_view anchor; /* node properties, empty when absent */
|
|
46
|
+
yep_view tag;
|
|
47
|
+
uint8_t style; /* yep_scalar_style */
|
|
48
|
+
uint8_t implicit; /* scalar written without quotes/tag (plain implicit) */
|
|
49
|
+
uint8_t flow; /* collection opened in flow context */
|
|
50
|
+
uint8_t multiline; /* scalar spanned lines: may not be a simple key */
|
|
51
|
+
uint8_t tag_id; /* resolved implicit/explicit tag (resolve/resolver.h) */
|
|
52
|
+
uint8_t borrowed; /* 1: value borrows the INPUT; 0: engine finish pool */
|
|
53
|
+
uint32_t anchor_id; /* 1-based anchor ordinal (the engine's serial);
|
|
54
|
+
* on ALIAS: the TARGET's ordinal. 0 = none. Sinks
|
|
55
|
+
* that key on it skip the name hash entirely. */
|
|
56
|
+
uint32_t line; /* 1-based position of the node start */
|
|
57
|
+
uint32_t col;
|
|
58
|
+
} yep_event;
|
|
59
|
+
|
|
60
|
+
struct yep_block_value; /* value facts for on_block_pair (below) */
|
|
61
|
+
|
|
62
|
+
typedef struct yep_sink {
|
|
63
|
+
/* Returns 0 to continue, nonzero to abort the parse (sink error). */
|
|
64
|
+
int (*on_event)(void* ctx, const yep_event* ev);
|
|
65
|
+
void* ctx;
|
|
66
|
+
/* Fused flow fast path (TODO.restructure/53): validate AND build
|
|
67
|
+
* the span at p[open..len) in ONE walk (the grammar walker is
|
|
68
|
+
* scan/json.c's SSOT). Returns 1 = built and staged, *close set —
|
|
69
|
+
* the engine runs its close-based grammar checks next, then
|
|
70
|
+
* COMMITS or ROLLS BACK; 2 = grammar-valid but a map key exceeds
|
|
71
|
+
* the simple-key limit (nothing staged; the engine's pass 2 owns
|
|
72
|
+
* that error); 0 = not JSON-class (nothing staged; the general
|
|
73
|
+
* kernel); <0 = abort. Sinks that consume events (pull/push/
|
|
74
|
+
* recorder) leave the trio NULL. */
|
|
75
|
+
int (*on_flow_build)(void* ctx, const char* p, size_t open, size_t len, uint32_t line,
|
|
76
|
+
size_t line_start, yep_view anchor, yep_view tag, uint32_t anchor_id,
|
|
77
|
+
int max_depth, size_t* close);
|
|
78
|
+
int (*on_flow_commit)(void* ctx);
|
|
79
|
+
void (*on_flow_rollback)(void* ctx);
|
|
80
|
+
/* Optional block fast path (TODO.restructure/54): the engine's
|
|
81
|
+
* classified KEY arm offers the whole line pair — key scalar plus
|
|
82
|
+
* a classified value — before emitting any event. line/cols are
|
|
83
|
+
* the engine's position facts. Return 1 = both nodes built and
|
|
84
|
+
* placed, 0 = not handled (the engine emits the two events
|
|
85
|
+
* exactly as before), <0 = abort. */
|
|
86
|
+
int (*on_block_pair)(void* ctx, const yep_view* key, const struct yep_block_value* v,
|
|
87
|
+
uint32_t line, uint16_t key_col, uint16_t val_col);
|
|
88
|
+
/* Optional block-open fast path (TODO.restructure/57): a `key:`
|
|
89
|
+
* line whose value lives on FOLLOWING lines, when the engine is
|
|
90
|
+
* about to open a FRESH mapping. 1 = the sink built the map node
|
|
91
|
+
* (placed, stack pushed) and the key node — the engine opens its
|
|
92
|
+
* frame silently and skips both events; 0 = events as before. */
|
|
93
|
+
int (*on_block_open)(void* ctx, const yep_view* key, uint32_t line, uint16_t key_col);
|
|
94
|
+
/* Optional dash-item fast path (TODO.restructure/78): a classified
|
|
95
|
+
* `- value` plain item after the engine opened (or continued) the
|
|
96
|
+
* block sequence. 1 = the sink built and placed the item node,
|
|
97
|
+
* 0 = the engine emits the scalar event as before, <0 = abort. */
|
|
98
|
+
int (*on_block_item)(void* ctx, const struct yep_block_value* v);
|
|
99
|
+
|
|
100
|
+
/* Direct scalar path (TODO.restructure/79): the same node the
|
|
101
|
+
* YEP_EV_SCALAR event builds, minus the event seam — emit_now
|
|
102
|
+
* resolves the tag first (the typing SSOT stays in the engine)
|
|
103
|
+
* and calls here when present. NULL = the event path, unchanged. */
|
|
104
|
+
int (*on_scalar)(void* ctx, const struct yep_view* value, const struct yep_view* tag,
|
|
105
|
+
const struct yep_view* anchor, uint32_t anchor_id, uint8_t tag_id,
|
|
106
|
+
uint8_t style, uint8_t implicit, uint8_t flow, int borrowed);
|
|
107
|
+
} yep_sink;
|
|
108
|
+
|
|
109
|
+
/* Value facts for on_block_pair (the classified value classes the
|
|
110
|
+
* block arms own; spans are input-borrowed). */
|
|
111
|
+
typedef struct yep_block_value {
|
|
112
|
+
uint8_t cls; /* YEP_LVAL_PLAIN / _ALIAS / _ANCHOR_PLAIN */
|
|
113
|
+
uint8_t borrowed; /* 1: value borrows the input; 0: engine pool */
|
|
114
|
+
yep_view value; /* scalar content / alias name */
|
|
115
|
+
yep_view anchor; /* _ANCHOR_PLAIN: the &name span */
|
|
116
|
+
uint32_t anchor_id; /* engine ordinal: the definition (_ANCHOR_)
|
|
117
|
+
* or the resolved TARGET (_ALIAS_) */
|
|
118
|
+
} yep_block_value;
|
|
119
|
+
|
|
120
|
+
#ifdef __cplusplus
|
|
121
|
+
}
|
|
122
|
+
#endif
|
|
123
|
+
|
|
124
|
+
#endif /* YEP_EVENTS_H */
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
/* numbers.c — the typed-value conversion kernels (TODO.impl/08B).
|
|
2
|
+
*
|
|
3
|
+
* Extracted verbatim from parse.c's node accessors: behavior is
|
|
4
|
+
* pinned by the typed-accessor spec battery and the 20k randomized
|
|
5
|
+
* strtod cross-checks. */
|
|
6
|
+
|
|
7
|
+
#include <errno.h>
|
|
8
|
+
#include <math.h>
|
|
9
|
+
#include <stdlib.h>
|
|
10
|
+
#include <string.h>
|
|
11
|
+
|
|
12
|
+
#include "numbers.h"
|
|
13
|
+
|
|
14
|
+
#define NUM_BUF 80
|
|
15
|
+
|
|
16
|
+
/* strips '_' and ',' into a NUL-terminated stack buffer; returns the
|
|
17
|
+
* cleaned length (the raw length when nothing needed stripping —
|
|
18
|
+
* callers then use the original bytes) */
|
|
19
|
+
static size_t num_clean(const char* p, uint32_t len, char* buf) {
|
|
20
|
+
if (memchr(p, '_', len) == NULL && memchr(p, ',', len) == NULL) {
|
|
21
|
+
return len; /* caller reads p directly */
|
|
22
|
+
}
|
|
23
|
+
size_t o = 0;
|
|
24
|
+
for (uint32_t i = 0; i < len && o + 1 < NUM_BUF; i++) {
|
|
25
|
+
char c = p[i];
|
|
26
|
+
if (c == '_' || c == ',') {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
buf[o++] = c;
|
|
30
|
+
}
|
|
31
|
+
buf[o] = '\0';
|
|
32
|
+
return o;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* Clinger-bounded exact decimal: mantissa < 2^53, adjusted
|
|
36
|
+
* exponent within +-22 — 23-entry pow10 table (08B) */
|
|
37
|
+
static const double k_pow10[23] = {
|
|
38
|
+
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11,
|
|
39
|
+
1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
static int fast_double(const char* s, size_t len, double* out) {
|
|
43
|
+
size_t i = 0;
|
|
44
|
+
int neg = 0;
|
|
45
|
+
if (i < len && (s[i] == '-' || s[i] == '+')) {
|
|
46
|
+
neg = s[i] == '-';
|
|
47
|
+
i++;
|
|
48
|
+
}
|
|
49
|
+
uint64_t m = 0;
|
|
50
|
+
int digits = 0;
|
|
51
|
+
int dot = -1;
|
|
52
|
+
for (; i < len; i++) {
|
|
53
|
+
char c = s[i];
|
|
54
|
+
if (c == '.') {
|
|
55
|
+
if (dot >= 0) {
|
|
56
|
+
return 0;
|
|
57
|
+
}
|
|
58
|
+
dot = (int)digits;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (c < '0' || c > '9') {
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
if (digits >= 15) {
|
|
65
|
+
return 0; /* outside the exact range */
|
|
66
|
+
}
|
|
67
|
+
m = m * 10u + (uint64_t)(c - '0');
|
|
68
|
+
digits++;
|
|
69
|
+
}
|
|
70
|
+
if (digits == 0 || (i < len && s[i] != 'e' && s[i] != 'E')) {
|
|
71
|
+
return 0; /* empty mantissa or trailing junk */
|
|
72
|
+
}
|
|
73
|
+
int e10 = 0;
|
|
74
|
+
if (i < len) {
|
|
75
|
+
i++; /* e/E */
|
|
76
|
+
int eneg = 0;
|
|
77
|
+
if (i < len && (s[i] == '-' || s[i] == '+')) {
|
|
78
|
+
eneg = s[i] == '-';
|
|
79
|
+
i++;
|
|
80
|
+
}
|
|
81
|
+
if (i >= len) {
|
|
82
|
+
return 0;
|
|
83
|
+
}
|
|
84
|
+
for (; i < len; i++) {
|
|
85
|
+
if (s[i] < '0' || s[i] > '9') {
|
|
86
|
+
return 0;
|
|
87
|
+
}
|
|
88
|
+
e10 = e10 * 10 + (s[i] - '0');
|
|
89
|
+
if (e10 > 308) {
|
|
90
|
+
return 0;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (eneg) {
|
|
94
|
+
e10 = -e10;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (dot >= 0) {
|
|
98
|
+
e10 -= digits - dot;
|
|
99
|
+
}
|
|
100
|
+
if (e10 > 22 || e10 < -22 || m >= (1ull << 53)) {
|
|
101
|
+
return 0; /* outside Clinger's exact range */
|
|
102
|
+
}
|
|
103
|
+
if (e10 >= 0) {
|
|
104
|
+
double v = (double)m * k_pow10[e10];
|
|
105
|
+
*out = neg ? -v : v;
|
|
106
|
+
} else {
|
|
107
|
+
double v = (double)m / k_pow10[-e10];
|
|
108
|
+
*out = neg ? -v : v;
|
|
109
|
+
}
|
|
110
|
+
return 1;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
int yep_num_i64(const char* p, uint32_t len, int64_t* out) {
|
|
114
|
+
if (p == NULL || len == 0) {
|
|
115
|
+
return 1;
|
|
116
|
+
}
|
|
117
|
+
char buf[NUM_BUF];
|
|
118
|
+
size_t l = num_clean(p, len, buf);
|
|
119
|
+
const char* num =
|
|
120
|
+
(l == len && memchr(p, '_', len) == NULL && memchr(p, ',', len) == NULL) ? p : buf;
|
|
121
|
+
if (num != p) {
|
|
122
|
+
/* cleaned copy already NUL-terminated by num_clean */
|
|
123
|
+
} else {
|
|
124
|
+
if (l >= NUM_BUF) {
|
|
125
|
+
return 1;
|
|
126
|
+
}
|
|
127
|
+
memcpy(buf, num, l);
|
|
128
|
+
buf[l] = '\0';
|
|
129
|
+
num = buf;
|
|
130
|
+
}
|
|
131
|
+
int base = 10;
|
|
132
|
+
const char* s = buf;
|
|
133
|
+
if (buf[0] == '-' || buf[0] == '+') {
|
|
134
|
+
s++;
|
|
135
|
+
}
|
|
136
|
+
if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
|
|
137
|
+
base = 16;
|
|
138
|
+
} else if (s[0] == '0' && (s[1] == 'b' || s[1] == 'B')) {
|
|
139
|
+
base = 2;
|
|
140
|
+
} else if (s[0] == '0' && s[1] == 'o') {
|
|
141
|
+
memmove(buf + (size_t)(s - buf) + 1, s + 2, l - (size_t)(s - buf) - 1);
|
|
142
|
+
l -= 1;
|
|
143
|
+
buf[l] = '\0';
|
|
144
|
+
base = 8; /* 0o17 -> 017 octal */
|
|
145
|
+
} else if (s[0] == '0' && s[1] != '\0' && s[1] != '.') {
|
|
146
|
+
base = 8; /* compat leading-0 octal */
|
|
147
|
+
}
|
|
148
|
+
if (memchr(buf, ':', l) != NULL) {
|
|
149
|
+
/* Psych's sexagesimal fold, verbatim (scalar_scanner.rb):
|
|
150
|
+
* component e weighs 60 ** |e - 2| and the SIGN rides the
|
|
151
|
+
* first component only (-1:30 -> -3600 + 1800 = -1800, not
|
|
152
|
+
* -5400). A 2-component value is H:M, seconds implicitly
|
|
153
|
+
* zero (1:30 -> 5400). TODO.restructure/43 / issue #30. */
|
|
154
|
+
const char* q = buf;
|
|
155
|
+
long long sign = 1;
|
|
156
|
+
if (q[0] == '-' || q[0] == '+') {
|
|
157
|
+
if (q[0] == '-')
|
|
158
|
+
sign = -1;
|
|
159
|
+
q++;
|
|
160
|
+
}
|
|
161
|
+
long long v = 0;
|
|
162
|
+
while (*q >= '0' && *q <= '9') {
|
|
163
|
+
v = v * 10 + (*q - '0');
|
|
164
|
+
q++;
|
|
165
|
+
}
|
|
166
|
+
v *= 3600; /* e0 weight */
|
|
167
|
+
if (sign < 0)
|
|
168
|
+
v = -v;
|
|
169
|
+
int groups = 0;
|
|
170
|
+
while (*q == ':' && groups < 2) {
|
|
171
|
+
q++;
|
|
172
|
+
long long g = 0;
|
|
173
|
+
int d = 0;
|
|
174
|
+
while (*q >= '0' && *q <= '9') {
|
|
175
|
+
g = g * 10 + (*q - '0');
|
|
176
|
+
q++;
|
|
177
|
+
d++;
|
|
178
|
+
}
|
|
179
|
+
if (d == 0) {
|
|
180
|
+
return 1;
|
|
181
|
+
}
|
|
182
|
+
v += g * (groups == 0 ? 60 : 1); /* e1 then e2 */
|
|
183
|
+
groups++;
|
|
184
|
+
}
|
|
185
|
+
if (groups == 0 || *q != '\0') {
|
|
186
|
+
return 1;
|
|
187
|
+
}
|
|
188
|
+
*out = v;
|
|
189
|
+
return 0;
|
|
190
|
+
}
|
|
191
|
+
char* end = NULL;
|
|
192
|
+
errno = 0;
|
|
193
|
+
long long v = strtoll(buf, &end, base);
|
|
194
|
+
if (end == buf || *end != '\0' || errno == ERANGE) {
|
|
195
|
+
return 1;
|
|
196
|
+
}
|
|
197
|
+
*out = (int64_t)v;
|
|
198
|
+
return 0;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
int yep_num_f64(const char* p, uint32_t len, double* out) {
|
|
202
|
+
if (p == NULL || len == 0) {
|
|
203
|
+
return 1;
|
|
204
|
+
}
|
|
205
|
+
char buf[NUM_BUF];
|
|
206
|
+
size_t l = num_clean(p, len, buf);
|
|
207
|
+
const char* num =
|
|
208
|
+
(l == len && memchr(p, '_', len) == NULL && memchr(p, ',', len) == NULL) ? p : buf;
|
|
209
|
+
/* 08B fast path: the common decimal shape converts exactly with
|
|
210
|
+
* integer arithmetic; everything else falls to strtod */
|
|
211
|
+
{
|
|
212
|
+
double fast;
|
|
213
|
+
if (fast_double(num, l, &fast)) {
|
|
214
|
+
*out = fast;
|
|
215
|
+
return 0;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
if (num != p) {
|
|
219
|
+
/* cleaned copy is NUL-terminated */
|
|
220
|
+
} else {
|
|
221
|
+
if (l >= NUM_BUF) {
|
|
222
|
+
return 1;
|
|
223
|
+
}
|
|
224
|
+
memcpy(buf, num, l);
|
|
225
|
+
buf[l] = '\0';
|
|
226
|
+
num = buf;
|
|
227
|
+
}
|
|
228
|
+
/* .inf / .nan family (sign allowed on inf) */
|
|
229
|
+
{
|
|
230
|
+
const char* s = buf;
|
|
231
|
+
size_t sl = l;
|
|
232
|
+
if (s[0] == '-' || s[0] == '+') {
|
|
233
|
+
s++;
|
|
234
|
+
sl--;
|
|
235
|
+
}
|
|
236
|
+
if (sl == 4 && s[0] == '.') {
|
|
237
|
+
if ((s[1] == 'i' || s[1] == 'I') && (s[2] == 'n' || s[2] == 'N') &&
|
|
238
|
+
(s[3] == 'f' || s[3] == 'F')) {
|
|
239
|
+
*out = (buf[0] == '-') ? -INFINITY : INFINITY;
|
|
240
|
+
return 0;
|
|
241
|
+
}
|
|
242
|
+
if ((s[1] == 'n' || s[1] == 'N') && (s[2] == 'a' || s[2] == 'A') &&
|
|
243
|
+
(s[3] == 'n' || s[3] == 'N')) {
|
|
244
|
+
*out = NAN;
|
|
245
|
+
return 0;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/* sexagesimal float — Psych's fold: weights 60**|e-2|, sign on
|
|
250
|
+
* the first component, the fraction on the LAST component
|
|
251
|
+
* (1:30.5 -> 1*3600 + 30.5*60 = 5430.0). */
|
|
252
|
+
if (memchr(buf, ':', l) != NULL) {
|
|
253
|
+
const char* s = buf;
|
|
254
|
+
double sign = 1.0;
|
|
255
|
+
if (s[0] == '-' || s[0] == '+') {
|
|
256
|
+
if (s[0] == '-')
|
|
257
|
+
sign = -1.0;
|
|
258
|
+
s++;
|
|
259
|
+
}
|
|
260
|
+
double v = 0.0;
|
|
261
|
+
const char* q = s;
|
|
262
|
+
while (*q >= '0' && *q <= '9') {
|
|
263
|
+
v = v * 10.0 + (*q - '0');
|
|
264
|
+
q++;
|
|
265
|
+
}
|
|
266
|
+
v *= 3600.0;
|
|
267
|
+
v *= sign;
|
|
268
|
+
int groups = 0;
|
|
269
|
+
double last = 0.0;
|
|
270
|
+
double weight = 60.0;
|
|
271
|
+
for (;;) {
|
|
272
|
+
if (*q != ':' || groups >= 2)
|
|
273
|
+
break;
|
|
274
|
+
q++;
|
|
275
|
+
double g = 0.0;
|
|
276
|
+
int d = 0;
|
|
277
|
+
while (*q >= '0' && *q <= '9') {
|
|
278
|
+
g = g * 10.0 + (*q - '0');
|
|
279
|
+
q++;
|
|
280
|
+
d++;
|
|
281
|
+
}
|
|
282
|
+
if (d == 0) {
|
|
283
|
+
return 1;
|
|
284
|
+
}
|
|
285
|
+
if (*q == '.') {
|
|
286
|
+
double frac = 0.0, scale = 0.1;
|
|
287
|
+
q++;
|
|
288
|
+
while (*q >= '0' && *q <= '9') {
|
|
289
|
+
frac += (*q - '0') * scale;
|
|
290
|
+
scale /= 10.0;
|
|
291
|
+
q++;
|
|
292
|
+
}
|
|
293
|
+
g += frac;
|
|
294
|
+
}
|
|
295
|
+
v += g * weight;
|
|
296
|
+
weight = 1.0; /* e2 */
|
|
297
|
+
last = g;
|
|
298
|
+
groups++;
|
|
299
|
+
}
|
|
300
|
+
(void)last;
|
|
301
|
+
if (groups == 0 || *q != '\0') {
|
|
302
|
+
return 1;
|
|
303
|
+
}
|
|
304
|
+
*out = v;
|
|
305
|
+
return 0;
|
|
306
|
+
}
|
|
307
|
+
char* end = NULL;
|
|
308
|
+
errno = 0;
|
|
309
|
+
double v = strtod(buf, &end);
|
|
310
|
+
if (end == buf || *end != '\0') {
|
|
311
|
+
return 1;
|
|
312
|
+
}
|
|
313
|
+
(void)errno;
|
|
314
|
+
*out = v;
|
|
315
|
+
return 0;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
int yep_num_bool(const char* p, uint32_t len) {
|
|
319
|
+
static const char* k_true[] = {"true", "True", "TRUE", "y", "Y", "yes",
|
|
320
|
+
"Yes", "YES", "on", "On", "ON"};
|
|
321
|
+
for (size_t i = 0; i < sizeof(k_true) / sizeof(k_true[0]); i++) {
|
|
322
|
+
size_t m = strlen(k_true[i]);
|
|
323
|
+
if (len == m && memcmp(p, k_true[i], m) == 0) {
|
|
324
|
+
return 1;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return 0;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
int yep_num_bool_ci(const char* p, uint32_t len) {
|
|
331
|
+
/* the compat resolver matches bool words case-insensitively;
|
|
332
|
+
* truth follows the same rule (Psych's scanner downcases) */
|
|
333
|
+
static const char* k_true[] = {"y", "yes", "true", "on"};
|
|
334
|
+
char buf[8];
|
|
335
|
+
if (len == 0 || len > 5) {
|
|
336
|
+
return 0;
|
|
337
|
+
}
|
|
338
|
+
for (uint32_t i = 0; i < len; i++) {
|
|
339
|
+
char c = p[i];
|
|
340
|
+
buf[i] = (c >= 'A' && c <= 'Z') ? (char)(c + 32) : c;
|
|
341
|
+
}
|
|
342
|
+
for (size_t i = 0; i < sizeof(k_true) / sizeof(k_true[0]); i++) {
|
|
343
|
+
size_t m = strlen(k_true[i]);
|
|
344
|
+
if (len == m && memcmp(buf, k_true[i], m) == 0) {
|
|
345
|
+
return 1;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return 0;
|
|
349
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* numbers.h — the typed-value conversion kernels (TODO.impl/08B).
|
|
2
|
+
*
|
|
3
|
+
* ONE home for text->int64/double/bool: the node typed accessors,
|
|
4
|
+
* the value stream (values.c), and any future consumer ride these.
|
|
5
|
+
* Pure functions over (pointer, length) — no handles, no state. */
|
|
6
|
+
#ifndef YEP_NUMBERS_H
|
|
7
|
+
#define YEP_NUMBERS_H
|
|
8
|
+
|
|
9
|
+
#include <stdint.h>
|
|
10
|
+
#include <yeptris/api.h>
|
|
11
|
+
|
|
12
|
+
#ifdef __cplusplus
|
|
13
|
+
extern "C" {
|
|
14
|
+
#endif
|
|
15
|
+
|
|
16
|
+
/* Separator-carrying YAML number text (digits, '_', ','; radix
|
|
17
|
+
* forms 0x/0o/0b/leading-0; sexagesimal for the compat schema).
|
|
18
|
+
* Returns 0 and sets *out on success, nonzero otherwise. */
|
|
19
|
+
YEPTRIS_API int yep_num_i64(const char* p, uint32_t len, int64_t* out);
|
|
20
|
+
YEPTRIS_API int yep_num_f64(const char* p, uint32_t len, double* out);
|
|
21
|
+
|
|
22
|
+
/* The resolver's true-word set (true/True/TRUE/y/Y/yes/Yes/YES/on/
|
|
23
|
+
* On/ON); anything else the BOOL tag accepted is false. */
|
|
24
|
+
YEPTRIS_API int yep_num_bool(const char* p, uint32_t len);
|
|
25
|
+
|
|
26
|
+
/* Case-insensitive truth (the compat resolver's matching rule). */
|
|
27
|
+
YEPTRIS_API int yep_num_bool_ci(const char* p, uint32_t len);
|
|
28
|
+
|
|
29
|
+
#ifdef __cplusplus
|
|
30
|
+
}
|
|
31
|
+
#endif
|
|
32
|
+
|
|
33
|
+
#endif /* YEP_NUMBERS_H */
|