leptris 1.9.193.0 → 1.9.193.2

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: d8b1ffa2c04d15482319b91021017e096e8199d6919071ff94c8532af66f0b4d
4
- data.tar.gz: bcbbca3c40e50c5d4c42c167f991267f8a670730dfe321c586292d0e201de0f6
3
+ metadata.gz: a1403106ca3fcdf3f417fccf03e36a651e99282294f8689c793483cb8e1ae86d
4
+ data.tar.gz: 0103b3de1a79e13aebf6c8f1710050857c8430696c9a4d5c5d63d186f049573c
5
5
  SHA512:
6
- metadata.gz: 7d0ff9f39131c9f66ed2e9f9cc41a266160f917a6edd90c15629e468e88230de2ad68bcaaecfdd7f60ddb62eec4888ab1d2a2800bcb32c77b27cfd01fef49a31
7
- data.tar.gz: 04ca510ed71d9d59b58d1b49f9d3875fe134d853612fc7e582889e8821902440de01f096b38dad93a7c9279afa510b2e311790e919ee322b7ba77a07ebd74774
6
+ metadata.gz: 50033a452f4d59d8ae42c89b58f9fbea1a4aa8567aa75bafe04f9d4fbb5761a6a98a374799bf3c189f2f5f224d5a5ca3053d35d4cf7625f4473b459c8d3e385d
7
+ data.tar.gz: 2329a71cc2a7a7c7f390ea9021b9cd18dcb1d232845f5ce03b1ebe3b0ec2afa9d0e09b3df320c7d54d9a0380428c2ceeddb336baf0884f7ba8c0c36f78cd4bbc
data/CHANGELOG.md CHANGED
@@ -5,6 +5,22 @@ All notable changes to Leptris will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.9.193.0] - 2026-09-17
9
+
10
+ ### Changed — libleptris 1.9.192 -> 1.9.193 (lockstep)
11
+
12
+ - Engine build hygiene: explicit includes — stdint.h in arena.c,
13
+ unistd.h in cli/output.c (leptris/leptris#1166). Under any
14
+ feature-macro shift (_GNU_SOURCE on the PGO trainer) the old
15
+ transitive-include graph broke the build; both musl platform-gem
16
+ legs now compile clean. The binding additionally forces
17
+ -include stdint.h on the throwaway trainer build (belt and
18
+ suspenders).
19
+ - No public-symbol changes: audit 323/323. The 1.9.193.0 gem is
20
+ the first published release since 1.9.188.0 (the 1.9.188.x PGO
21
+ attempts never passed the musl legs) and carries the full
22
+ 1.9.189-192 RNG wave plus the two-stage PGO library build.
23
+
8
24
  ## [1.9.192.0] - 2026-09-17
9
25
 
10
26
  ### Changed — libleptris 1.9.188 → 1.9.192 (lockstep)
data/Rakefile CHANGED
@@ -117,10 +117,13 @@ task :compile do
117
117
  # _GNU_SOURCE is MUSL-ONLY: the CLI trainer's fileno needs a POSIX
118
118
  # feature macro under musl. On glibc the macro reshuffles the
119
119
  # header graph and breaks arena.c's accidental (missing-stdint.h)
120
- # uintptr_t. Single-quote: the value carries a space (an unquoted
121
- # split hands cmake a bare -D_GNU_SOURCE); non-Windows branch, so
122
- # sh quoting is safe.
123
- gnu = RUBY_PLATFORM =~ /musl/ ? " -D_GNU_SOURCE" : ""
120
+ # uintptr_t. -include stdint.h: under _GNU_SOURCE musl's header
121
+ # graph ALSO stops feeding stdint.h to arena.c (leptris/leptris
122
+ # #1166) force the include on the throwaway trainer build;
123
+ # the shipped library keeps the plain flags. Single-quote: the
124
+ # value carries a space (an unquoted split hands cmake a bare
125
+ # -D_GNU_SOURCE); non-Windows branch, so sh quoting is safe.
126
+ gnu = RUBY_PLATFORM =~ /musl/ ? " -D_GNU_SOURCE -include stdint.h" : ""
124
127
  pgo_cflags = "#{cflags}#{gnu}".strip
125
128
  pgo_base =
126
129
  if pgo_cflags == cflags
@@ -120,6 +120,7 @@ static ID id_iv_c_address, id_iv_native_cache, id_iv_binding_cache;
120
120
  static ID id_iv_version, id_iv_readonly, id_address;
121
121
  static ID id_iv_nn_content, id_iv_nn_content_ver;
122
122
  static ID id_iv_nn_attrs, id_iv_nn_attrs_ver;
123
+ static ID id_child_klasses;
123
124
  static VALUE c_use_after_free_error;
124
125
 
125
126
  static VALUE native_cache_of(VALUE document);
@@ -366,6 +367,42 @@ static VALUE nn_allocate(VALUE klass)
366
367
  return TypedData_Make_Struct(klass, struct native_node, &nn_type, n);
367
368
  }
368
369
 
370
+ /* Klass-propagating reads (#246): a consumer subclass installed a
371
+ * per-kind child-klass map; reads mint that class so the child
372
+ * arrives already being the consumer's wrapper. Map-less callers
373
+ * (the base class) keep today's base mint. */
374
+ static VALUE klass_for_kind(VALUE owner_klass, int kind)
375
+ {
376
+ VALUE map = rb_attr_get(owner_klass, id_child_klasses);
377
+ VALUE k;
378
+ if (NIL_P(map))
379
+ return c_native_node;
380
+ k = rb_ary_entry(map, (long)kind);
381
+ return RB_TYPE_P(k, T_CLASS) ? k : c_native_node;
382
+ }
383
+
384
+ static VALUE nn_install_child_klasses(VALUE self, VALUE map)
385
+ {
386
+ long i, len;
387
+ Check_Type(map, T_ARRAY);
388
+ len = RARRAY_LEN(map);
389
+ if (len > 5)
390
+ rb_raise(rb_eArgError,
391
+ "child klasses: Array of classes/nil indexed by "
392
+ "node kind (element, text, comment, cdata, pi)");
393
+ for (i = 0; i < len; i++) {
394
+ VALUE k = rb_ary_entry(map, i);
395
+ if (!NIL_P(k) &&
396
+ !(RB_TYPE_P(k, T_CLASS) &&
397
+ RTEST(rb_class_inherited_p(k, c_native_node))))
398
+ rb_raise(rb_eTypeError,
399
+ "child klasses entries must be nil or a "
400
+ "Leptris::XML::NativeNode subclass");
401
+ }
402
+ rb_ivar_set(self, id_child_klasses, map);
403
+ return self;
404
+ }
405
+
369
406
  /* Bulk children: one native pass; cache check/store inline; the
370
407
  * document's wrapper_cache (a Ruby Hash keyed by address) provides
371
408
  * identity for nodes seen through other paths. */
@@ -401,7 +438,7 @@ static VALUE nn_children(VALUE self)
401
438
  void **buf;
402
439
  int *kinds;
403
440
  int count, i;
404
- VALUE cache, out;
441
+ VALUE cache, out, owner_klass;
405
442
 
406
443
  TypedData_Get_Struct(self, struct native_node, &nn_type, n);
407
444
  count = fetch_children_two_call(n->ptr, &buf, &kinds);
@@ -413,13 +450,14 @@ static VALUE nn_children(VALUE self)
413
450
 
414
451
  cache = native_cache_of(n->document);
415
452
  out = rb_ary_new2(count);
453
+ owner_klass = rb_obj_class(self);
416
454
  for (i = 0; i < count; i++) {
417
455
  uint64_t addr = (uint64_t)(uintptr_t)buf[i];
418
456
  VALUE key = ULL2NUM(addr);
419
457
  VALUE child = rb_hash_aref(cache, key);
420
458
  if (NIL_P(child)) {
421
459
  struct native_node *cn;
422
- child = nn_allocate(c_native_node);
460
+ child = nn_allocate(klass_for_kind(owner_klass, kinds[i]));
423
461
  TypedData_Get_Struct(child, struct native_node, &nn_type, cn);
424
462
  cn->ptr = buf[i];
425
463
  cn->document = n->document;
@@ -454,7 +492,7 @@ static VALUE nn_element_children(VALUE self)
454
492
  void **buf;
455
493
  int *kinds;
456
494
  int count, i;
457
- VALUE cache, out;
495
+ VALUE cache, out, child_klass;
458
496
 
459
497
  TypedData_Get_Struct(self, struct native_node, &nn_type, n);
460
498
  count = fetch_children_two_call(n->ptr, &buf, &kinds);
@@ -466,6 +504,7 @@ static VALUE nn_element_children(VALUE self)
466
504
 
467
505
  cache = native_cache_of(n->document);
468
506
  out = rb_ary_new();
507
+ child_klass = klass_for_kind(rb_obj_class(self), NT_ELEMENT);
469
508
  for (i = 0; i < count; i++) {
470
509
  if (kinds[i] != NT_ELEMENT)
471
510
  continue;
@@ -473,7 +512,7 @@ static VALUE nn_element_children(VALUE self)
473
512
  VALUE child = rb_hash_aref(cache, key);
474
513
  if (NIL_P(child)) {
475
514
  struct native_node *cn;
476
- child = nn_allocate(c_native_node);
515
+ child = nn_allocate(child_klass);
477
516
  TypedData_Get_Struct(child, struct native_node, &nn_type, cn);
478
517
  cn->ptr = buf[i];
479
518
  cn->document = n->document;
@@ -486,7 +525,8 @@ static VALUE nn_element_children(VALUE self)
486
525
  return out;
487
526
  }
488
527
 
489
- static VALUE wrap_cached(struct native_node *owner, void *ptr)
528
+ static VALUE wrap_cached(VALUE owner_klass, struct native_node *owner,
529
+ void *ptr)
490
530
  {
491
531
  VALUE cache, key, node;
492
532
  struct native_node *n;
@@ -496,7 +536,7 @@ static VALUE wrap_cached(struct native_node *owner, void *ptr)
496
536
  node = rb_hash_aref(cache, key);
497
537
  if (!NIL_P(node))
498
538
  return node;
499
- node = nn_allocate(c_native_node);
539
+ node = nn_allocate(klass_for_kind(owner_klass, f_node_type(ptr)));
500
540
  TypedData_Get_Struct(node, struct native_node, &nn_type, n);
501
541
  n->ptr = ptr;
502
542
  n->document = owner->document;
@@ -510,7 +550,7 @@ static VALUE nn_next_sibling(VALUE self)
510
550
  void *sib;
511
551
  TypedData_Get_Struct(self, struct native_node, &nn_type, n);
512
552
  sib = f_next_sibling(n->ptr);
513
- return sib ? wrap_cached(n, sib) : Qnil;
553
+ return sib ? wrap_cached(rb_obj_class(self), n, sib) : Qnil;
514
554
  }
515
555
 
516
556
  static VALUE nn_parent(VALUE self)
@@ -519,7 +559,7 @@ static VALUE nn_parent(VALUE self)
519
559
  void *par;
520
560
  TypedData_Get_Struct(self, struct native_node, &nn_type, n);
521
561
  par = f_parent(n->ptr);
522
- return par ? wrap_cached(n, par) : Qnil;
562
+ return par ? wrap_cached(rb_obj_class(self), n, par) : Qnil;
523
563
  }
524
564
 
525
565
  /* Wrap a freshly-created C node as a NativeNode and register it
@@ -2281,6 +2321,7 @@ void Init_native(void)
2281
2321
  id_iv_nn_content_ver = rb_intern("@nn_content_ver");
2282
2322
  id_iv_nn_attrs = rb_intern("@nn_attrs");
2283
2323
  id_iv_nn_attrs_ver = rb_intern("@nn_attrs_ver");
2324
+ id_child_klasses = rb_intern("@nn_child_klasses");
2284
2325
  id_iv_doc_handle = rb_intern("@doc_handle");
2285
2326
  id_freed_new = rb_intern("new");
2286
2327
  id_alive = rb_intern("alive");
@@ -2291,6 +2332,8 @@ void Init_native(void)
2291
2332
  rb_gc_register_mark_object(c_use_after_free_error);
2292
2333
 
2293
2334
  rb_define_singleton_method(c_native_node, "from", nn_from, 2);
2335
+ rb_define_singleton_method(c_native_node, "install_child_klasses",
2336
+ nn_install_child_klasses, 1);
2294
2337
  rb_define_singleton_method(c_native_node, "create_element", nn_create_element, 2);
2295
2338
  rb_define_singleton_method(c_native_node, "create_text", nn_create_text, 2);
2296
2339
  rb_define_singleton_method(c_native_node, "set_root", nn_set_root, 2);
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Leptris
4
- VERSION = "1.9.193.0"
4
+ VERSION = "1.9.193.2"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leptris
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.193.0
4
+ version: 1.9.193.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.