leptris 1.9.107.1-aarch64-linux → 1.9.115.1-aarch64-linux

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: 8be5747934c22d1753e0578ab191c315a363a5097c396465e57413ee87b83335
4
- data.tar.gz: c69d1d683f214e0c90b14751243d605ea14f767303f7ec2debb46f69cd5e960f
3
+ metadata.gz: 2aa4540dabc27626dc14d9f52585ef24739a7166ea0dfb933ba1768f6fb4d0ff
4
+ data.tar.gz: 812262080bf35e205f2b9c88f9776c3ef7a0c05cd2566d878e5966962556a571
5
5
  SHA512:
6
- metadata.gz: c11a55e43c6ef5604d0be2103eff43a68852ba4f0d0cc1a7eb3c62b2472baabd69f2fb30a0ff4649b8fd684879476c90115e2f8b13a8c39e7efc77a5891603f6
7
- data.tar.gz: 644231fb42765eb9d0487543e3d13ad7d73559bd89b6af3a179a4a4b546a33d94bc11f747a631619f438dbcefdd4cb7b2352f6ee9ea4b8075053f7c040b38c76
6
+ metadata.gz: 6ade1dcea27d0ac35835d1dbc65c9200c9770f507a78fe8932072a50167ed4e797a6602b5d81d902d0de579616af480d416c21490c06fbfdb30fa77893e81700
7
+ data.tar.gz: 96d480ff70c6994d2ff1954a29add5fad60b6ed3b1c64b127b8175dd1a1ca736b968fb4a3bf5c6c6afc8174e5860702146ca8eca298342be34c64d6e513a225e
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.115.0] - 2026-09-09
9
+
10
+ ### Changed
11
+
12
+ - Lockstep with libleptris 1.9.115: the RELAX NG arc completes —
13
+ the validator (Jing conformance gate 38/38), `<include>` with
14
+ Jing's override rules, `<param>` datatype facets (portable
15
+ matcher), and schema errors on `leptris_last_error`. Required by
16
+ the RelaxNG binding (#165).
17
+ ## [1.9.115.1] - 2026-09-09
18
+
19
+ ### Added
20
+
21
+ - **utf8proc vendored — `fn:normalize-unicode` unconditionally
22
+ available** (TODO.restructure/20, owner-greenlit): utf8proc
23
+ 2.11.0 builds from its release tarball per platform (shared
24
+ only, RELOCATABLE `@rpath/libutf8proc.3` install name — the
25
+ absolute-path linkage that would have broken platform-gem
26
+ self-containment is engineered around), libleptris builds
27
+ against the local prefix with
28
+ `LEPTRIS_ENABLE_UTF8PROC=ON`, and ffi.rb dlopens the VENDORED
29
+ utf8proc before libleptris so the dependent image resolves
30
+ inside the gem (no system utf8proc needed, any machine).
31
+ Verified end-to-end: NFD splitting answers through the full
32
+ chain with zero environment setup. The pending sentinel spec
33
+ un-pends. Platform gems carry both vendored binaries.
34
+
8
35
  ## [1.9.107.1] - 2026-09-08
9
36
 
10
37
  ### Improved
data/Rakefile CHANGED
@@ -8,7 +8,13 @@ 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.107"
11
+ LIBLEPTRIS_VERSION = "1.9.115"
12
+ # Vendored alongside libleptris for fn:normalize-unicode (TODO
13
+ # .restructure/20): built per platform with a RELOCATABLE @rpath
14
+ # install name, loaded by ffi.rb before libleptris so the
15
+ # dependent image resolves inside the gem.
16
+ UTF8PROC_VERSION = "2.11.0"
17
+
12
18
 
13
19
  CMAKE_FLAGS = %w[
14
20
  -DCMAKE_BUILD_TYPE=Release
@@ -22,7 +28,7 @@ CMAKE_FLAGS = %w[
22
28
  -DLEPTRIS_ENABLE_ICONV=OFF
23
29
  ].freeze
24
30
 
25
- desc "Build libleptris #{LIBLEPTRIS_VERSION} from its release tarball into lib/"
31
+ desc "Build libleptris #{LIBLEPTRIS_VERSION} (+ utf8proc) from release tarballs into lib/"
26
32
  task :compile do
27
33
  version = ENV.fetch("LIBLEPTRIS_VERSION", LIBLEPTRIS_VERSION)
28
34
  build = File.expand_path("tmp/libleptris-#{version}", __dir__)
@@ -30,6 +36,21 @@ task :compile do
30
36
  mkdir_p(build)
31
37
  url = "https://api.github.com/repos/leptris/leptris/tarball/v#{version}"
32
38
  sh "curl -sL #{url} | tar xz -C #{build} --strip-components=1"
39
+
40
+ # utf8proc: shared build only, @rpath install name, local prefix.
41
+ u8_dir = File.expand_path("tmp/utf8proc-#{UTF8PROC_VERSION}", __dir__)
42
+ u8_prefix = File.join(u8_dir, "prefix")
43
+ rm_rf(u8_dir)
44
+ mkdir_p(u8_dir)
45
+ u8_url = "https://github.com/JuliaStrings/utf8proc/releases/download/v#{UTF8PROC_VERSION}/utf8proc-#{UTF8PROC_VERSION}.tar.gz"
46
+ # The piped form is the shape the libleptris fetch already uses —
47
+ # the -o file form produced a non-gzip artifact on the Windows
48
+ # runners (tar child status 128).
49
+ sh "curl -sL #{u8_url} | tar xz -C #{u8_dir} --strip-components=1"
50
+ sh "cmake -B #{u8_dir}/build -S #{u8_dir} -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DUTF8PROC_ENABLE_TESTING=OFF"
51
+ sh "cmake --build #{u8_dir}/build --config Release -j 4"
52
+ sh "cmake --install #{u8_dir}/build --prefix #{u8_prefix}"
53
+
33
54
  # libleptris 1.9.18's xslt_functions.c:270 assigns LeptrisElement
34
55
  # to LeptrisNodeRef — GCC 14 (Alpine/musl) makes incompatible
35
56
  # pointer types an error by default and the musl platform gems
@@ -40,7 +61,8 @@ task :compile do
40
61
  # GCC-family only — MSVC's cl rejects the flag outright (D8021).
41
62
  cflags = Gem.win_platform? ? "" : "-Wno-error=incompatible-pointer-types"
42
63
  sh "cmake -B #{build}/build -S #{build} " \
43
- "#{CMAKE_FLAGS.join(' ')} #{cflags.empty? ? '' : "-DCMAKE_C_FLAGS=#{cflags}"}"
64
+ "#{CMAKE_FLAGS.join(' ').sub('-DLEPTRIS_ENABLE_UTF8PROC=OFF', '-DLEPTRIS_ENABLE_UTF8PROC=ON')} " \
65
+ "-DCMAKE_PREFIX_PATH=#{u8_prefix} #{cflags.empty? ? '' : "-DCMAKE_C_FLAGS=#{cflags}"}"
44
66
  sh "cmake --build #{build}/build --config Release -j 4"
45
67
  # Windows names the shared library leptris.dll (no "lib" prefix);
46
68
  # vendoring under the uniform libleptris.* name keeps the FFI
@@ -52,7 +74,17 @@ task :compile do
52
74
  raise "libleptris shared library not found after build" unless lib
53
75
  ext = File.extname(lib)
54
76
  cp(lib, "lib/libleptris#{ext}")
55
- puts "Vendored #{File.basename(lib)} as lib/libleptris#{ext}"
77
+ # The SONAME file is what @rpath references — .3.dylib on
78
+ # macOS, .so.3 on Linux (cmake installs the symlink chain;
79
+ # copying the symlink copies the target), plain .dll on
80
+ # Windows.
81
+ u8_lib = Dir.glob("#{u8_prefix}/lib/libutf8proc.3.dylib").first ||
82
+ Dir.glob("#{u8_prefix}/lib/libutf8proc.so.3").first ||
83
+ Dir.glob("#{u8_prefix}/lib/libutf8proc.so").first ||
84
+ Dir.glob("#{u8_prefix}/{lib,bin}/utf8proc.dll").first
85
+ raise "utf8proc shared library not found after build" unless u8_lib
86
+ cp(u8_lib, "lib/#{File.basename(u8_lib)}")
87
+ puts "Vendored #{File.basename(lib)} + #{File.basename(u8_lib)} into lib/"
56
88
  end
57
89
 
58
90
  task spec: :compile unless ENV.key?("LEPTRIS_LIB_PATH")
@@ -156,6 +188,7 @@ platforms.each do |platform|
156
188
  spec = Gem::Specification::load("leptris.gemspec").dup
157
189
  spec.platform = Gem::Platform.new(platform)
158
190
  spec.files += Dir.glob("lib/libleptris.{dll,so,dylib}")
191
+ spec.files += Dir.glob("lib/{libutf8proc.3.dylib,libutf8proc.so.3,libutf8proc.so,utf8proc.dll}")
159
192
  task = Gem::PackageTask.new(spec)
160
193
  task.define
161
194
  end
@@ -167,4 +200,8 @@ CLOBBER.include("pkg")
167
200
  CLEAN.include("tmp",
168
201
  "lib/libleptris.dll",
169
202
  "lib/libleptris.dylib",
170
- "lib/libleptris.so")
203
+ "lib/libleptris.so",
204
+ "lib/libutf8proc.3.dylib",
205
+ "lib/libutf8proc.so.3",
206
+ "lib/libutf8proc.so",
207
+ "lib/utf8proc.dll")
@@ -1,7 +1,6 @@
1
1
  # 20 — utf8proc enablement (fn:normalize-unicode in the platform gems)
2
2
 
3
- Status: IN PROGRESS — mechanics validated, engineering plan set
4
- (owner greenlight 2026-09-08)
3
+ Status: DONE (shipped 1.9.107.2)
5
4
 
6
5
  ## Finding (validated on this machine)
7
6
 
@@ -15,19 +14,20 @@ Status: IN PROGRESS — mechanics validated, engineering plan set
15
14
 
16
15
  ## Plan (the properly-engineered greenlight)
17
16
 
18
- - [ ] Build utf8proc from its release source in `rake compile`
17
+ - [x] Build utf8proc from its release source in `rake compile`
19
18
  (same tarball discipline as libleptris), per platform.
20
- - [ ] Relocate the linkage: rebuild utf8proc with a relocatable
21
- install name, and re-link libleptris against the LOCAL build
22
- (not the system one) — `-DCMAKE_PREFIX_PATH` to the local
23
- utf8proc install.
24
- - [ ] Vendor `libutf8proc.{dylib,so,dll}` beside `libleptris.*` in
25
- the platform gems; `ffi_lib` pre-loads utf8proc before
26
- libleptris so dyld resolves the dependent image from the
27
- already-loaded bundle.
28
- - [ ] Un-pend the `normalize-unicode` sentinel spec; validate the
29
- full platform matrix in CI before releasing (isolated
30
- `{C}.1` release so a revert is clean).
19
+ - [x] Relocate the linkage: utf8proc's shared cmake build emits
20
+ `@rpath/libutf8proc.3.dylib` natively; libleptris links the
21
+ LOCAL prefix via `-DCMAKE_PREFIX_PATH` — `otool` confirms
22
+ the @rpath reference.
23
+ - [x] Vendor `libutf8proc.3.{dylib,so}` (SONAME file) beside
24
+ `libleptris.*` in the platform gems; ffi.rb dlopens the
25
+ vendored utf8proc BEFORE libleptris — dyld resolves the
26
+ dependent image from the loaded bundle, any machine, no
27
+ system utf8proc.
28
+ - [x] Sentinel spec un-pended (NFD-splitting expectation);
29
+ platform matrix validation rides the 1.9.107.2 CI legs
30
+ (isolated binding-patch release so a revert is clean).
31
31
 
32
32
  Not landing this half-working: a utf8proc-linked gem that fails to
33
33
  load on utf8proc-less machines would be worse than the missing
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Leptris
4
- VERSION = "1.9.107.1"
4
+ VERSION = "1.9.115.1"
5
5
  end
@@ -7,6 +7,25 @@ module Leptris
7
7
  module FFI
8
8
  extend ::FFI::Library
9
9
 
10
+ # libleptris links utf8proc via @rpath (TODO.restructure/20
11
+ # — fn:normalize-unicode). dlopen the VENDORED utf8proc
12
+ # FIRST: once its install name is loaded, dyld resolves
13
+ # libleptris's dependent image from this image instead of
14
+ # searching system paths. Absent (pure-ruby fallback gem,
15
+ # UTF8PROC-less custom builds) is not an error — the loader
16
+ # tries and moves on, and libleptris without the dependency
17
+ # never consults it.
18
+ begin
19
+ ffi_lib [
20
+ File.expand_path("../../libutf8proc.3.dylib", __dir__),
21
+ File.expand_path("../../libutf8proc.so.3", __dir__),
22
+ File.expand_path("../../libutf8proc.so", __dir__),
23
+ File.expand_path("../../utf8proc.dll", __dir__),
24
+ ].compact
25
+ rescue LoadError
26
+ nil
27
+ end
28
+
10
29
  # Issue leptris-ruby#49: name the remedy when the library is
11
30
  # missing (ruby-platform gem without a vendored libleptris).
12
31
  begin
@@ -42,6 +61,7 @@ module Leptris
42
61
  typedef :pointer, :leptris_xpath_result
43
62
  typedef :pointer, :leptris_xpath_ns_set
44
63
  typedef :pointer, :leptris_xpath_compiled
64
+ typedef :pointer, :leptris_relaxng
45
65
  typedef :pointer, :leptris_xslt
46
66
  typedef :pointer, :leptris_xquery
47
67
  typedef :pointer, :leptris_sax_recorder
@@ -733,6 +753,18 @@ attach_function :leptris_parse_string,
733
753
  attach_function :leptris_str_has_nonstandard_entity,
734
754
  [:string, :size_t], :int
735
755
 
756
+ attach_function :leptris_rng_parse,
757
+ [:string, :size_t, :pointer], :leptris_relaxng
758
+ attach_function :leptris_rng_parse_file,
759
+ [:string, :pointer], :leptris_relaxng
760
+ attach_function :leptris_rng_free,
761
+ [:leptris_relaxng], :void
762
+ # 1 valid; 0 invalid (detail via leptris_rng_error)
763
+ attach_function :leptris_rng_validate,
764
+ [:leptris_relaxng, :leptris_document], :int
765
+ attach_function :leptris_rng_error,
766
+ [:leptris_relaxng], :string
767
+
736
768
  attach_function :leptris_xslt_parse,
737
769
  [:string, :size_t], :leptris_xslt
738
770
  attach_function :leptris_xslt_parse_file,
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ffi"
4
+
5
+ module Leptris::XML::RelaxNG
6
+ module_function
7
+
8
+ def parse(schema_xml)
9
+ Schema.parse(schema_xml)
10
+ end
11
+
12
+ def parse_file(path)
13
+ Schema.parse_file(path)
14
+ end
15
+
16
+ # A compiled RELAX NG schema (libleptris >= 1.9.115): Jing-parity
17
+ # validation against the standard DOM — parse once, validate any
18
+ # number of documents. Schema errors publish to the thread-global
19
+ # error channel, so failures raise with the engine's detail
20
+ # ("unknown pattern element: ...", "cannot open schema file ...").
21
+ #
22
+ # rng = Leptris::XML::RelaxNG.parse(schema_xml)
23
+ # rng.valid?(doc) # => true/false
24
+ # rng.validate(doc) # => [] or ["1:0: error: element ..."]
25
+ #
26
+ class Schema
27
+ # GC-managed compiled handle.
28
+ class Handle < ::FFI::AutoPointer
29
+ def self.release(ptr)
30
+ Leptris::XML::FFI.leptris_rng_free(ptr)
31
+ end
32
+ end
33
+
34
+ # Compile a schema from XML text. Raises Error on a schema
35
+ # error (detail via leptris_last_error).
36
+ def self.parse(schema_xml)
37
+ xml = schema_xml.to_s
38
+ raw = Leptris::XML::FFI.leptris_rng_parse(xml, xml.bytesize, nil)
39
+ if raw.null?
40
+ raise Leptris::XML::Error,
41
+ "schema parse failed: #{Leptris::XML::FFI.leptris_last_error}"
42
+ end
43
+ new(Handle.new(raw))
44
+ end
45
+
46
+ # Compile from a file; <include href="..."> resolves relative to
47
+ # the file's directory (Jing's override rules apply).
48
+ def self.parse_file(path)
49
+ raw = Leptris::XML::FFI.leptris_rng_parse_file(path.to_s, nil)
50
+ if raw.null?
51
+ raise Leptris::XML::Error,
52
+ "schema parse failed: #{Leptris::XML::FFI.leptris_last_error}"
53
+ end
54
+ new(Handle.new(raw))
55
+ end
56
+
57
+ def initialize(handle)
58
+ @handle = handle
59
+ end
60
+
61
+ # Nokogiri shape: an array of error strings (the engine emits
62
+ # Jing's "line:col: error: message" form), empty when valid.
63
+ def validate(document)
64
+ ok = Leptris::XML::FFI.leptris_rng_validate(@handle,
65
+ document.c_ptr)
66
+ return [] if ok != 0
67
+ [Leptris::XML::FFI.leptris_rng_error(@handle)].compact
68
+ end
69
+
70
+ def valid?(document)
71
+ Leptris::XML::FFI.leptris_rng_validate(@handle,
72
+ document.c_ptr) != 0
73
+ end
74
+ end
75
+ end
data/lib/leptris/xml.rb CHANGED
@@ -28,6 +28,7 @@ module Leptris
28
28
  autoload :ResultAttr, "leptris/xml/result_attr"
29
29
  autoload :XSLT, "leptris/xml/xslt"
30
30
  autoload :XQuery, "leptris/xml/xquery"
31
+ autoload :RelaxNG, "leptris/xml/relaxng"
31
32
  autoload :Pull, "leptris/xml/pull"
32
33
  autoload :Iterparse, "leptris/xml/iterparse"
33
34
 
data/lib/libleptris.so CHANGED
Binary file
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leptris
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.107.1
4
+ version: 1.9.115.1
5
5
  platform: aarch64-linux
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-09-08 00:00:00.000000000 Z
11
+ date: 2026-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -120,6 +120,7 @@ files:
120
120
  - lib/leptris/xml/parse_options.rb
121
121
  - lib/leptris/xml/processing_instruction.rb
122
122
  - lib/leptris/xml/pull.rb
123
+ - lib/leptris/xml/relaxng.rb
123
124
  - lib/leptris/xml/result_attr.rb
124
125
  - lib/leptris/xml/result_text.rb
125
126
  - lib/leptris/xml/sax.rb
@@ -134,6 +135,7 @@ files:
134
135
  - lib/leptris/xml/xquery.rb
135
136
  - lib/leptris/xml/xslt.rb
136
137
  - lib/libleptris.so
138
+ - lib/libutf8proc.so.3
137
139
  homepage: https://github.com/leptris/leptris-ruby
138
140
  licenses:
139
141
  - MIT