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 +4 -4
- data/CHANGELOG.md +16 -0
- data/Rakefile +7 -4
- data/ext/leptris/native/native.c +51 -8
- data/lib/leptris/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a1403106ca3fcdf3f417fccf03e36a651e99282294f8689c793483cb8e1ae86d
|
|
4
|
+
data.tar.gz: 0103b3de1a79e13aebf6c8f1710050857c8430696c9a4d5c5d63d186f049573c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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.
|
|
121
|
-
#
|
|
122
|
-
#
|
|
123
|
-
|
|
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
|
data/ext/leptris/native/native.c
CHANGED
|
@@ -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(
|
|
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(
|
|
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,
|
|
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(
|
|
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);
|
data/lib/leptris/version.rb
CHANGED