leptris 1.9.320.0-ppc64le-linux → 1.9.322.0-ppc64le-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: 7691bd3eb83cab9783c2a73c4a42e9dc2ac129b13d40342f46a7bc9609b8e902
4
- data.tar.gz: b1d4348cd9fd819a7cd808c33d8c1204261e6f4472327c76f0f6f4017d233ae3
3
+ metadata.gz: 7f838f3aa92b2932ec3b32f7cf4227c70c415a84c5916f115f4f1b6811c2a913
4
+ data.tar.gz: fed0ebac144489410e7737113f5f0210e652113d9921cab7422fdbf182ec91e0
5
5
  SHA512:
6
- metadata.gz: 2a7312c3e914fbb020c54c0c80ee11e4ebee98b26b4bd15fa7e8f3f4e85cb54827adfa3664fe39ac541d3c9ecc2652aa80488c0d87acd2174e27e911d3794525
7
- data.tar.gz: c11f2d4c3910a6be2f7945ceb0e30fc14339cdae47b74e10b31058b28983a4caca94efd3da0140ecbb9a22875764f15544eefe7a6917066f0b25599f06c69b53
6
+ metadata.gz: 4f65c9924ed95bd9cc2e577982bc99d5508a89c0f5cdaa272224b5ce36973b88d2c5fd4c2e486f70e33a140fc74c57a1fbdb13f764a790044952d889c7f337ef
7
+ data.tar.gz: 27b270be847e3dde7c1806030f654ff0766695437ca1b32b5a5e910728f38aa1a52ecd6d65b85955f3df7aa24d9e6d67243501e5b2294b56845a58fb0e22b5e0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,31 @@
1
+ ## [1.9.322.0] - 2026-10-08
2
+
3
+ ### Engine sync (libleptris 1.9.322)
4
+
5
+ - `leptris validate --xsd FILE` rides the CLI's validate command
6
+ (compile error detail, every accumulated instance error,
7
+ non-zero exit) — CLI-only, no binding surface; audit 381/380
8
+ unchanged. The inline-anonymous complexType capture fix
9
+ (leptris#1592, engine PR #1596) merged after this tag and ships
10
+ with the engine's next release — the binding pin follows there.
11
+
12
+ ## [1.9.321.0] - 2026-10-08
13
+
14
+ ### Added — engine sync (libleptris 1.9.321)
15
+
16
+ - **XSD instance validation, slices 3-4 (#1075)**:
17
+ `Schema#valid?` walks the whole document — element declarations,
18
+ attribute rows (required + typed + lenient qualified spellings),
19
+ text lexical checks, child content models through a Thompson NFA
20
+ (linear in children x states, no backtracking blowup);
21
+ `Schema#validate_errors` enumerates every failure (the engine
22
+ replaces the list per run); `Schema#content_valid?` evaluates a
23
+ child sequence directly against a top-level declaration's model.
24
+ The -1 contract raises (unknown declaration never masquerades as
25
+ invalid input). Pins use the named-ref shape — the inline-
26
+ anonymous complexType capture gap is filed upstream
27
+ (leptris#1592).
28
+
1
29
  ## [1.9.320.0] - 2026-10-08
2
30
 
3
31
  ### Fixed — engine sync (libleptris 1.9.320)
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.320"
11
+ LIBLEPTRIS_VERSION = "1.9.322"
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Leptris
4
- VERSION = "1.9.320.0"
4
+ VERSION = "1.9.322.0"
5
5
  end
@@ -1304,6 +1304,21 @@ attach_function :leptris_parse_string,
1304
1304
  [:string, :string], :int
1305
1305
  attach_function :leptris_xsd_simple_valid,
1306
1306
  [:leptris_xsd_schema, :string, :string], :int
1307
+ # Slices 3-4 (libleptris 1.9.321, #1075): content models via
1308
+ # Thompson NFA (linear in children x states) and whole-
1309
+ # instance validation — element declarations, attribute rows
1310
+ # (required + typed + lenient qualified spellings), text
1311
+ # lexical checks, child content models. Failures enumerate
1312
+ # behind error_count/_at (schema-owned; the next validate
1313
+ # run replaces them).
1314
+ attach_function :leptris_xsd_content_valid,
1315
+ [:leptris_xsd_schema, :string, :pointer, :pointer, :size_t], :int
1316
+ attach_function :leptris_xsd_validate,
1317
+ [:leptris_xsd_schema, :leptris_document], :int
1318
+ attach_function :leptris_xsd_error_count,
1319
+ [:leptris_xsd_schema], :size_t
1320
+ attach_function :leptris_xsd_error_at,
1321
+ [:leptris_xsd_schema, :size_t], UTF8_STRING
1307
1322
 
1308
1323
  attach_function :leptris_rng_parse,
1309
1324
  [:string, :size_t, :pointer], :leptris_relaxng
@@ -79,14 +79,66 @@ module Leptris::XML::XSD
79
79
  # name) — restriction chains validate every hop's facets,
80
80
  # cycle-guarded. Unknown type names raise (the -1 contract).
81
81
  def simple_valid?(type_name, lexical)
82
- r = Leptris::XML::FFI.leptris_xsd_simple_valid(
83
- @handle, type_name.to_s, lexical.to_s)
84
- case r
82
+ tri_state(
83
+ Leptris::XML::FFI.leptris_xsd_simple_valid(
84
+ @handle, type_name.to_s, lexical.to_s),
85
+ "#{type_name.inspect} is not a simpleType in this schema")
86
+ end
87
+
88
+ # Slices 3-4 (libleptris 1.9.321, #1075): whole-instance
89
+ # validation — element declarations, attribute rows (required
90
+ # + typed + lenient qualified spellings), text lexical checks,
91
+ # and child content models through the Thompson NFA. Returns
92
+ # true/false.
93
+ def valid?(document)
94
+ tri_state(
95
+ Leptris::XML::FFI.leptris_xsd_validate(
96
+ @handle, document.c_ptr), "invalid document handle")
97
+ end
98
+
99
+ # The enumerated failure list of the last #validate run
100
+ # (empty when valid; the NEXT validate replaces the list).
101
+ def validate_errors(document)
102
+ valid?(document)
103
+ Leptris::XML::FFI.leptris_xsd_error_count(@handle).times.map do |i|
104
+ Leptris::XML::FFI.leptris_xsd_error_at(@handle, i)
105
+ end
106
+ end
107
+
108
+ # Slice 3 direct face: a child SEQUENCE against a top-level
109
+ # element declaration's compiled content model (occurrence
110
+ # bounds, xs:any wildcards). +children+ are child Nodes (name
111
+ # + effective namespace extracted per child). Unknown element
112
+ # declarations raise (the -1 contract).
113
+ def content_valid?(element_name, children)
114
+ kids = children.to_a
115
+ nb, na = Leptris::XML::CStringArray.to_c(
116
+ kids.map { |c| c.name.to_s })
117
+ ub, ua = Leptris::XML::CStringArray.to_c(
118
+ kids.map { |c| child_ns_uri(c) })
119
+ tri_state(
120
+ Leptris::XML::FFI.leptris_xsd_content_valid(
121
+ @handle, element_name.to_s, nb, ub, kids.size),
122
+ "#{element_name.inspect} is not a top-level element declaration")
123
+ end
124
+
125
+ private
126
+
127
+ # A child's effective namespace URI (nil = none) — read
128
+ # through its own c_ptr, so docless wrappers work.
129
+ def child_ns_uri(node)
130
+ uri = Leptris::XML::FFI.leptris_element_namespace(node.c_ptr)
131
+ uri.nil? || uri.empty? ? "" : uri
132
+ end
133
+
134
+ # The C faces' 1/0/-1 contract: true/false, with -1 raising —
135
+ # a silent false would mean "no such declaration/type", which
136
+ # callers must never confuse with "invalid input".
137
+ def tri_state(code, unknown_message)
138
+ case code
85
139
  when 1 then true
86
140
  when 0 then false
87
- else
88
- raise ArgumentError,
89
- "#{type_name.inspect} is not a simpleType in this schema"
141
+ else raise ArgumentError, unknown_message
90
142
  end
91
143
  end
92
144
  end
data/lib/libleptris.so CHANGED
Binary file
data/vendor-src/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  Sources vendored in this gem (recompile rights; the ruby
2
2
  variant builds them at install via extconf.rb):
3
3
 
4
- - libleptris v1.9.320
4
+ - libleptris v1.9.322
5
5
  - utf8proc v2.11.0
6
6
 
7
7
  Rebuild by hand:
@@ -1,5 +1,40 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [1.9.322] - 2026-10-08
4
+
5
+ ### Added
6
+
7
+ - **`leptris validate --xsd FILE` (#1075, PR #1593).** The compiled
8
+ XSD surface rides the same validate command as `--dtd`/`--rng`/
9
+ `--schematron`: compile failures report the schema's own error
10
+ detail (compile returns error-carrying handles — the status keys
11
+ the failure); invalid documents print every accumulated error and
12
+ exit non-zero.
13
+
14
+
15
+
16
+ ## [1.9.321] - 2026-10-08
17
+
18
+ ### Added
19
+
20
+ - **XSD validation, tier 1, slices 3–4 (#1075, PRs #1589/#1590).**
21
+ Slice 3 — content models: the compiler captures top-level
22
+ `xs:element` declarations and named `xs:complexType` models
23
+ (sequence/choice/all, occurrence bounds incl. unbounded, element
24
+ name/ref particles, `xs:any` wildcards with the full
25
+ namespace-filter grammar); `leptris_xsd_content_valid` evaluates
26
+ a child sequence through a Thompson NFA — linear in children x
27
+ states, no backtracking blowup on nested choices. Slice 4 —
28
+ instance validation: `leptris_xsd_validate(schema, document)`
29
+ walks element declarations, complexType attribute rows
30
+ (required + typed + lenient qualified spellings), child content
31
+ models, and lexical text checks for simple-typed elements
32
+ (particles carry type refs); failures enumerate behind
33
+ `leptris_xsd_error_count/_at`. The libxml2 corpus gate holds at
34
+ 163/163; full suite 1911/1911.
35
+
36
+
37
+
3
38
  ## [1.9.320] - 2026-10-08
4
39
 
5
40
  ### Fixed
@@ -3,7 +3,7 @@
3
3
  cmake_minimum_required(VERSION 3.20)
4
4
 
5
5
  project(leptris
6
- VERSION 1.9.320
6
+ VERSION 1.9.322
7
7
  DESCRIPTION "Fast XML parser and XPath evaluator in pure C"
8
8
  LANGUAGES C CXX
9
9
  )
@@ -156,6 +156,7 @@ static int run_schematron(const char* path, const char* phase,
156
156
 
157
157
  static cli_result_t validate_execute(int argc, char** argv) {
158
158
  const char* rng_path = NULL;
159
+ const char* xsd_path = NULL;
159
160
  const char* sch_path = NULL;
160
161
  const char* dtd_path = NULL;
161
162
  const char* phase = NULL;
@@ -164,6 +165,8 @@ static cli_result_t validate_execute(int argc, char** argv) {
164
165
  for (int i = 1; i < argc; i++) {
165
166
  if (strcmp(argv[i], "--rng") == 0 && i + 1 < argc) {
166
167
  rng_path = argv[++i];
168
+ } else if (strcmp(argv[i], "--xsd") == 0 && i + 1 < argc) {
169
+ xsd_path = argv[++i];
167
170
  } else if ((strcmp(argv[i], "--schematron") == 0 ||
168
171
  strcmp(argv[i], "-s") == 0) &&
169
172
  i + 1 < argc) {
@@ -184,6 +187,7 @@ static cli_result_t validate_execute(int argc, char** argv) {
184
187
  printf("Options:\n");
185
188
  printf(" --dtd FILE External DTD\n");
186
189
  printf(" --rng FILE RELAX NG schema\n");
190
+ printf(" --xsd FILE W3C XML Schema (XSD)\n");
187
191
  printf(" --schematron FILE ISO Schematron schema\n");
188
192
  printf(" --phase ID Schematron phase to");
189
193
  printf(" select\n");
@@ -205,8 +209,8 @@ static cli_result_t validate_execute(int argc, char** argv) {
205
209
  cli_error("validate requires an XML document");
206
210
  return CLI_ERROR_ARGS;
207
211
  }
208
- if (!rng_path && !sch_path && !dtd_path) {
209
- cli_error("validate needs --dtd and/or --rng and/or --schematron");
212
+ if (!rng_path && !sch_path && !dtd_path && !xsd_path) {
213
+ cli_error("validate needs --dtd/--rng/--schematron/--xsd");
210
214
  return CLI_ERROR_ARGS;
211
215
  }
212
216
  LeptrisDocument doc = read_doc(xml_path);
@@ -261,6 +265,43 @@ static cli_result_t validate_execute(int argc, char** argv) {
261
265
  }
262
266
  leptris_rng_free(rng);
263
267
  }
268
+ if (xsd_path) {
269
+ size_t xsd_len = 0;
270
+ char* xsd_content = read_file(xsd_path, &xsd_len);
271
+ if (!xsd_content) {
272
+ cli_error("cannot read XSD: %s", xsd_path);
273
+ leptris_document_free(doc);
274
+ return CLI_ERROR_IO;
275
+ }
276
+ LeptrisStatus st = LEPTRIS_OK;
277
+ LeptrisXsdSchema xsd =
278
+ leptris_xsd_compile(xsd_content, xsd_len, &st);
279
+ free(xsd_content);
280
+ /* compile returns an error-carrying handle on failure — the
281
+ * status, not the pointer, says whether it succeeded. */
282
+ if (st != LEPTRIS_OK) {
283
+ const char* detail =
284
+ xsd ? leptris_xsd_error(xsd)
285
+ : leptris_status_string(st);
286
+ cli_error("XSD compile failed: %s",
287
+ detail ? detail : leptris_status_string(st));
288
+ if (xsd) leptris_xsd_free(xsd);
289
+ leptris_document_free(doc);
290
+ return CLI_ERROR_IO;
291
+ }
292
+ if (leptris_xsd_validate(xsd, doc)) {
293
+ printf("xsd: valid\n");
294
+ } else {
295
+ printf("xsd: invalid\n");
296
+ size_t n = leptris_xsd_error_count(xsd);
297
+ for (size_t i = 0; i < n; i++) {
298
+ const char* e = leptris_xsd_error_at(xsd, i);
299
+ if (e) printf(" %s\n", e);
300
+ }
301
+ invalid = 1;
302
+ }
303
+ leptris_xsd_free(xsd);
304
+ }
264
305
  if (sch_path) {
265
306
  cli_result_t r = run_schematron(
266
307
  sch_path, phase, want_svrl, doc, &invalid);
@@ -276,7 +317,8 @@ static cli_result_t validate_execute(int argc, char** argv) {
276
317
 
277
318
  static cli_command_t validate_command = {
278
319
  .name = "validate",
279
- .description = "Validate XML against RELAX NG / Schematron",
320
+ .description =
321
+ "Validate XML against RELAX NG / Schematron / XSD",
280
322
  .execute = validate_execute,
281
323
  .print_help = NULL
282
324
  };
@@ -29,6 +29,8 @@ set(LEPTRIS_SOURCES
29
29
  leptris/rng/parse.c
30
30
  leptris/xsd/compile.c
31
31
  leptris/xsd/datatypes.c
32
+ leptris/xsd/content_model.c
33
+ leptris/xsd/validate.c
32
34
  leptris/rng/rng_public.c
33
35
  leptris/rng/rng_regex.c
34
36
  leptris/rng/validate.c
@@ -920,6 +920,28 @@ LEPTRIS_API int leptris_xsd_builtin_valid(const char* builtin,
920
920
  LEPTRIS_API int leptris_xsd_simple_valid(LeptrisXsdSchema schema,
921
921
  const char* type_name,
922
922
  const char* lexical);
923
+ /* Slice 3 — content models. Validates a child sequence against the
924
+ * compiled content model of a top-level element declaration (its
925
+ * type's sequence/choice/all with occurrence bounds and xs:any
926
+ * wildcards). 1 valid, 0 invalid, -1 unknown element. child_ns may
927
+ * be NULL (all children unqualified). */
928
+ LEPTRIS_API int leptris_xsd_content_valid(
929
+ LeptrisXsdSchema schema, const char* element_name,
930
+ const char* const* child_names, const char* const* child_ns,
931
+ size_t child_count);
932
+ /* Slice 4 — instance validation. Walks the document against the
933
+ * compiled schema: element declarations by name, attribute rows
934
+ * (required use + typed values, lenient qualified spellings),
935
+ * text lexical checks for simple-typed elements, child content
936
+ * models (slice 3). Returns 1 valid, 0 invalid, -1 bad args.
937
+ * Errors accumulate — leptris_xsd_error_count/_at enumerate them
938
+ * (schema-owned; the next validate run replaces them; freed with
939
+ * the schema). */
940
+ LEPTRIS_API int leptris_xsd_validate(LeptrisXsdSchema schema,
941
+ LeptrisDocument doc);
942
+ LEPTRIS_API size_t leptris_xsd_error_count(LeptrisXsdSchema schema);
943
+ LEPTRIS_API const char* leptris_xsd_error_at(LeptrisXsdSchema schema,
944
+ size_t i);
923
945
  /* Validate an instance document against the parsed schema
924
946
  * (phase-2 core subset: element/attribute/text/data/value/
925
947
  * choice/group/interleave/repeats/ref). Returns 1 valid; on 0,