yeptris 0.6.37.0 → 0.6.39.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 21d7aeafdf87354e93274fd18b06de28ce461ae8cc05e6099db13b4fc4015c2a
4
- data.tar.gz: 6023fd4222e75a11e1af43f29428a62dc53e40f6115eff376c2967a165fbea4d
3
+ metadata.gz: 4090bc7b6300956011d45957cc060d06e93e5e737afaf0c8b58366c809771019
4
+ data.tar.gz: 1b15dcbefa1d6520c58479056eedfb6d1e4a3c39992b7da15ac90b00ebf08eca
5
5
  SHA512:
6
- metadata.gz: e4f2edd4df325413745e537f097a84f08607839c63f40a8737b5381429e7e85ebe47bdfd0bb16a4b028d9967df3bb7cabc6716ce1525b3558bb31563f5b37a50
7
- data.tar.gz: ca9a4a7e1f14025dfb9d3b42b7a7a1cf9c51fda65a6a49e0c6287a23dbf1e9cc0dfb02f4fd38ec6eaa272a6e298aaa7b6c24cee496a59665bbab622316914cfe
6
+ metadata.gz: 6b2f075e359a046945be8fcedbca6c00f1eb3e54e3ba1f94d8997ef03709e2ba14f625864c87a6efc859c236afe1ad6b28e5cfa6810581af3dba7c9602491609
7
+ data.tar.gz: 9d173d7b9331869c3a6e26e0c7072280cc01c760d2fb43958ac08dc61d50636284ea4f191307e472e7b0982dd2af9967c0800c82d68b401f4c25ad8621a0b829
data/lib/yeptris.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  module Yeptris
4
4
  # The gem's version lives in the parent namespace's file — the last
5
5
  # internal require (yeptris/version) retired with it.
6
- VERSION = "0.6.37.0".freeze
6
+ VERSION = "0.6.39.1".freeze
7
7
 
8
8
  # Informational notices are OPT-IN (yeptris-ruby#217): consumers
9
9
  # embed yeptris inside CLIs that assert clean stderr, and a
@@ -3,7 +3,7 @@
3
3
  cmake_minimum_required(VERSION 3.20)
4
4
 
5
5
  project(yeptris
6
- VERSION 0.6.37
6
+ VERSION 0.6.39
7
7
  DESCRIPTION "Ultra-fast YAML 1.2 parser, emitter and streamer in C"
8
8
  LANGUAGES C CXX
9
9
  )
@@ -346,7 +346,37 @@ static void emit_literal(yep_writer* w, const yep_dnode* n, int parent_col) {
346
346
  wr_indent(w, pad);
347
347
  }
348
348
  }
349
- for (uint32_t i = 0; i < trail; i++) {
349
+ /* The reader swallows the own break of a WHITESPACE-ONLY
350
+ * more-indented last line ("|+\n:\n \t\n\n\n" reads trail=2), so
351
+ * the spelling needs one extra break there -- written N reads N-1
352
+ * (the nightly's round 32, crash-90c98918: pass1
353
+ * "|+\n :\n \t\n\n" re-parsed one break short and the second
354
+ * pass emitted clip). A regular last line reads 1:1. */
355
+ uint32_t ls = body;
356
+ while (ls > 0 && p[ls - 1] != '\n') {
357
+ ls--;
358
+ }
359
+ int tab_last = 0;
360
+ int ws_last = 1;
361
+ for (uint32_t i = ls; i < body; i++) {
362
+ if (p[i] == '\t') {
363
+ tab_last = 1;
364
+ } else if (p[i] != ' ') {
365
+ ws_last = 0;
366
+ break;
367
+ }
368
+ }
369
+ /* the reader swallows the own break of a whitespace-only last line
370
+ * that carries a TAB (the tab-indent law shifts the line's content
371
+ * start): "|+\n:\n \t\n\n\n" reads trail=2 where a spaces-only
372
+ * line reads 1:1 (the nightly's round 32, crash-90c98918: pass1
373
+ * "|+\n :\n \t\n\n" re-parsed one break short and the second
374
+ * pass emitted clip). One extra break spells the tab case — and
375
+ * ONLY that case: a CONTENT last line that merely carries a tab
376
+ * ("|+\n \t:\n..." — the round-33 composite, crash-306b67eb)
377
+ * reads its own break 1:1, and the extra break made the value
378
+ * GROW one break per pass. */
379
+ for (uint32_t i = 0; i < trail + ((tab_last && ws_last) ? 1 : 0); i++) {
350
380
  wr_byte(w, '\n');
351
381
  }
352
382
  }
@@ -663,6 +693,19 @@ static void emit_anchor_ex(yep_emitter* em, const yep_dnode* n) {
663
693
  if (n->anchor.len == 0) {
664
694
  return;
665
695
  }
696
+ /* A name ending in ':' rides or separates context-dependently
697
+ * (2SXE): spelled directly before a collection ("&: [[]]", the
698
+ * nightly's round 31, crash-66a513ea; "k: &: [[1]]" fails its own
699
+ * re-parse the same way) every spelling re-lexes differently --
700
+ * the riding/yield law reads the colon as the key indicator at
701
+ * the follower, so the tree changes or the parse dies. A scalar
702
+ * node keeps riding raw ("k: &n: v" round-trips byte-stably).
703
+ * There is no spell for the collection form: fail the serialize. */
704
+ yep_view chk = wv(w, n->anchor);
705
+ if (n->kind != 0 && chk.len > 0 && chk.p[chk.len - 1] == ':') {
706
+ w->unserializable = 1;
707
+ return;
708
+ }
666
709
  wr_byte(w, '&');
667
710
  yep_view adec = wv(w, n->anchor);
668
711
  if (w->canonical) {
@@ -1276,10 +1276,12 @@ static void e_props(yep_engine* e, yep_view* anchor, yep_view* tag) {
1276
1276
  return;
1277
1277
  }
1278
1278
  /* The flow-follower colon law (the nightly's round 29,
1279
- * crash-47eb4054): a name ending at a riding colon whose
1280
- * follower is a FLOW collection un-consumes the colon.
1281
- * libyaml ACCEPTS "&k2: [1,\n2]" — the anchor names the
1282
- * implicit-null KEY and the flow is the value — so the
1279
+ * crash-47eb4054; the block-header twin is round 31,
1280
+ * crash-4cbeede1): a name ending at a riding colon whose
1281
+ * follower is a FLOW collection or a BLOCK SCALAR HEADER
1282
+ * un-consumes the colon. libyaml ACCEPTS "&k2: [1,\n2]"
1283
+ * and "&kk: |\n x" — the anchor names the implicit-null
1284
+ * KEY and the collection/scalar is the value — so the
1283
1285
  * riding law (2SXE) must yield exactly where its result
1284
1286
  * is observable in the differential; the plain-led twins
1285
1287
  * keep it (libyaml rejects those: "&a: key: v", W5VH's
@@ -1287,11 +1289,32 @@ static void e_props(yep_engine* e, yep_view* anchor, yep_view* tag) {
1287
1289
  * re-lexes as the key indicator and the existing colon
1288
1290
  * arm builds the anchored null key. */
1289
1291
  if (e->p[e->pos - 1] == ':') {
1292
+ /* the follower scan crosses blanks, breaks AND
1293
+ * comments: the pair separator at line end still opens
1294
+ * the value on a later line ("&k:\n {\n}" — the
1295
+ * nightly's round 31, crash-c2232e17 — rode the colon
1296
+ * and DROPPED the flow map; "&: #c\n|\nA" — round
1297
+ * 32's crash-d580b467 — stopped at the comment, rode
1298
+ * the colon into the anchor name and pass1/pass2
1299
+ * spelled different trees). A comment is
1300
+ * blank-equivalent here: skip it to its break and keep
1301
+ * scanning. */
1290
1302
  size_t t = e->pos;
1291
- while (t < e->len && (e->p[t] == ' ' || e->p[t] == '\t')) {
1292
- t++;
1303
+ for (;;) {
1304
+ while (t < e->len && (e->p[t] == ' ' || e->p[t] == '\t' || e->p[t] == '\n' ||
1305
+ e->p[t] == '\r')) {
1306
+ t++;
1307
+ }
1308
+ if (t < e->len && e->p[t] == '#') {
1309
+ while (t < e->len && e->p[t] != '\n' && e->p[t] != '\r') {
1310
+ t++;
1311
+ }
1312
+ continue;
1313
+ }
1314
+ break;
1293
1315
  }
1294
- if (t < e->len && (e->p[t] == '[' || e->p[t] == '{')) {
1316
+ if (t < e->len &&
1317
+ (e->p[t] == '[' || e->p[t] == '{' || e->p[t] == '|' || e->p[t] == '>')) {
1295
1318
  anchor->len -= 1;
1296
1319
  e->pos -= 1;
1297
1320
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yeptris
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.37.0
4
+ version: 0.6.39.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-10-22 00:00:00.000000000 Z
11
+ date: 2026-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi