leptris 1.9.188.0 → 1.9.193.0

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: cf80ccf870ddf66abc6a3a4fa99727a9f15d8da89649f337c34d7d24349eb94f
4
- data.tar.gz: 95bc3a48e901eda33ba20492d98007da08746dbbef90a391fe518ec37db2942b
3
+ metadata.gz: d8b1ffa2c04d15482319b91021017e096e8199d6919071ff94c8532af66f0b4d
4
+ data.tar.gz: bcbbca3c40e50c5d4c42c167f991267f8a670730dfe321c586292d0e201de0f6
5
5
  SHA512:
6
- metadata.gz: fa413d38c0dc9571c72564d8df2277ddc4c47b0b9a3e38c00824c54b50042042f2594c2acddc94800ba7cd5b455b9b72296b69abe61c0e99711f860de4bd1a71
7
- data.tar.gz: '089846a5778f5e3fe3bdf8daa0460f09e81cd4d31250860cf12129de8918caefddc219eb11e445898ca183c94490fed804ed3a89b0bea4fb5c94af6a55eaf8e4'
6
+ metadata.gz: 7d0ff9f39131c9f66ed2e9f9cc41a266160f917a6edd90c15629e468e88230de2ad68bcaaecfdd7f60ddb62eec4888ab1d2a2800bcb32c77b27cfd01fef49a31
7
+ data.tar.gz: 04ca510ed71d9d59b58d1b49f9d3875fe134d853612fc7e582889e8821902440de01f096b38dad93a7c9279afa510b2e311790e919ee322b7ba77a07ebd74774
data/CHANGELOG.md CHANGED
@@ -5,6 +5,33 @@ 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.192.0] - 2026-09-17
9
+
10
+ ### Changed — libleptris 1.9.188 → 1.9.192 (lockstep)
11
+
12
+ - **`RelaxNG::Schema#validate_report`** — the whole validation
13
+ report in one C call (upstream 1.9.190,
14
+ `leptris_rng_error_report`): `[{ kind:, message:, offender:,
15
+ line:, column: }]`, empty when valid. `kind` is the #1126
16
+ failure-class taxonomy ("missing-required-attr",
17
+ "attr-not-allowed", ...), `offender` the attributed element/
18
+ attribute name. Spec-pinned. `validate_errors` now renders from
19
+ the same report (one call + struct reads instead of 4 accessor
20
+ calls per error); the per-index accessors stay attached for
21
+ back-compat.
22
+ - **The metanorma schema chain compiles and validates end to end**
23
+ (1.9.189): the combine-merge heap-use-after-free on include
24
+ merges, XSD `\i`/`\c` pattern classes, and the whole-value match
25
+ anchor riding the continuation. Spec-pinned (combine merge,
26
+ `\i\c*`).
27
+ - **Attributes behind a `<ref>` are consumed** — both the verdict
28
+ (1.9.191) and the diagnostic walk (1.9.192): basicdoc.rng's
29
+ `Root-Attributes` no longer produces false
30
+ "found attribute X, but no attributes allowed here". Spec-pinned.
31
+ - **externalRef resolves in bare-`<element>` schemas** (1.9.190).
32
+ Spec-pinned.
33
+ - One new public symbol: audit 323/323.
34
+
8
35
  ## [1.9.188.0] - 2026-09-17
9
36
 
10
37
  ### Changed — libleptris 1.9.186 → 1.9.188 (lockstep)
data/Rakefile CHANGED
@@ -8,7 +8,7 @@ RSpec::Core::RakeTask.new(:spec)
8
8
  # Pin for `rake compile` and the platform-gem builds. Keep in lockstep
9
9
  # with .github/workflows/build.yml (which calls `rake compile`) and the
10
10
  # CHANGELOG when libleptris releases.
11
- LIBLEPTRIS_VERSION = "1.9.188"
11
+ LIBLEPTRIS_VERSION = "1.9.193"
12
12
  # Vendored alongside libleptris for fn:normalize-unicode (TODO
13
13
  # .restructure/20): built per platform with a RELOCATABLE @rpath
14
14
  # install name, loaded by ffi.rb before libleptris so the
@@ -98,10 +98,59 @@ task :compile do
98
98
  # literal on Windows shells (they broke the MSVC build).
99
99
  # GCC-family only — MSVC's cl rejects the flag outright (D8021).
100
100
  cflags = Gem.win_platform? ? "" : "-Wno-error=incompatible-pointer-types"
101
- sh "cmake -B #{build}/build -S #{build} " \
102
- "#{CMAKE_FLAGS.join(' ').sub('-DLEPTRIS_ENABLE_UTF8PROC=OFF', '-DLEPTRIS_ENABLE_UTF8PROC=ON')} " \
103
- "-DCMAKE_PREFIX_PATH=#{u8_prefix} #{cflags.empty? ? '' : "-DCMAKE_C_FLAGS=#{cflags}"}"
104
- sh "cmake --build #{build}/build --config Release -j 4"
101
+ cmake_base =
102
+ "#{CMAKE_FLAGS.join(' ').sub('-DLEPTRIS_ENABLE_UTF8PROC=OFF', '-DLEPTRIS_ENABLE_UTF8PROC=ON')} " \
103
+ "-DCMAKE_PREFIX_PATH=#{u8_prefix} #{cflags.empty? ? '' : "-DCMAKE_C_FLAGS=#{cflags}"}"
104
+
105
+ # Two-stage PGO (engine CMake: LEPTRIS_ENABLE_PGO GENERATE/USE;
106
+ # measured ~20% CPU on the DOM parse path, v1.9.188 worktree A/B,
107
+ # every PGO round beating every baseline round). Train via the CLI
108
+ # over the tarball's XML corpus. Windows keeps the plain build —
109
+ # MSVC PGO is inherently LTCG and these gems link the DLL as-is.
110
+ # LEPTRIS_PGO=0 escapes to the single-stage build.
111
+ pgo = ENV["LEPTRIS_PGO"] != "0" && !Gem.win_platform?
112
+ if pgo
113
+ # _GNU_SOURCE for the TRAIN build only: the CLI (the trainer, not
114
+ # built in normal gems) uses fileno, which musl hides without a
115
+ # POSIX feature macro (glibc is lenient). Upstream fix pending in
116
+ # the C repo; this stays on the throwaway instrumented build.
117
+ # _GNU_SOURCE is MUSL-ONLY: the CLI trainer's fileno needs a POSIX
118
+ # feature macro under musl. On glibc the macro reshuffles the
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" : ""
124
+ pgo_cflags = "#{cflags}#{gnu}".strip
125
+ pgo_base =
126
+ if pgo_cflags == cflags
127
+ cmake_base
128
+ else
129
+ cmake_base.sub("-DCMAKE_C_FLAGS=#{cflags}",
130
+ "-DCMAKE_C_FLAGS='#{pgo_cflags}'")
131
+ end
132
+ sh "cmake -B #{build}/build -S #{build} #{pgo_base} " \
133
+ "-DLEPTRIS_BUILD_CLI=ON -DLEPTRIS_ENABLE_PGO=GENERATE"
134
+ sh "cmake --build #{build}/build --config Release -j 4"
135
+ cli = File.join(build, "build", "cli", "leptris")
136
+ pgo_dir = File.join(build, "build", "pgo-data")
137
+ corpus = Dir[File.join(build, "benchmarks", "data", "*.xml")]
138
+ corpus.each do |xml|
139
+ # a corpus file can be deliberately malformed; training tolerates it
140
+ system({ "LLVM_PROFILE_FILE" => File.join(pgo_dir, "%p.profraw") },
141
+ cli, "parse", xml, out: File::NULL, err: File::NULL)
142
+ end
143
+ if RUBY_PLATFORM =~ /darwin/
144
+ sh "xcrun llvm-profdata merge -output=#{File.join(pgo_dir, 'default.profdata')} " \
145
+ "#{File.join(pgo_dir, '*.profraw')}"
146
+ end
147
+ sh "cmake -B #{build}/build -S #{build} #{cmake_base} " \
148
+ "-DLEPTRIS_BUILD_CLI=OFF -DLEPTRIS_ENABLE_PGO=USE"
149
+ sh "cmake --build #{build}/build --config Release -j 4"
150
+ else
151
+ sh "cmake -B #{build}/build -S #{build} #{cmake_base}"
152
+ sh "cmake --build #{build}/build --config Release -j 4"
153
+ end
105
154
  # Windows names the shared library leptris.dll (no "lib" prefix);
106
155
  # vendoring under the uniform libleptris.* name keeps the FFI
107
156
  # search order simple. libleptris >= 1.3.0 renames the DLL to
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Leptris
4
- VERSION = "1.9.188.0"
4
+ VERSION = "1.9.193.0"
5
5
  end
@@ -1027,6 +1027,21 @@ attach_function :leptris_parse_string,
1027
1027
  attach_function :leptris_rng_error_column,
1028
1028
  [:leptris_relaxng, :size_t], :int
1029
1029
 
1030
+ # Whole-report face (libleptris 1.9.190): one call returns
1031
+ # every record — kind (the #1126 failure-class taxonomy) and
1032
+ # offender were unreachable through the per-index accessors.
1033
+ # Record array is handle-owned; strings live until the next
1034
+ # validate call or leptris_rng_free.
1035
+ class RngErrorRecord < ::FFI::Struct
1036
+ layout :kind, :string,
1037
+ :message, :string,
1038
+ :offender, :string,
1039
+ :line, :uint,
1040
+ :column, :uint
1041
+ end
1042
+ attach_function :leptris_rng_error_report,
1043
+ [:leptris_relaxng, :pointer], :size_t
1044
+
1030
1045
  attach_function :leptris_xslt_parse,
1031
1046
  [:string, :size_t], :leptris_xslt
1032
1047
  attach_function :leptris_xslt_parse_file,
@@ -23,6 +23,7 @@ module Leptris::XML::RelaxNG
23
23
  # rng.valid?(doc) # => true/false
24
24
  # rng.validate(doc) # => [] or ["1:0: error: element ..."]
25
25
  # rng.validate_errors(doc) # => [] or [{line:, column:, message:}]
26
+ # rng.validate_report(doc) # => [] or [{kind:, message:, offender:, ...}]
26
27
  #
27
28
  class Schema
28
29
  # GC-managed compiled handle.
@@ -86,23 +87,40 @@ module Leptris::XML::RelaxNG
86
87
  # callers need for log formatting, instead of re-parsing the
87
88
  # Jing-form strings from #validate. Empty when valid. Message,
88
89
  # line, and column carry Jing's exact attribution (libleptris
89
- # >= 1.9.179, upstream #878). This is the single enumeration of
90
- # the error-accumulation surface; #validate renders these rows.
90
+ # >= 1.9.179, upstream #878). Rendered from #validate_report
91
+ # the single enumeration of the error surface.
91
92
  def validate_errors(document)
93
+ validate_report(document).map do |r|
94
+ { line: r[:line], column: r[:column], message: r[:message] }
95
+ end
96
+ end
97
+
98
+ # The whole validation report, one C call (libleptris >= 1.9.190):
99
+ # [{ kind:, message:, offender:, line:, column: }] — empty when
100
+ # valid. `kind` is the #1126 failure-class taxonomy
101
+ # ("missing-required-attr", "attr-not-allowed", ...), `offender`
102
+ # the attributed element/attribute name (nil when unknown).
103
+ # Strings are read into Ruby copies before returning.
104
+ def validate_report(document)
92
105
  ok = Leptris::XML::FFI.leptris_rng_validate(@handle,
93
106
  document.c_ptr)
94
107
  return [] if ok != 0
95
- count = Leptris::XML::FFI.leptris_rng_error_count(@handle)
108
+ out = ::FFI::MemoryPointer.new(:pointer)
109
+ count = Leptris::XML::FFI.leptris_rng_error_report(@handle, out)
96
110
  return [] if count.zero?
111
+ base = out.read_pointer
112
+ return [] if base.null?
113
+ record = Leptris::XML::FFI::RngErrorRecord
97
114
  Array.new(count) do |i|
98
- msg = Leptris::XML::FFI.leptris_rng_error_message(@handle, i)
99
- next nil if msg.nil?
115
+ r = record.new(base + i * record.size)
100
116
  {
101
- line: Leptris::XML::FFI.leptris_rng_error_line(@handle, i),
102
- column: Leptris::XML::FFI.leptris_rng_error_column(@handle, i),
103
- message: msg,
117
+ kind: r[:kind],
118
+ message: r[:message],
119
+ offender: r[:offender],
120
+ line: r[:line],
121
+ column: r[:column],
104
122
  }
105
- end.compact
123
+ end
106
124
  end
107
125
  end
108
126
  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.188.0
4
+ version: 1.9.193.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.