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,396 @@
|
|
|
1
|
+
/* print.c — the float printer (TODO.impl/14, clean room; see
|
|
2
|
+
* floatint.h for the licensing note and the two-tier design).
|
|
3
|
+
*
|
|
4
|
+
* Public entries decode IEEE bits, dispatch tiers, and render the
|
|
5
|
+
* digit split into the canonical YAML form. The u128 tier carries the
|
|
6
|
+
* same interval logic as dragon.c over machine integers; values whose
|
|
7
|
+
* exact scaled representation exceeds 128 bits fall through to the
|
|
8
|
+
* limb tier (correct for every double/float, slower for extremes).
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#include <math.h>
|
|
12
|
+
#include <string.h>
|
|
13
|
+
|
|
14
|
+
#include "emit/float/floatint.h"
|
|
15
|
+
|
|
16
|
+
/* ---- decode ---- */
|
|
17
|
+
|
|
18
|
+
typedef struct {
|
|
19
|
+
uint64_t m2;
|
|
20
|
+
int e2;
|
|
21
|
+
int pow2_low;
|
|
22
|
+
int negative;
|
|
23
|
+
} yep_fdecode;
|
|
24
|
+
|
|
25
|
+
static int decode_double(double d, yep_fdecode* out) {
|
|
26
|
+
uint64_t bits;
|
|
27
|
+
memcpy(&bits, &d, 8);
|
|
28
|
+
out->negative = (int)(bits >> 63);
|
|
29
|
+
uint32_t exp = (uint32_t)((bits >> 52) & 0x7FF);
|
|
30
|
+
uint64_t mant = bits & 0xFFFFFFFFFFFFFull;
|
|
31
|
+
if (exp == 0x7FF) {
|
|
32
|
+
return 0; /* inf/nan handled by the caller */
|
|
33
|
+
}
|
|
34
|
+
if (exp == 0) {
|
|
35
|
+
out->m2 = mant;
|
|
36
|
+
out->e2 = -1074;
|
|
37
|
+
out->pow2_low = 0; /* subnormals: uniform spacing */
|
|
38
|
+
} else {
|
|
39
|
+
out->m2 = mant | (1ull << 52);
|
|
40
|
+
out->e2 = (int)exp - 1075;
|
|
41
|
+
out->pow2_low = (mant == 0); /* exact power of two */
|
|
42
|
+
}
|
|
43
|
+
return 1;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static int decode_float(float f, yep_fdecode* out) {
|
|
47
|
+
uint32_t bits;
|
|
48
|
+
memcpy(&bits, &f, 4);
|
|
49
|
+
out->negative = (int)(bits >> 31);
|
|
50
|
+
uint32_t exp = (bits >> 23) & 0xFF;
|
|
51
|
+
uint32_t mant = bits & 0x7FFFFF;
|
|
52
|
+
if (exp == 0xFF) {
|
|
53
|
+
return 0;
|
|
54
|
+
}
|
|
55
|
+
if (exp == 0) {
|
|
56
|
+
out->m2 = mant;
|
|
57
|
+
out->e2 = -149;
|
|
58
|
+
out->pow2_low = 0;
|
|
59
|
+
} else {
|
|
60
|
+
out->m2 = mant | (1u << 23);
|
|
61
|
+
out->e2 = (int)exp - 150;
|
|
62
|
+
out->pow2_low = (mant == 0);
|
|
63
|
+
}
|
|
64
|
+
return 1;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* ---- tier A: the interval loop over u128 ---- */
|
|
68
|
+
|
|
69
|
+
typedef struct {
|
|
70
|
+
yep_u128 v;
|
|
71
|
+
int n; /* limb count in 64-bit halves, 1 or 2 */
|
|
72
|
+
} u128v;
|
|
73
|
+
|
|
74
|
+
/* u128_cmp/u128_max/fits10 live in floatint.h — the portable helper
|
|
75
|
+
* surface (MSVC rides the same expressions; no operator arithmetic) */
|
|
76
|
+
#define u128_cmp yep_u128_cmp
|
|
77
|
+
#define fits10(x) yep_u128_fits10(x)
|
|
78
|
+
#define u128_max yep_u128_max()
|
|
79
|
+
|
|
80
|
+
int yep_u128_shortest(uint64_t m2, int e2, int mb, int pow2_low, int tie_even, yep_dsplit* out) {
|
|
81
|
+
yep_u128 r = yep_u128_of(m2), s = yep_u128_of(1), mm = yep_u128_of(1), mp = yep_u128_of(1);
|
|
82
|
+
/* Capacity: every value below must fit 128 bits. For e2 >= 0 the
|
|
83
|
+
* operands grow by 2^e2 (double: e2 <= 75 keeps r < 2^128); for
|
|
84
|
+
* e2 < 0 only s grows (s = 2^-e2 <= 2^96 for the tier range). */
|
|
85
|
+
if (e2 >= 0) {
|
|
86
|
+
if (e2 > 75) {
|
|
87
|
+
return 0;
|
|
88
|
+
}
|
|
89
|
+
r = yep_u128_shl(r, (unsigned)e2);
|
|
90
|
+
if (e2 >= 1) {
|
|
91
|
+
mp = yep_u128_shl(mp, (unsigned)(e2 - 1));
|
|
92
|
+
} else {
|
|
93
|
+
mp = yep_u128_of(1);
|
|
94
|
+
}
|
|
95
|
+
mm = mp;
|
|
96
|
+
if (yep_u128_cmp(r, yep_u128_shr(u128_max, (unsigned)e2)) > 0) {
|
|
97
|
+
return 0; /* shifted out of range */
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
int bits = 1 - e2; /* half-ulp denominator (see dragon.c) */
|
|
101
|
+
if (bits > 96) {
|
|
102
|
+
return 0;
|
|
103
|
+
}
|
|
104
|
+
r = yep_u128_shl(r, 1);
|
|
105
|
+
s = yep_u128_shl(s, (unsigned)bits);
|
|
106
|
+
if (yep_u128_cmp(r, yep_u128_shr(u128_max, 1)) > 0 ||
|
|
107
|
+
yep_u128_cmp(s, yep_u128_shr(u128_max, (unsigned)bits)) > 0) {
|
|
108
|
+
return 0;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (pow2_low) {
|
|
112
|
+
r = yep_u128_shl(r, 1);
|
|
113
|
+
s = yep_u128_shl(s, 1);
|
|
114
|
+
mp = yep_u128_shl(mp, 1);
|
|
115
|
+
if (yep_u128_cmp(r, yep_u128_shr(u128_max, 1)) > 0 ||
|
|
116
|
+
yep_u128_cmp(s, yep_u128_shr(u128_max, 1)) > 0 ||
|
|
117
|
+
yep_u128_cmp(mp, yep_u128_shr(u128_max, 1)) > 0) {
|
|
118
|
+
return 0;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/* digit loop grows r, mm, mp by up to 10^(1 + 17) worst case and s
|
|
122
|
+
* by up to 10^(~22): 128-bit headroom must hold */
|
|
123
|
+
int k = 0;
|
|
124
|
+
{
|
|
125
|
+
yep_u128 rmp = yep_u128_add(r, mp);
|
|
126
|
+
int guard = 0;
|
|
127
|
+
while (u128_cmp(rmp, s) <= 0) {
|
|
128
|
+
if (!fits10(r) || !fits10(mm) || !fits10(mp)) {
|
|
129
|
+
return 0;
|
|
130
|
+
}
|
|
131
|
+
r = yep_u128_mul_small(r, 10);
|
|
132
|
+
mm = yep_u128_mul_small(mm, 10);
|
|
133
|
+
mp = yep_u128_mul_small(mp, 10);
|
|
134
|
+
rmp = yep_u128_add(r, mp);
|
|
135
|
+
k--;
|
|
136
|
+
if (++guard > 24) {
|
|
137
|
+
return 0;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
guard = 0;
|
|
141
|
+
while (u128_cmp(r, s) >= 0) {
|
|
142
|
+
if (!fits10(s)) {
|
|
143
|
+
return 0;
|
|
144
|
+
}
|
|
145
|
+
s = yep_u128_mul_small(s, 10);
|
|
146
|
+
k++;
|
|
147
|
+
if (++guard > 24) {
|
|
148
|
+
return 0;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const int max_digits = (mb >= 52) ? 17 : 9;
|
|
154
|
+
char digits[24];
|
|
155
|
+
int n = 0;
|
|
156
|
+
for (;;) {
|
|
157
|
+
if (!fits10(r) || !fits10(mm) || !fits10(mp)) {
|
|
158
|
+
return 0; /* out of u128 range mid-loop: tier B */
|
|
159
|
+
}
|
|
160
|
+
r = yep_u128_mul_small(r, 10);
|
|
161
|
+
mm = yep_u128_mul_small(mm, 10);
|
|
162
|
+
mp = yep_u128_mul_small(mp, 10);
|
|
163
|
+
int d = 0;
|
|
164
|
+
while (u128_cmp(r, s) >= 0) {
|
|
165
|
+
r = yep_u128_sub(r, s);
|
|
166
|
+
d++;
|
|
167
|
+
}
|
|
168
|
+
digits[n] = (char)('0' + d);
|
|
169
|
+
n++;
|
|
170
|
+
/* an exact boundary hit ties at reparse to the even float —
|
|
171
|
+
* acceptable only when v itself is even (tie_even) */
|
|
172
|
+
int can_down = u128_cmp(r, mm) < 0 || (tie_even && u128_cmp(r, mm) == 0);
|
|
173
|
+
int can_up = u128_cmp(yep_u128_sub(s, r), mp) < 0 ||
|
|
174
|
+
(tie_even && u128_cmp(yep_u128_sub(s, r), mp) == 0);
|
|
175
|
+
if (can_down || can_up) {
|
|
176
|
+
int up;
|
|
177
|
+
if (can_down && can_up) {
|
|
178
|
+
yep_u128 t = yep_u128_add(r, r);
|
|
179
|
+
int c = u128_cmp(t, s);
|
|
180
|
+
up = (c > 0) || (c == 0 && (d % 2) != 0);
|
|
181
|
+
} else {
|
|
182
|
+
up = can_up;
|
|
183
|
+
}
|
|
184
|
+
if (up) {
|
|
185
|
+
int i = n - 1;
|
|
186
|
+
for (;;) {
|
|
187
|
+
if (digits[i] != '9') {
|
|
188
|
+
digits[i]++;
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
digits[i] = '0';
|
|
192
|
+
if (i == 0) {
|
|
193
|
+
for (int j = n; j > 0; j--) {
|
|
194
|
+
digits[j] = digits[j - 1];
|
|
195
|
+
}
|
|
196
|
+
digits[0] = '1';
|
|
197
|
+
n++;
|
|
198
|
+
k++;
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
i--;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
if (n >= max_digits) {
|
|
207
|
+
break; /* 17 (9) significant digits always round-trip */
|
|
208
|
+
}
|
|
209
|
+
if (n >= 23) {
|
|
210
|
+
return 0;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
memcpy(out->digits, digits, (size_t)n);
|
|
214
|
+
out->len = n;
|
|
215
|
+
out->k = k;
|
|
216
|
+
return 1;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/* ---- rendering ---- */
|
|
220
|
+
|
|
221
|
+
int yep_float_render(const yep_dsplit* ds, int negative, char* buf) {
|
|
222
|
+
int o = 0;
|
|
223
|
+
if (negative) {
|
|
224
|
+
buf[o++] = '-';
|
|
225
|
+
}
|
|
226
|
+
const char* d = ds->digits;
|
|
227
|
+
int len = ds->len;
|
|
228
|
+
int k = ds->k;
|
|
229
|
+
if (len == 1 && d[0] == '0') {
|
|
230
|
+
memcpy(buf + o, "0.0", 3);
|
|
231
|
+
return o + 3;
|
|
232
|
+
}
|
|
233
|
+
/* plain notation for 10^-4 <= |v| < 10^16 (k in [-3, 16]) */
|
|
234
|
+
if (k >= -3 && k <= 16) {
|
|
235
|
+
if (k <= 0) {
|
|
236
|
+
buf[o++] = '0';
|
|
237
|
+
buf[o++] = '.';
|
|
238
|
+
for (int i = 0; i < -k; i++) {
|
|
239
|
+
buf[o++] = '0';
|
|
240
|
+
}
|
|
241
|
+
memcpy(buf + o, d, (size_t)len);
|
|
242
|
+
return o + len;
|
|
243
|
+
}
|
|
244
|
+
if (k < len) {
|
|
245
|
+
memcpy(buf + o, d, (size_t)k);
|
|
246
|
+
buf[o + k] = '.';
|
|
247
|
+
memcpy(buf + o + k + 1, d + k, (size_t)(len - k));
|
|
248
|
+
return o + len + 1;
|
|
249
|
+
}
|
|
250
|
+
memcpy(buf + o, d, (size_t)len);
|
|
251
|
+
for (int i = 0; i < k - len; i++) {
|
|
252
|
+
buf[o + len + i] = '0';
|
|
253
|
+
}
|
|
254
|
+
int end = o + k;
|
|
255
|
+
buf[end] = '.';
|
|
256
|
+
buf[end + 1] = '0';
|
|
257
|
+
return end + 2;
|
|
258
|
+
}
|
|
259
|
+
/* scientific: d.dddde[+-]XX, at least one fraction digit */
|
|
260
|
+
buf[o++] = d[0];
|
|
261
|
+
buf[o++] = '.';
|
|
262
|
+
if (len == 1) {
|
|
263
|
+
buf[o++] = '0';
|
|
264
|
+
} else {
|
|
265
|
+
memcpy(buf + o, d + 1, (size_t)(len - 1));
|
|
266
|
+
o += len - 1;
|
|
267
|
+
}
|
|
268
|
+
buf[o++] = 'e';
|
|
269
|
+
int e = k - 1;
|
|
270
|
+
if (e < 0) {
|
|
271
|
+
buf[o++] = '-';
|
|
272
|
+
e = -e;
|
|
273
|
+
} else {
|
|
274
|
+
buf[o++] = '+';
|
|
275
|
+
}
|
|
276
|
+
char er[8];
|
|
277
|
+
int en = 0;
|
|
278
|
+
while (e > 0) {
|
|
279
|
+
er[en++] = (char)('0' + e % 10);
|
|
280
|
+
e /= 10;
|
|
281
|
+
}
|
|
282
|
+
if (en == 0) {
|
|
283
|
+
er[en++] = '0';
|
|
284
|
+
}
|
|
285
|
+
if (en == 1) {
|
|
286
|
+
er[en++] = '0'; /* two-digit minimum: 1.0e-07, Float#to_s shape */
|
|
287
|
+
}
|
|
288
|
+
for (int i = 0; i < en; i++) {
|
|
289
|
+
buf[o++] = er[en - 1 - i];
|
|
290
|
+
}
|
|
291
|
+
return o;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/* ---- public entries ---- */
|
|
295
|
+
|
|
296
|
+
int yep_d2s_shortest(double d, char* buf) {
|
|
297
|
+
yep_fdecode dec;
|
|
298
|
+
if (!decode_double(d, &dec)) {
|
|
299
|
+
return 0; /* non-finite: the caller consults yep_d2s_nonfinite */
|
|
300
|
+
}
|
|
301
|
+
if (dec.m2 == 0) {
|
|
302
|
+
int o = dec.negative;
|
|
303
|
+
if (dec.negative) {
|
|
304
|
+
buf[0] = '-';
|
|
305
|
+
}
|
|
306
|
+
memcpy(buf + o, "0.0", 3);
|
|
307
|
+
return o + 3;
|
|
308
|
+
}
|
|
309
|
+
yep_dsplit ds;
|
|
310
|
+
int tie_even = (dec.m2 % 2) == 0;
|
|
311
|
+
if (!yep_u128_shortest(dec.m2, dec.e2, 52, dec.pow2_low, tie_even, &ds)) {
|
|
312
|
+
if (yep_dragon_shortest(dec.m2, dec.e2, 52, dec.pow2_low, tie_even, &ds) != 0) {
|
|
313
|
+
return 0;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return yep_float_render(&ds, dec.negative, buf);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
int yep_f2s_shortest(float f, char* buf) {
|
|
320
|
+
yep_fdecode dec;
|
|
321
|
+
if (!decode_float(f, &dec)) {
|
|
322
|
+
return 0;
|
|
323
|
+
}
|
|
324
|
+
if (dec.m2 == 0) {
|
|
325
|
+
int o = dec.negative;
|
|
326
|
+
if (dec.negative) {
|
|
327
|
+
buf[0] = '-';
|
|
328
|
+
}
|
|
329
|
+
memcpy(buf + o, "0.0", 3);
|
|
330
|
+
return o + 3;
|
|
331
|
+
}
|
|
332
|
+
yep_dsplit ds;
|
|
333
|
+
int tie_even = (dec.m2 % 2) == 0;
|
|
334
|
+
if (!yep_u128_shortest(dec.m2, dec.e2, 23, dec.pow2_low, tie_even, &ds)) {
|
|
335
|
+
if (yep_dragon_shortest(dec.m2, dec.e2, 23, dec.pow2_low, tie_even, &ds) != 0) {
|
|
336
|
+
return 0;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
return yep_float_render(&ds, dec.negative, buf);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
int yep_d2fixed(double d, uint32_t precision, char* buf) {
|
|
343
|
+
if (!isfinite(d)) {
|
|
344
|
+
int n = yep_d2s_nonfinite(d, buf);
|
|
345
|
+
if (n == 0) {
|
|
346
|
+
return 0;
|
|
347
|
+
}
|
|
348
|
+
/* fixed notation of non-finite is the word itself */
|
|
349
|
+
return n;
|
|
350
|
+
}
|
|
351
|
+
yep_fdecode dec;
|
|
352
|
+
decode_double(d, &dec);
|
|
353
|
+
if (dec.m2 == 0) {
|
|
354
|
+
int o = 0;
|
|
355
|
+
if (dec.negative && precision > 0) {
|
|
356
|
+
buf[o++] = '-';
|
|
357
|
+
}
|
|
358
|
+
buf[o++] = '0';
|
|
359
|
+
if (precision > 0) {
|
|
360
|
+
buf[o++] = '.';
|
|
361
|
+
for (uint32_t i = 0; i < precision; i++) {
|
|
362
|
+
buf[o++] = '0';
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
return o;
|
|
366
|
+
}
|
|
367
|
+
/* sign applies after digit production (printf prints -0.00) */
|
|
368
|
+
char tmp[512];
|
|
369
|
+
int n = yep_dragon_fixed(dec.m2, dec.e2, precision, tmp);
|
|
370
|
+
if (n <= 0) {
|
|
371
|
+
return n;
|
|
372
|
+
}
|
|
373
|
+
if (dec.negative) {
|
|
374
|
+
buf[0] = '-';
|
|
375
|
+
memcpy(buf + 1, tmp, (size_t)n);
|
|
376
|
+
return n + 1;
|
|
377
|
+
}
|
|
378
|
+
memcpy(buf, tmp, (size_t)n);
|
|
379
|
+
return n;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
int yep_d2s_nonfinite(double d, char* buf) {
|
|
383
|
+
if (isnan(d)) {
|
|
384
|
+
memcpy(buf, ".nan", 4);
|
|
385
|
+
return 4;
|
|
386
|
+
}
|
|
387
|
+
if (isinf(d)) {
|
|
388
|
+
if (d < 0) {
|
|
389
|
+
memcpy(buf, "-.inf", 5);
|
|
390
|
+
return 5;
|
|
391
|
+
}
|
|
392
|
+
memcpy(buf, ".inf", 4);
|
|
393
|
+
return 4;
|
|
394
|
+
}
|
|
395
|
+
return 0;
|
|
396
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/* style.c — the style rule table (TODO.impl/13). */
|
|
2
|
+
|
|
3
|
+
#include "style.h"
|
|
4
|
+
|
|
5
|
+
#include <string.h>
|
|
6
|
+
|
|
7
|
+
static int is_blank(char c) {
|
|
8
|
+
return c == ' ' || c == '\t';
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
static int is_break(char c) {
|
|
12
|
+
return c == '\n' || c == '\r';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
int yep_style_plain_safe(const char* p, uint32_t len) {
|
|
16
|
+
if (len == 0) {
|
|
17
|
+
return 0; /* empty needs quotes or an empty-value slot */
|
|
18
|
+
}
|
|
19
|
+
if (is_blank(p[0]) || is_blank(p[len - 1])) {
|
|
20
|
+
return 0;
|
|
21
|
+
}
|
|
22
|
+
switch (p[0]) {
|
|
23
|
+
case ':':
|
|
24
|
+
/* libyaml (Psych symbol dumps ":name"): a leading colon only
|
|
25
|
+
* indicates when followed by a blank/EOL — the interior rule
|
|
26
|
+
* below covers it; ":name" stays plain */
|
|
27
|
+
break;
|
|
28
|
+
case '-':
|
|
29
|
+
case '?':
|
|
30
|
+
/* indicators only before a blank or EOL: "-5" and "?x" are
|
|
31
|
+
* plain (libyaml emits negative numbers plain; Psych, too) */
|
|
32
|
+
return !(len == 1 || is_blank(p[1]));
|
|
33
|
+
case ',':
|
|
34
|
+
case '[':
|
|
35
|
+
case ']':
|
|
36
|
+
case '{':
|
|
37
|
+
case '}':
|
|
38
|
+
case '#':
|
|
39
|
+
case '&':
|
|
40
|
+
case '*':
|
|
41
|
+
case '!':
|
|
42
|
+
case '|':
|
|
43
|
+
case '>':
|
|
44
|
+
case '\'':
|
|
45
|
+
case '"':
|
|
46
|
+
case '%':
|
|
47
|
+
case '@':
|
|
48
|
+
case '`':
|
|
49
|
+
return 0;
|
|
50
|
+
default:
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
for (uint32_t i = 0; i < len; i++) {
|
|
54
|
+
char c = p[i];
|
|
55
|
+
if (is_break(c) || c == '\t') {
|
|
56
|
+
return 0;
|
|
57
|
+
}
|
|
58
|
+
if (c == ':') {
|
|
59
|
+
if (i + 1 >= len || is_blank(p[i + 1])) {
|
|
60
|
+
return 0;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (c == '#') {
|
|
64
|
+
if (i > 0 && is_blank(p[i - 1])) {
|
|
65
|
+
return 0;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/* document markers */
|
|
70
|
+
if ((len == 3 && (memcmp(p, "---", 3) == 0 || memcmp(p, "...", 3) == 0))) {
|
|
71
|
+
return 0;
|
|
72
|
+
}
|
|
73
|
+
return 1;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
int yep_style_plain_key_safe(const char* p, uint32_t len) {
|
|
77
|
+
/* plain_safe's colon rule is the key rule too: a colon only ends a
|
|
78
|
+
* key when followed by a blank/EOL, so "a:b" and ":name" are plain
|
|
79
|
+
* keys (libyaml emits Psych's symbol dumps exactly this way) */
|
|
80
|
+
return yep_style_plain_safe(p, len);
|
|
81
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/* style.h — emission style rules (TODO.impl/13).
|
|
2
|
+
*
|
|
3
|
+
* The parse-recorded style is the SSOT of "what this scalar is like";
|
|
4
|
+
* these rules decide re-emission safety and fresh-value choices. A
|
|
5
|
+
* rule is a predicate over bytes — the table, not a branch soup, is
|
|
6
|
+
* where new rules land (OCP).
|
|
7
|
+
*/
|
|
8
|
+
#ifndef YEP_EMIT_STYLE_H
|
|
9
|
+
#define YEP_EMIT_STYLE_H
|
|
10
|
+
|
|
11
|
+
#include <stdint.h>
|
|
12
|
+
|
|
13
|
+
/* A plain scalar may be re-emitted plain only when every byte is safe
|
|
14
|
+
* in ANY position of a block context: no leading/trailing space, no
|
|
15
|
+
* indicator first byte, no ": " / " #" inside, no tab, no break, and
|
|
16
|
+
* the value is not a document marker or the empty-string corner that
|
|
17
|
+
* needs quotes (empty plain emits as an empty value instead). */
|
|
18
|
+
int yep_style_plain_safe(const char* p, uint32_t len);
|
|
19
|
+
|
|
20
|
+
/* A plain scalar is key-safe when it may sit directly before ':'
|
|
21
|
+
* (plain_safe plus: no ':' at all unless followed by a non-blank). */
|
|
22
|
+
int yep_style_plain_key_safe(const char* p, uint32_t len);
|
|
23
|
+
|
|
24
|
+
#endif /* YEP_EMIT_STYLE_H */
|