leptris 1.9.201.0-arm-linux → 1.9.201.2-arm-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 +4 -4
- data/CHANGELOG.md +23 -0
- data/Rakefile +52 -12
- data/ext/leptris/native/extconf.rb +85 -0
- data/ext/leptris/native/native.c +1 -1
- data/lib/leptris/version.rb +1 -1
- data/lib/leptris/xml/ffi.rb +13 -0
- data/lib/leptris/xml/native.so +0 -0
- data/vendor-src/libleptris/CHANGELOG.md +8080 -0
- data/vendor-src/libleptris/CLAUDE.md +150 -0
- data/vendor-src/libleptris/CMakeLists.txt +379 -0
- data/vendor-src/libleptris/CMakePresets.json +61 -0
- data/vendor-src/libleptris/CODE_OF_CONDUCT.md +132 -0
- data/vendor-src/libleptris/CONTEXT.md +49 -0
- data/vendor-src/libleptris/LICENSE.md +33 -0
- data/vendor-src/libleptris/README.adoc +1197 -0
- data/vendor-src/libleptris/TODO.assemble/README.md +16 -0
- data/vendor-src/libleptris/TODO.bindings/01-mutation-construction.md +18 -0
- data/vendor-src/libleptris/TODO.bindings/02-incremental-iterparse.md +15 -0
- data/vendor-src/libleptris/TODO.bindings/03-compiled-xpath.md +15 -0
- data/vendor-src/libleptris/TODO.bindings/04-pull-stax-api.md +14 -0
- data/vendor-src/libleptris/TODO.bindings/05-per-parse-options.md +17 -0
- data/vendor-src/libleptris/TODO.bindings/06-serialize-encoding-guarantees.md +14 -0
- data/vendor-src/libleptris/TODO.bindings/README.md +36 -0
- data/vendor-src/libleptris/TODO.concurrency/01-thread-safe-errors.md +19 -0
- data/vendor-src/libleptris/TODO.concurrency/02-export-surface-gate.md +24 -0
- data/vendor-src/libleptris/TODO.concurrency/03-mixed-nodeset-batch.md +14 -0
- data/vendor-src/libleptris/TODO.concurrency/04-canonical-status-message.md +13 -0
- data/vendor-src/libleptris/TODO.concurrency/05-windows-dll-name.md +10 -0
- data/vendor-src/libleptris/TODO.concurrency/06-exslt-pack.md +26 -0
- data/vendor-src/libleptris/TODO.concurrency/07-ns-set-pairs.md +11 -0
- data/vendor-src/libleptris/TODO.concurrency/08-threading-contract.md +45 -0
- data/vendor-src/libleptris/TODO.engine/01-file-sources.md +11 -0
- data/vendor-src/libleptris/TODO.engine/02-compiled-contexts.md +10 -0
- data/vendor-src/libleptris/TODO.engine/03-rust-publish.md +9 -0
- data/vendor-src/libleptris/TODO.engine/04-ruby-release-input.md +8 -0
- data/vendor-src/libleptris/TODO.engine/05-todo-md-refresh.md +7 -0
- data/vendor-src/libleptris/TODO.engine/README.md +16 -0
- data/vendor-src/libleptris/TODO.hygiene/README.md +15 -0
- data/vendor-src/libleptris/TODO.max-perf/00-INDEX.md +22 -0
- data/vendor-src/libleptris/TODO.max-perf/1-simd-html-scanner.md +15 -0
- data/vendor-src/libleptris/TODO.max-perf/10-moxml-plan-followups.md +9 -0
- data/vendor-src/libleptris/TODO.max-perf/2-compiled-dispatch-tokenizer.md +8 -0
- data/vendor-src/libleptris/TODO.max-perf/3-iterparse-fixed-cost.md +5 -0
- data/vendor-src/libleptris/TODO.max-perf/4-compact-node-micro-opts.md +17 -0
- data/vendor-src/libleptris/TODO.max-perf/5-xslt-bench-profiling-rounds.md +13 -0
- data/vendor-src/libleptris/TODO.max-perf/6-language-tails.md +9 -0
- data/vendor-src/libleptris/TODO.max-perf/7-validate-bindings.md +6 -0
- data/vendor-src/libleptris/TODO.max-perf/8-native-xml-diff-consumer.md +5 -0
- data/vendor-src/libleptris/TODO.max-perf/9-prebuilt-gem-matrix.md +14 -0
- data/vendor-src/libleptris/TODO.md +33 -0
- data/vendor-src/libleptris/TODO.transform/README.md +39 -0
- data/vendor-src/libleptris/TODO.validate/README.md +32 -0
- data/vendor-src/libleptris/TODO.xpath2/README.md +91 -0
- data/vendor-src/libleptris/TODO.xslt-full/01-xpath-fn-sequences.md +27 -0
- data/vendor-src/libleptris/TODO.xslt-full/02-xpath-fn-regex.md +13 -0
- data/vendor-src/libleptris/TODO.xslt-full/03-xpath-fn-math.md +10 -0
- data/vendor-src/libleptris/TODO.xslt-full/04-xpath-fn-strings-qname-uri.md +97 -0
- data/vendor-src/libleptris/TODO.xslt-full/05-xpath-fn-dates.md +30 -0
- data/vendor-src/libleptris/TODO.xslt-full/06-xpath-grammar-3x.md +83 -0
- data/vendor-src/libleptris/TODO.xslt-full/07-xpath-function-items.md +124 -0
- data/vendor-src/libleptris/TODO.xslt-full/08-xpath-maps-arrays.md +79 -0
- data/vendor-src/libleptris/TODO.xslt-full/09-xslt-noop-fillins.md +35 -0
- data/vendor-src/libleptris/TODO.xslt-full/10-xslt-tunnel-params.md +9 -0
- data/vendor-src/libleptris/TODO.xslt-full/11-xquery-core.md +119 -0
- data/vendor-src/libleptris/TODO.xslt-full/12-xquery-31.md +65 -0
- data/vendor-src/libleptris/TODO.xslt-full/13-perf-inprocess.md +425 -0
- data/vendor-src/libleptris/TODO.xslt-full/14-html-mode.md +803 -0
- data/vendor-src/libleptris/TODO.xslt-full/15-binding-entries.md +19 -0
- data/vendor-src/libleptris/TODO.xslt-full/16-schematron.md +156 -0
- data/vendor-src/libleptris/TODO.xslt-full/17-xml-diff.md +52 -0
- data/vendor-src/libleptris/TODO.xslt-full/18-compact-nodes.md +278 -0
- data/vendor-src/libleptris/TODO.xslt-full/README.md +26 -0
- data/vendor-src/libleptris/TODO.xslt-full/REMAINING.md +163 -0
- data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/00-triage.md +171 -0
- data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/01-fragment-nodes.md +19 -0
- data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/02-root-node-semantics.md +34 -0
- data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/03-crashes.md +15 -0
- data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/04-namespaces.md +14 -0
- data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/05-number-attrset-sort.md +13 -0
- data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/06-document-chains.md +10 -0
- data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/07-charef-serializer.md +9 -0
- data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/08-perf-gate.md +8 -0
- data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/09-release.md +14 -0
- data/vendor-src/libleptris/VALIDATION.md +151 -0
- data/vendor-src/libleptris/benchmarks/CMakeLists.txt +259 -0
- data/vendor-src/libleptris/benchmarks/README.adoc +228 -0
- data/vendor-src/libleptris/benchmarks/README.md +212 -0
- data/vendor-src/libleptris/benchmarks/common/benchmark.c +252 -0
- data/vendor-src/libleptris/benchmarks/common/benchmark.h +77 -0
- data/vendor-src/libleptris/benchmarks/common/test_data.c +415 -0
- data/vendor-src/libleptris/benchmarks/common/test_data.h +18 -0
- data/vendor-src/libleptris/benchmarks/comprehensive/CMakeLists.txt +184 -0
- data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_decomp.cpp +110 -0
- data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_first_access.cpp +261 -0
- data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_many_attrs.cpp +150 -0
- data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_memory.cpp +185 -0
- data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_parse.cpp +270 -0
- data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_parse_ops.cpp +392 -0
- data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_sax.c +106 -0
- data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_write.cpp +351 -0
- data/vendor-src/libleptris/benchmarks/data/attrs.xml +303 -0
- data/vendor-src/libleptris/benchmarks/data/cdata_test.xml +13 -0
- data/vendor-src/libleptris/benchmarks/data/comment_test.xml +15 -0
- data/vendor-src/libleptris/benchmarks/data/deep.xml +205 -0
- data/vendor-src/libleptris/benchmarks/data/generate_attrs.rb +22 -0
- data/vendor-src/libleptris/benchmarks/data/generate_deep.rb +25 -0
- data/vendor-src/libleptris/benchmarks/data/generate_large.rb +33 -0
- data/vendor-src/libleptris/benchmarks/data/generate_wide.rb +18 -0
- data/vendor-src/libleptris/benchmarks/data/large.xml +21003 -0
- data/vendor-src/libleptris/benchmarks/data/large_workflow.xml +4003 -0
- data/vendor-src/libleptris/benchmarks/data/medium.xml +67 -0
- data/vendor-src/libleptris/benchmarks/data/medium_workflow.xml +353 -0
- data/vendor-src/libleptris/benchmarks/data/pi_test.xml +9 -0
- data/vendor-src/libleptris/benchmarks/data/small.xml +10 -0
- data/vendor-src/libleptris/benchmarks/data/small_workflow.xml +36 -0
- data/vendor-src/libleptris/benchmarks/data/wide.xml +5003 -0
- data/vendor-src/libleptris/benchmarks/dom/bench_document_lifecycle.c +69 -0
- data/vendor-src/libleptris/benchmarks/dom/bench_leptris.c +184 -0
- data/vendor-src/libleptris/benchmarks/dom/bench_libxml2.c +176 -0
- data/vendor-src/libleptris/benchmarks/dom/bench_text_borrowed.c +74 -0
- data/vendor-src/libleptris/benchmarks/dom/dom_benchmark_v2.cpp +314 -0
- data/vendor-src/libleptris/benchmarks/fixtures/large.xml +4003 -0
- data/vendor-src/libleptris/benchmarks/fixtures/large_catalog.xml +50003 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2/eve.xml +6 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2/slashdot.rdf +66 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2/wap.xml +27 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/4rects.xml +11 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/a-valid.xml +10 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/a-wf.xml +9 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/bike.xml +41 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/circle.xml +11 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/defs.xml +14 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/desc.xml +14 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/ellipse.xml +10 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/flower2.xml +44 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/gradient.xml +16 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/group01.xml +15 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/group02.xml +13 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/group03.xml +13 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/image-valid.xml +11 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/image-wf.xml +11 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/lin-gradient.xml +16 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/marker.xml +28 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/mask.xml +13 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/mathswitch.xml +32 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/parentns.xml +12 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/path01.xml +5 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/path02.xml +10 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/patternfill.xml +12 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/polyline.xml +9 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/private.xml +19 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/rad-gradient.xml +17 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/rectangle.xml +10 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/richdesc.xml +12 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/script.xml +13 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/structure01.xml +10 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/style.xml +11 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/switch.xml +21 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/symbol-use.xml +28 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/template.xml +9 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/text01.xml +12 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/text02.xml +17 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/text03.xml +8 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/toap01.xml +10 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/toap02.xml +33 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/transform.xml +26 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/trivial.xml +6 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/twin-gradients.xml +19 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/v-template.xml +9 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/viewport-nest.xml +13 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/viewport-transform.xml +46 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/viewport.xml +11 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/wf-template.xml +7 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_xsdtest.xml +5286 -0
- data/vendor-src/libleptris/benchmarks/fixtures/medium.xml +403 -0
- data/vendor-src/libleptris/benchmarks/fixtures/medium_catalog.xml +3003 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/empty.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/large.xml +1 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/latintest_latin1.xml +1 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/latintest_utf8.xml +1 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/multiline.xml +3 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/small.xml +1 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/truncation.xml +19 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_be.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_be_bom.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_be_clean.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_be_nodecl.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_le.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_le_bom.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_le_clean.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_le_nodecl.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_be.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_be_bom.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_be_clean.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_be_nodecl.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_le.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_le_bom.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_le_clean.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_le_nodecl.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf8.xml +87 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf8_bom.xml +87 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf8_clean.xml +84 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf8_nodecl.xml +86 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml//321/202/320/265/321/201/321/202.xml +1 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/empty.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/large.xml +1 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/latintest_latin1.xml +1 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/latintest_utf8.xml +1 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/multiline.xml +3 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/small.xml +1 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/truncation.xml +19 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_be.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_be_bom.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_be_clean.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_be_nodecl.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_le.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_le_bom.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_le_clean.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_le_nodecl.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_be.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_be_bom.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_be_clean.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_be_nodecl.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_le.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_le_bom.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_le_clean.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_le_nodecl.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf8.xml +87 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf8_bom.xml +87 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf8_clean.xml +84 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf8_nodecl.xml +86 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests//321/202/320/265/321/201/321/202.xml +1 -0
- data/vendor-src/libleptris/benchmarks/fixtures/small.xml +38 -0
- data/vendor-src/libleptris/benchmarks/html/bench_html_parse.c +111 -0
- data/vendor-src/libleptris/benchmarks/html/gen_nokogiri_reference.rb +112 -0
- data/vendor-src/libleptris/benchmarks/html/nokogiri_html_parse.rb +64 -0
- data/vendor-src/libleptris/benchmarks/matrix/README.md +71 -0
- data/vendor-src/libleptris/benchmarks/matrix/bench2html.rb +316 -0
- data/vendor-src/libleptris/benchmarks/matrix/bench_matrix.cpp +724 -0
- data/vendor-src/libleptris/benchmarks/modification/bench_leptris_modify.c +211 -0
- data/vendor-src/libleptris/benchmarks/modification/bench_node_creation.c +130 -0
- data/vendor-src/libleptris/benchmarks/results/BENCHMARK_REPORT.md +226 -0
- data/vendor-src/libleptris/benchmarks/results/baseline_report.md +219 -0
- data/vendor-src/libleptris/benchmarks/results/benchmark_20251223_134550.json +13 -0
- data/vendor-src/libleptris/benchmarks/results/benchmark_20260129_225844.json +13 -0
- data/vendor-src/libleptris/benchmarks/results/leptris_dom_output.txt +24 -0
- data/vendor-src/libleptris/benchmarks/results/leptris_modify.json +36 -0
- data/vendor-src/libleptris/benchmarks/results/leptris_modify_optimized.json +36 -0
- data/vendor-src/libleptris/benchmarks/results/leptris_modify_session1.json +36 -0
- data/vendor-src/libleptris/benchmarks/results/leptris_modify_session2.json +36 -0
- data/vendor-src/libleptris/benchmarks/results/leptris_serialize.json +34 -0
- data/vendor-src/libleptris/benchmarks/results/leptris_xpath_output.txt +24 -0
- data/vendor-src/libleptris/benchmarks/results/libxml2_dom_output.txt +24 -0
- data/vendor-src/libleptris/benchmarks/results/libxml2_xpath_output.txt +24 -0
- data/vendor-src/libleptris/benchmarks/results/phase16_session2.json +21 -0
- data/vendor-src/libleptris/benchmarks/results/phase17.5_session1.json +30 -0
- data/vendor-src/libleptris/benchmarks/results/phase17_session1.json +30 -0
- data/vendor-src/libleptris/benchmarks/results/pugixml_dom_output.txt +51 -0
- data/vendor-src/libleptris/benchmarks/results/xpath_axes_leptris.json +318 -0
- data/vendor-src/libleptris/benchmarks/results/xpath_axes_libxml2.json +318 -0
- data/vendor-src/libleptris/benchmarks/results/xpath_functions_leptris.json +222 -0
- data/vendor-src/libleptris/benchmarks/results/xpath_functions_libxml2.json +222 -0
- data/vendor-src/libleptris/benchmarks/sax/bench_iterparse.c +115 -0
- data/vendor-src/libleptris/benchmarks/sax/bench_leptris.c +124 -0
- data/vendor-src/libleptris/benchmarks/sax/bench_libxml2.c +115 -0
- data/vendor-src/libleptris/benchmarks/serialization/bench_leptris_serialize.c +198 -0
- data/vendor-src/libleptris/benchmarks/src/benchmark_base.h +175 -0
- data/vendor-src/libleptris/benchmarks/twins/mutation_leptris.c +37 -0
- data/vendor-src/libleptris/benchmarks/twins/mutation_pugixml.cpp +28 -0
- data/vendor-src/libleptris/benchmarks/twins/parse_leptris.c +35 -0
- data/vendor-src/libleptris/benchmarks/twins/parse_pugixml.cpp +35 -0
- data/vendor-src/libleptris/benchmarks/utils.c +171 -0
- data/vendor-src/libleptris/benchmarks/utils.h +70 -0
- data/vendor-src/libleptris/benchmarks/workflows/bench_dom_modify.c +325 -0
- data/vendor-src/libleptris/benchmarks/workflows/bench_end_to_end.c +529 -0
- data/vendor-src/libleptris/benchmarks/xpath/bench_axes.c +411 -0
- data/vendor-src/libleptris/benchmarks/xpath/bench_axes_libxml2.c +108 -0
- data/vendor-src/libleptris/benchmarks/xpath/bench_diagnostic.c +431 -0
- data/vendor-src/libleptris/benchmarks/xpath/bench_functions.c +271 -0
- data/vendor-src/libleptris/benchmarks/xpath/bench_functions_libxml2.c +123 -0
- data/vendor-src/libleptris/benchmarks/xpath/bench_leptris.c +78 -0
- data/vendor-src/libleptris/benchmarks/xpath/bench_libxml2.c +98 -0
- data/vendor-src/libleptris/benchmarks/xpath/bench_pugixml.cpp +117 -0
- data/vendor-src/libleptris/benchmarks/xpath/bench_scalar_eval.c +86 -0
- data/vendor-src/libleptris/benchmarks/xpath/bench_scalar_eval_libxml2.c +70 -0
- data/vendor-src/libleptris/benchmarks/xpath/bench_xslt_transform.c +48 -0
- data/vendor-src/libleptris/benchmarks/xslt/bench_dispatch.c +52 -0
- data/vendor-src/libleptris/benchmarks/xslt/bench_dispatch_heavy.c +82 -0
- data/vendor-src/libleptris/benchmarks/xslt/bench_dispatch_pred.c +34 -0
- data/vendor-src/libleptris/benchmarks/xslt/bench_subtree_copy.c +55 -0
- data/vendor-src/libleptris/benchmarks/xslt/bench_valueof.c +46 -0
- data/vendor-src/libleptris/benchmarks/xslt/heavy_lxml.py +48 -0
- data/vendor-src/libleptris/benchmarks/xslt/scorecard_lxml.py +169 -0
- data/vendor-src/libleptris/bindings/ruby/leptris.gemspec +22 -0
- data/vendor-src/libleptris/bindings/ruby/lib/leptris/document.rb +60 -0
- data/vendor-src/libleptris/bindings/ruby/lib/leptris/element.rb +86 -0
- data/vendor-src/libleptris/bindings/ruby/lib/leptris/error.rb +6 -0
- data/vendor-src/libleptris/bindings/ruby/lib/leptris/node.rb +73 -0
- data/vendor-src/libleptris/bindings/ruby/lib/leptris/sax.rb +189 -0
- data/vendor-src/libleptris/bindings/ruby/lib/leptris/xpath.rb +44 -0
- data/vendor-src/libleptris/bindings/ruby/lib/leptris.rb +137 -0
- data/vendor-src/libleptris/bindings/ruby/spec/leptris_spec.rb +113 -0
- data/vendor-src/libleptris/bindings/ruby/spec/sax_spec.rb +141 -0
- data/vendor-src/libleptris/bindings/ruby/spec/spec_helper.rb +7 -0
- data/vendor-src/libleptris/bindings/ruby/test_full.rb +21 -0
- data/vendor-src/libleptris/bindings/rust/Cargo.lock +7 -0
- data/vendor-src/libleptris/bindings/rust/Cargo.toml +13 -0
- data/vendor-src/libleptris/bindings/rust/README.md +61 -0
- data/vendor-src/libleptris/bindings/rust/build.rs +74 -0
- data/vendor-src/libleptris/bindings/rust/src/ffi.rs +204 -0
- data/vendor-src/libleptris/bindings/rust/src/lib.rs +580 -0
- data/vendor-src/libleptris/bindings/rust/tests/integration.rs +156 -0
- data/vendor-src/libleptris/cli/ARCHITECTURE_REVIEW.md +514 -0
- data/vendor-src/libleptris/cli/CLI_ARCHITECTURE.md +851 -0
- data/vendor-src/libleptris/cli/CMakeLists.txt +46 -0
- data/vendor-src/libleptris/cli/cli.c +115 -0
- data/vendor-src/libleptris/cli/cli.h +232 -0
- data/vendor-src/libleptris/cli/commands/diff.c +208 -0
- data/vendor-src/libleptris/cli/commands/format.c +379 -0
- data/vendor-src/libleptris/cli/commands/parse.c +343 -0
- data/vendor-src/libleptris/cli/commands/validate.c +284 -0
- data/vendor-src/libleptris/cli/commands/version.c +49 -0
- data/vendor-src/libleptris/cli/commands/xpath.c +428 -0
- data/vendor-src/libleptris/cli/commands/xquery.c +188 -0
- data/vendor-src/libleptris/cli/completion/leptris.bash +86 -0
- data/vendor-src/libleptris/cli/completion/leptris.zsh +74 -0
- data/vendor-src/libleptris/cli/error.c +394 -0
- data/vendor-src/libleptris/cli/error.h +360 -0
- data/vendor-src/libleptris/cli/leptris +0 -0
- data/vendor-src/libleptris/cli/main.c +127 -0
- data/vendor-src/libleptris/cli/man/leptris-format.1.adoc +226 -0
- data/vendor-src/libleptris/cli/man/leptris-parse.1.adoc +213 -0
- data/vendor-src/libleptris/cli/man/leptris-xpath.1.adoc +479 -0
- data/vendor-src/libleptris/cli/man/leptris.1.adoc +192 -0
- data/vendor-src/libleptris/cli/options.c +451 -0
- data/vendor-src/libleptris/cli/options.h +378 -0
- data/vendor-src/libleptris/cli/output.c +841 -0
- data/vendor-src/libleptris/cli/output.h +361 -0
- data/vendor-src/libleptris/cmake/FindUtf8proc.cmake +56 -0
- data/vendor-src/libleptris/cmake/leptris-config.cmake.in +14 -0
- data/vendor-src/libleptris/cmake/leptris.pc.in +11 -0
- data/vendor-src/libleptris/cmake/modules/AdocMan.cmake +132 -0
- data/vendor-src/libleptris/docs/ARCHITECTURE_REVIEW.md +280 -0
- data/vendor-src/libleptris/docs/Doxyfile +47 -0
- data/vendor-src/libleptris/docs/FFI.md +165 -0
- data/vendor-src/libleptris/docs/README.md +47 -0
- data/vendor-src/libleptris/docs/ROADMAP-SAXON-PARITY.md +194 -0
- data/vendor-src/libleptris/docs/guide/building.md +199 -0
- data/vendor-src/libleptris/docs/guide/getting-started.md +134 -0
- data/vendor-src/libleptris/docs/guide/parsing.md +315 -0
- data/vendor-src/libleptris/docs/guide/xpath-queries.md +444 -0
- data/vendor-src/libleptris/examples/c/CMakeLists.txt +58 -0
- data/vendor-src/libleptris/examples/c/README.md +345 -0
- data/vendor-src/libleptris/examples/c/basic_example.c +80 -0
- data/vendor-src/libleptris/examples/c/dom_traversal_example.c +58 -0
- data/vendor-src/libleptris/examples/c/error_handling_example.c +121 -0
- data/vendor-src/libleptris/examples/c/namespace_example.c +49 -0
- data/vendor-src/libleptris/examples/c/xpath_example.c +74 -0
- data/vendor-src/libleptris/ports/leptris/portfile.cmake +41 -0
- data/vendor-src/libleptris/ports/leptris/usage +28 -0
- data/vendor-src/libleptris/scripts/check_dll_exports.py +54 -0
- data/vendor-src/libleptris/scripts/check_export_surface.py +84 -0
- data/vendor-src/libleptris/scripts/check_ffi_mirrors.py +163 -0
- data/vendor-src/libleptris/scripts/check_formatting.sh +30 -0
- data/vendor-src/libleptris/scripts/check_shared_exports.sh +120 -0
- data/vendor-src/libleptris/scripts/check_trailing_whitespace.sh +18 -0
- data/vendor-src/libleptris/scripts/gen-api-docs.sh +31 -0
- data/vendor-src/libleptris/scripts/run_static_analysis.sh +16 -0
- data/vendor-src/libleptris/scripts/validate.sh +199 -0
- data/vendor-src/libleptris/scripts/xslt_triage.sh +72 -0
- data/vendor-src/libleptris/src/CMakeLists.txt +597 -0
- data/vendor-src/libleptris/src/include/leptris/descriptor.h +178 -0
- data/vendor-src/libleptris/src/include/leptris/dom/document.h +213 -0
- data/vendor-src/libleptris/src/include/leptris/dom/element.h +435 -0
- data/vendor-src/libleptris/src/include/leptris/dom/serialize.h +133 -0
- data/vendor-src/libleptris/src/include/leptris/dtd.h +178 -0
- data/vendor-src/libleptris/src/include/leptris/error.h +97 -0
- data/vendor-src/libleptris/src/include/leptris/sax/sax.h +584 -0
- data/vendor-src/libleptris/src/include/leptris/types.h +386 -0
- data/vendor-src/libleptris/src/include/leptris/xpath/xpath.h +250 -0
- data/vendor-src/libleptris/src/include/leptris/xquery/xquery.h +80 -0
- data/vendor-src/libleptris/src/include/leptris.h +3701 -0
- data/vendor-src/libleptris/src/leptris/chartype.h +124 -0
- data/vendor-src/libleptris/src/leptris/common/chartype.c +90 -0
- data/vendor-src/libleptris/src/leptris/common/chartype.h +44 -0
- data/vendor-src/libleptris/src/leptris/common/cpu.c +40 -0
- data/vendor-src/libleptris/src/leptris/common/cpu.h +63 -0
- data/vendor-src/libleptris/src/leptris/common/entities.c +329 -0
- data/vendor-src/libleptris/src/leptris/common/entities.h +79 -0
- data/vendor-src/libleptris/src/leptris/common/format_number.c +273 -0
- data/vendor-src/libleptris/src/leptris/common/format_number.h +29 -0
- data/vendor-src/libleptris/src/leptris/common/port.h +171 -0
- data/vendor-src/libleptris/src/leptris/common/simd_text.c +237 -0
- data/vendor-src/libleptris/src/leptris/common/simd_text.h +104 -0
- data/vendor-src/libleptris/src/leptris/common/simd_text_avx2.c +105 -0
- data/vendor-src/libleptris/src/leptris/common/simd_text_neon.c +280 -0
- data/vendor-src/libleptris/src/leptris/common/string_view.c +204 -0
- data/vendor-src/libleptris/src/leptris/common/string_view.h +68 -0
- data/vendor-src/libleptris/src/leptris/common/types_internal.h +31 -0
- data/vendor-src/libleptris/src/leptris/core.c +201 -0
- data/vendor-src/libleptris/src/leptris/descriptor/plan.c +527 -0
- data/vendor-src/libleptris/src/leptris/diff/diff.c +491 -0
- data/vendor-src/libleptris/src/leptris/dom/cdata.c +47 -0
- data/vendor-src/libleptris/src/leptris/dom/cdata.h +73 -0
- data/vendor-src/libleptris/src/leptris/dom/comment.c +48 -0
- data/vendor-src/libleptris/src/leptris/dom/comment.h +74 -0
- data/vendor-src/libleptris/src/leptris/dom/compact.c +397 -0
- data/vendor-src/libleptris/src/leptris/dom/compact.h +307 -0
- data/vendor-src/libleptris/src/leptris/dom/diag.c +58 -0
- data/vendor-src/libleptris/src/leptris/dom/diag.h +75 -0
- data/vendor-src/libleptris/src/leptris/dom/digest.c +255 -0
- data/vendor-src/libleptris/src/leptris/dom/doctype.c +137 -0
- data/vendor-src/libleptris/src/leptris/dom/doctype.h +52 -0
- data/vendor-src/libleptris/src/leptris/dom/document_node.c +13 -0
- data/vendor-src/libleptris/src/leptris/dom/document_node.h +21 -0
- data/vendor-src/libleptris/src/leptris/dom/edges.h +60 -0
- data/vendor-src/libleptris/src/leptris/dom/element.c +1114 -0
- data/vendor-src/libleptris/src/leptris/dom/element.h +1109 -0
- data/vendor-src/libleptris/src/leptris/dom/element_index.c +444 -0
- data/vendor-src/libleptris/src/leptris/dom/element_index.h +135 -0
- data/vendor-src/libleptris/src/leptris/dom/element_modify.c +2185 -0
- data/vendor-src/libleptris/src/leptris/dom/element_query.c +1468 -0
- data/vendor-src/libleptris/src/leptris/dom/entity_ref.c +57 -0
- data/vendor-src/libleptris/src/leptris/dom/entity_ref.h +70 -0
- data/vendor-src/libleptris/src/leptris/dom/node.c +420 -0
- data/vendor-src/libleptris/src/leptris/dom/node.h +170 -0
- data/vendor-src/libleptris/src/leptris/dom/node_public.c +937 -0
- data/vendor-src/libleptris/src/leptris/dom/node_vtable.c +138 -0
- data/vendor-src/libleptris/src/leptris/dom/pi.c +70 -0
- data/vendor-src/libleptris/src/leptris/dom/pi.h +80 -0
- data/vendor-src/libleptris/src/leptris/dom/root_doc_map.c +310 -0
- data/vendor-src/libleptris/src/leptris/dom/root_doc_map.h +30 -0
- data/vendor-src/libleptris/src/leptris/dom/text.c +157 -0
- data/vendor-src/libleptris/src/leptris/dom/text.h +119 -0
- data/vendor-src/libleptris/src/leptris/dtd/content_check.c +300 -0
- data/vendor-src/libleptris/src/leptris/dtd/model.c +533 -0
- data/vendor-src/libleptris/src/leptris/dtd/model.h +354 -0
- data/vendor-src/libleptris/src/leptris/dtd/parser.c +827 -0
- data/vendor-src/libleptris/src/leptris/dtd/resolver.c +354 -0
- data/vendor-src/libleptris/src/leptris/dtd/validator.c +668 -0
- data/vendor-src/libleptris/src/leptris/encoding/encoders.c +346 -0
- data/vendor-src/libleptris/src/leptris/encoding/encoders.h +61 -0
- data/vendor-src/libleptris/src/leptris/encoding/encoding.c +451 -0
- data/vendor-src/libleptris/src/leptris/encoding/encoding.h +118 -0
- data/vendor-src/libleptris/src/leptris/encoding/unicode.c +317 -0
- data/vendor-src/libleptris/src/leptris/encoding/unicode.h +64 -0
- data/vendor-src/libleptris/src/leptris/encoding/utf16.c +204 -0
- data/vendor-src/libleptris/src/leptris/encoding/utf16.h +78 -0
- data/vendor-src/libleptris/src/leptris/encoding/wrapper.c +243 -0
- data/vendor-src/libleptris/src/leptris/error.c +134 -0
- data/vendor-src/libleptris/src/leptris/flat/direct_parse.c +1935 -0
- data/vendor-src/libleptris/src/leptris/flat/direct_parse.h +41 -0
- data/vendor-src/libleptris/src/leptris/html/html_parse.c +8040 -0
- data/vendor-src/libleptris/src/leptris/leptris.c +1264 -0
- data/vendor-src/libleptris/src/leptris/leptris_internal.h +910 -0
- data/vendor-src/libleptris/src/leptris/leptris_memory.c +179 -0
- data/vendor-src/libleptris/src/leptris/leptris_memory.h +180 -0
- data/vendor-src/libleptris/src/leptris/leptris_parse.h +195 -0
- data/vendor-src/libleptris/src/leptris/memory/arena.c +243 -0
- data/vendor-src/libleptris/src/leptris/memory/arena.h +93 -0
- data/vendor-src/libleptris/src/leptris/memory/pool.c +1055 -0
- data/vendor-src/libleptris/src/leptris/memory/pool.h +426 -0
- data/vendor-src/libleptris/src/leptris/rng/parse.c +814 -0
- data/vendor-src/libleptris/src/leptris/rng/rng_internal.h +112 -0
- data/vendor-src/libleptris/src/leptris/rng/rng_public.c +159 -0
- data/vendor-src/libleptris/src/leptris/rng/rng_regex.c +453 -0
- data/vendor-src/libleptris/src/leptris/rng/validate.c +1923 -0
- data/vendor-src/libleptris/src/leptris/sax/iterparse.c +435 -0
- data/vendor-src/libleptris/src/leptris/sax/parser.c +105 -0
- data/vendor-src/libleptris/src/leptris/sax/pull.c +489 -0
- data/vendor-src/libleptris/src/leptris/sax/recorder.c +252 -0
- data/vendor-src/libleptris/src/leptris/sax/sax_internal.h +163 -0
- data/vendor-src/libleptris/src/leptris/sax/streaming.c +1469 -0
- data/vendor-src/libleptris/src/leptris/sch/schematron.c +1588 -0
- data/vendor-src/libleptris/src/leptris/serialize/c14n.c +1143 -0
- data/vendor-src/libleptris/src/leptris/serialize/serialize.c +2333 -0
- data/vendor-src/libleptris/src/leptris/serialize/serialize.h +188 -0
- data/vendor-src/libleptris/src/leptris/simd_helpers.h +447 -0
- data/vendor-src/libleptris/src/leptris/unicode/unicode.c +237 -0
- data/vendor-src/libleptris/src/leptris/unicode/unicode.h +113 -0
- data/vendor-src/libleptris/src/leptris/xinclude/xinclude.c +794 -0
- data/vendor-src/libleptris/src/leptris/xpath/bytecode.h +229 -0
- data/vendor-src/libleptris/src/leptris/xpath/compiler.c +1478 -0
- data/vendor-src/libleptris/src/leptris/xpath/evaluator.c +1099 -0
- data/vendor-src/libleptris/src/leptris/xpath/evaluator.h +189 -0
- data/vendor-src/libleptris/src/leptris/xpath/evaluator_axes.c +787 -0
- data/vendor-src/libleptris/src/leptris/xpath/evaluator_internal.h +112 -0
- data/vendor-src/libleptris/src/leptris/xpath/evaluator_operators.c +2138 -0
- data/vendor-src/libleptris/src/leptris/xpath/evaluator_path.c +1312 -0
- data/vendor-src/libleptris/src/leptris/xpath/evaluator_types.c +294 -0
- data/vendor-src/libleptris/src/leptris/xpath/functions.c +2544 -0
- data/vendor-src/libleptris/src/leptris/xpath/functions.h +161 -0
- data/vendor-src/libleptris/src/leptris/xpath/functions_exslt.c +545 -0
- data/vendor-src/libleptris/src/leptris/xpath/functions_ext31.c +4316 -0
- data/vendor-src/libleptris/src/leptris/xpath/lexer.c +636 -0
- data/vendor-src/libleptris/src/leptris/xpath/lexer.h +25 -0
- data/vendor-src/libleptris/src/leptris/xpath/parser.c +2992 -0
- data/vendor-src/libleptris/src/leptris/xpath/parser.h +28 -0
- data/vendor-src/libleptris/src/leptris/xpath/vm.c +2903 -0
- data/vendor-src/libleptris/src/leptris/xpath/xpath_ast_cache.c +319 -0
- data/vendor-src/libleptris/src/leptris/xpath/xpath_compiled.c +263 -0
- data/vendor-src/libleptris/src/leptris/xpath/xpath_internal.h +134 -0
- data/vendor-src/libleptris/src/leptris/xpath/xpath_public.c +1139 -0
- data/vendor-src/libleptris/src/leptris/xpath/xpath_variables.c +410 -0
- data/vendor-src/libleptris/src/leptris/xpath/xpath_variables.h +230 -0
- data/vendor-src/libleptris/src/leptris/xquery/xquery.c +2641 -0
- data/vendor-src/libleptris/src/leptris/xslt/xslt_exec.c +4887 -0
- data/vendor-src/libleptris/src/leptris/xslt/xslt_functions.c +1612 -0
- data/vendor-src/libleptris/src/leptris/xslt/xslt_internal.h +862 -0
- data/vendor-src/libleptris/src/leptris/xslt/xslt_parse.c +2418 -0
- data/vendor-src/libleptris/src/leptris/xslt/xslt_pattern.c +441 -0
- data/vendor-src/libleptris/src/leptris/xslt/xslt_public.c +710 -0
- data/vendor-src/libleptris/src/leptris.symvers +16 -0
- data/vendor-src/libleptris/src/man/libleptris.5.adoc +961 -0
- data/vendor-src/libleptris/test/CMakeLists.txt +234 -0
- data/vendor-src/libleptris/test/README.md +59 -0
- data/vendor-src/libleptris/test/abi/test_descriptor.cpp +441 -0
- data/vendor-src/libleptris/test/abi/test_doctype_api.cpp +51 -0
- data/vendor-src/libleptris/test/abi/test_dom_deep_copy.cpp +110 -0
- data/vendor-src/libleptris/test/abi/test_dom_mutation_bugs.cpp +210 -0
- data/vendor-src/libleptris/test/abi/test_header_hygiene.cpp +269 -0
- data/vendor-src/libleptris/test/abi/test_namespace_mutation_and_create.cpp +198 -0
- data/vendor-src/libleptris/test/abi/test_node_get_xpath.cpp +128 -0
- data/vendor-src/libleptris/test/abi/test_nokogiri_api.cpp +392 -0
- data/vendor-src/libleptris/test/abi/test_parse_fragment.cpp +114 -0
- data/vendor-src/libleptris/test/abi/test_previous_sibling_and_c14n_ex.cpp +299 -0
- data/vendor-src/libleptris/test/abi/test_public_surface.cpp +463 -0
- data/vendor-src/libleptris/test/abi/test_serialize_abi.cpp +67 -0
- data/vendor-src/libleptris/test/abi/test_v0_5_14_bugs.cpp +299 -0
- data/vendor-src/libleptris/test/abi/test_xpath_custom_fns.cpp +106 -0
- data/vendor-src/libleptris/test/cli/test_cli.cpp +493 -0
- data/vendor-src/libleptris/test/common/test_simd_spans.cpp +88 -0
- data/vendor-src/libleptris/test/common/test_simd_text.cpp +142 -0
- data/vendor-src/libleptris/test/concurrency/test_concurrency.cpp +218 -0
- data/vendor-src/libleptris/test/diff/test_diff.cpp +244 -0
- data/vendor-src/libleptris/test/dom/test_compact.cpp +339 -0
- data/vendor-src/libleptris/test/dom/test_digest.cpp +111 -0
- data/vendor-src/libleptris/test/dom/test_document_children.cpp +270 -0
- data/vendor-src/libleptris/test/dom/test_dom.cpp +2310 -0
- data/vendor-src/libleptris/test/dom/test_map_lifecycle.cpp +111 -0
- data/vendor-src/libleptris/test/dom/test_node_surface_parity.cpp +268 -0
- data/vendor-src/libleptris/test/dom/test_text_borrowed.cpp +126 -0
- data/vendor-src/libleptris/test/dom/test_vtable.cpp +108 -0
- data/vendor-src/libleptris/test/dtd/test_dtd_validate.cpp +1227 -0
- data/vendor-src/libleptris/test/dtd/test_w3c_conformance.cpp +212 -0
- data/vendor-src/libleptris/test/fixtures/basic.xml +13 -0
- data/vendor-src/libleptris/test/fixtures/cdata.xml +5 -0
- data/vendor-src/libleptris/test/fixtures/malformed.xml +2 -0
- data/vendor-src/libleptris/test/fixtures/namespaces.xml +11 -0
- data/vendor-src/libleptris/test/fixtures/utf16_decl.xml +5 -0
- data/vendor-src/libleptris/test/fuzz/fuzz_parse.c +40 -0
- data/vendor-src/libleptris/test/html/html5lib-redlist.txt +1366 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/LICENSE +21 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/README.md +11 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/adoption01.dat +354 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/adoption02.dat +39 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/blocks.dat +695 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/comments01.dat +217 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/doctype01.dat +474 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/domjs-unsafe.dat +0 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/entities01.dat +943 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/entities02.dat +309 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/foreign-fragment.dat +645 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/html5test-com.dat +301 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/inbody01.dat +54 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/isindex.dat +49 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/main-element.dat +46 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/math.dat +104 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/menuitem-element.dat +240 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/namespace-sensitivity.dat +22 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/noscript01.dat +237 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/pending-spec-changes-plain-text-unsafe.dat +0 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/pending-spec-changes.dat +46 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/plain-text-unsafe.dat +0 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/ruby.dat +302 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/scriptdata01.dat +372 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/search-element.dat +46 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/svg.dat +104 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tables01.dat +308 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/template.dat +1673 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests1.dat +1956 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests10.dat +849 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests11.dat +523 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests12.dat +62 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests14.dat +75 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests15.dat +216 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests16.dat +2602 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests17.dat +179 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests18.dat +558 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests19.dat +1398 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests2.dat +821 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests20.dat +842 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests21.dat +306 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests22.dat +190 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests23.dat +168 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests24.dat +79 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests25.dat +288 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests26.dat +453 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests3.dat +305 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests4.dat +58 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests5.dat +210 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests6.dat +663 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests7.dat +417 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests8.dat +165 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests9.dat +472 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests_innerHTML_1.dat +843 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tricky01.dat +336 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/webkit01.dat +785 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/webkit02.dat +554 -0
- data/vendor-src/libleptris/test/html/html5lib_cases.h.in +6 -0
- data/vendor-src/libleptris/test/html/nokogiri-parity-redlist.txt +1183 -0
- data/vendor-src/libleptris/test/html/nokogiri-tree-tests.dat +18107 -0
- data/vendor-src/libleptris/test/html/test_html.cpp +2191 -0
- data/vendor-src/libleptris/test/html/test_html5lib.cpp +831 -0
- data/vendor-src/libleptris/test/memory/test_arena.cpp +252 -0
- data/vendor-src/libleptris/test/memory/test_oom_injection.cpp +170 -0
- data/vendor-src/libleptris/test/memory/test_pool.cpp +331 -0
- data/vendor-src/libleptris/test/memory/test_pool_arena.cpp +180 -0
- data/vendor-src/libleptris/test/parser/test_encoding.cpp +282 -0
- data/vendor-src/libleptris/test/parser/test_large_documents.cpp +346 -0
- data/vendor-src/libleptris/test/parser/test_parser.cpp +565 -0
- data/vendor-src/libleptris/test/parser/test_simd_count.cpp +70 -0
- data/vendor-src/libleptris/test/perf/test_perf.cpp +362 -0
- data/vendor-src/libleptris/test/perf/test_stress_high_doc_count.cpp +67 -0
- data/vendor-src/libleptris/test/rng/include-cases/bad-construct.rng +7 -0
- data/vendor-src/libleptris/test/rng/include-cases/bad-override.rng +6 -0
- data/vendor-src/libleptris/test/rng/include-cases/bad-start-override.rng +5 -0
- data/vendor-src/libleptris/test/rng/include-cases/ext-lib.rng +3 -0
- data/vendor-src/libleptris/test/rng/include-cases/ext-main.rng +7 -0
- data/vendor-src/libleptris/test/rng/include-cases/lib.rng +5 -0
- data/vendor-src/libleptris/test/rng/include-cases/lib2.rng +6 -0
- data/vendor-src/libleptris/test/rng/include-cases/main.rng +4 -0
- data/vendor-src/libleptris/test/rng/include-cases/no-href.rng +4 -0
- data/vendor-src/libleptris/test/rng/include-cases/override.rng +8 -0
- data/vendor-src/libleptris/test/rng/include-cases/self-include.rng +4 -0
- data/vendor-src/libleptris/test/rng/include-cases/start-override.rng +5 -0
- data/vendor-src/libleptris/test/rng/jing-cases/000.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/000.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/000.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/001.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/001.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/001.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/002.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/002.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/002.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/003.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/003.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/003.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/004.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/004.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/004.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/005.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/005.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/005.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/006.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/006.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/006.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/007.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/007.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/007.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/008.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/008.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/008.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/009.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/009.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/009.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/010.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/010.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/010.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/011.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/011.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/011.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/012.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/012.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/012.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/013.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/013.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/013.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/014.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/014.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/014.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/015.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/015.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/015.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/016.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/016.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/016.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/017.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/017.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/017.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/018.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/018.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/018.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/019.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/019.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/019.rng +7 -0
- data/vendor-src/libleptris/test/rng/jing-cases/020-book.rng +4 -0
- data/vendor-src/libleptris/test/rng/jing-cases/020.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/020.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/020.rng +3 -0
- data/vendor-src/libleptris/test/rng/jing-cases/README.md +32 -0
- data/vendor-src/libleptris/test/rng/jing-cases/jing-ref.json +212 -0
- data/vendor-src/libleptris/test/rng/jing-cases/meta.json +1 -0
- data/vendor-src/libleptris/test/rng/test_rng.cpp +1365 -0
- data/vendor-src/libleptris/test/rng/test_rng_corpus.cpp +133 -0
- data/vendor-src/libleptris/test/rng/test_rng_corpus_msg.cpp +233 -0
- data/vendor-src/libleptris/test/sax/test_iterparse.cpp +203 -0
- data/vendor-src/libleptris/test/sax/test_pull.cpp +214 -0
- data/vendor-src/libleptris/test/sax/test_pull_batch.cpp +201 -0
- data/vendor-src/libleptris/test/sax/test_recorder.cpp +265 -0
- data/vendor-src/libleptris/test/sax/test_sax.cpp +665 -0
- data/vendor-src/libleptris/test/sax/test_streaming.cpp +434 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/README.md +15 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/extends-baseuri-fixup-01.xml +28 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/extends-recursive-01.xml +27 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/include-baseuri-fixup-01.xml +24 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/include-recursive-01.xml +24 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-name-collision-error-01.xml +20 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-name-collision-error-02.xml +20 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-name-collision-error-03.xml +20 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-name-collision-error-04.xml +23 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-name-collision-error-05.xml +20 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-name-collision-error-06.xml +25 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-pattern-global-01.xml +24 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-reference-undefined-01.xml +18 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-reference-undefined-02.xml +18 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-reference-undefined-03.xml +18 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-reference-undefined-04.xml +19 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-reference-undefined-05.xml +20 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-reference-undefined-06.xml +20 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-reference-undefined-07.xml +18 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-rule-global-01.xml +20 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-rule-global-02.xml +23 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-scope-pattern-01.xml +25 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-scope-phase-01.xml +23 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-scope-rule-01.xml +23 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-value-element-content-01.xml +33 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/pattern-abstract-01.xml +22 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/pattern-subordinate-document-01.xml +21 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/pattern-subordinate-document-02.xml +21 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-abstract-01.xml +21 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-abstract-02.xml +23 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-attribute-01.xml +18 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-comment-01.xml +20 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-element-01.xml +18 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-pi-01.xml +20 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-root-01.xml +18 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-text-01.xml +18 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-variable-01.xml +22 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-variable-02.xml +25 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-variable-03.xml +22 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-order-01.xml +21 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/schema-default-phase-01.xml +26 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/schema-default-phase-02.xml +25 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/svrl-diagnostic-01.xml +28 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/svrl-diagnostic-02.xml +25 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/svrl-name-nopath-01.xml +23 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/svrl-name-path-01.xml +23 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/svrl-property-01.xml +28 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/svrl-property-copy-of.xml +26 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/svrl-value-of-01.xml +23 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/xslt-key-01.xml +19 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/xslt-key-element-content-01.xml +21 -0
- data/vendor-src/libleptris/test/sch/test_schematron.cpp +337 -0
- data/vendor-src/libleptris/test/sch/test_schematron_corpus.cpp +421 -0
- data/vendor-src/libleptris/test/serializer/test_c14n.cpp +539 -0
- data/vendor-src/libleptris/test/serializer/test_serialize.cpp +890 -0
- data/vendor-src/libleptris/test/smoke/test_smoke.cpp +41 -0
- data/vendor-src/libleptris/test/xinclude/test_xinclude.cpp +903 -0
- data/vendor-src/libleptris/test/xpath/test_bytecode_vm.cpp +755 -0
- data/vendor-src/libleptris/test/xpath/test_compiled.cpp +171 -0
- data/vendor-src/libleptris/test/xpath/test_exslt.cpp +141 -0
- data/vendor-src/libleptris/test/xpath/test_xpath.cpp +2433 -0
- data/vendor-src/libleptris/test/xpath/test_xpath_conformance.cpp +570 -0
- data/vendor-src/libleptris/test/xpath/test_xslt.cpp +4245 -0
- data/vendor-src/libleptris/test/xquery/books.xml +1 -0
- data/vendor-src/libleptris/test/xquery/qt3/README.md +28 -0
- data/vendor-src/libleptris/test/xquery/qt3/fn/concat.xml +878 -0
- data/vendor-src/libleptris/test/xquery/qt3/fn/contains.xml +795 -0
- data/vendor-src/libleptris/test/xquery/qt3/fn/ends-with.xml +556 -0
- data/vendor-src/libleptris/test/xquery/qt3/fn/starts-with.xml +644 -0
- data/vendor-src/libleptris/test/xquery/qt3/fn/substring/concepts.xml +1 -0
- data/vendor-src/libleptris/test/xquery/qt3/fn/substring.xml +449 -0
- data/vendor-src/libleptris/test/xquery/test_qt3.cpp +324 -0
- data/vendor-src/libleptris/test/xquery/test_xquery.cpp +768 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/ATTRIBUTION.md +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/array.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/array.xml +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/array.xsl +26 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-1-.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-1-.xml +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-1-.xsl +21 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-10-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-10-.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-10-.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-100.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-100.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-100.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-101.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-101.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-101.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-102-inc.xsl +21 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-102.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-102.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-102.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-103.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-103.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-103.xsl +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-104.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-104.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-104.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-105.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-105.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-105.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-106.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-106.xml +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-106.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-107.out +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-107.xml +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-107.xsl +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-108.out +25 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-108.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-108.xsl +21 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-109.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-109.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-109.xsl +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-11-.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-11-.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-11-.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-110.ent +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-110.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-110.xml +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-110.xsl +20 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-111.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-111.xml +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-111.xsl +45 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-112.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-112.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-112.xsl +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-113.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-113.xml +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-113.xsl +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-114.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-114.xml +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-114.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-115.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-115.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-115.xsl +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-116.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-116.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-116.xsl +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-117.out +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-117.xml +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-117.xsl +59 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-118.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-118.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-118.xsl +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-119.out +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-119.xml +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-119.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-12-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-12-.xml +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-12-.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-120.out +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-120.xml +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-120.xsl +27 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-121.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-121.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-121.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-122.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-122.xml +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-122.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-123.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-123.xml +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-123.xsl +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-124.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-124.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-124.xsl +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-125.out +351 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-125.xml +118 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-125.xsl +99 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-126.out +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-126.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-126.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-127.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-127.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-127.xsl +18 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-128.out +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-128.xml +26 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-128.xsl +26 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-129.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-129.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-129.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-13-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-13-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-13-.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130-imp1.imp +25 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130-imp2.imp +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130-imp3.imp +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130-imp4.imp +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130.doc +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130.xsl +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-131-imp.imp +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-131.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-131.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-131.xsl +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-132.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-132.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-132.xsl +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-133.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-133.xml +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-133.xsl +32 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-134.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-134.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-134.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-135.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-135.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-135.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-136.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-136.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-136.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-137.imp +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-137.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-137.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-137.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-138.out +23 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-138.xml +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-138.xsl +28 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-139.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-139.xml +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-139.xsl +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-14-.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-14-.xml +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-14-.xsl +23 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-140.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-140.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-140.xsl +32 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-141.out +46 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-141.xml +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-141.xsl +25 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-142.out +35 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-142.xml +65 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-142.xsl +85 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-143.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-143.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-143.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-144.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-144.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-144.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-145.err +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-145.xml +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-145.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147-1.imp +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147-2.imp +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147-3.imp +57 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147-4.imp +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147-5.imp +27 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147-6.imp +31 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147.out +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147.xml +21 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147.xsl +29 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-148.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-148.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-148.xsl +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-149.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-149.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-149.xsl +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-15-.out +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-15-.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-15-.xsl +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-150.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-150.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-150.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-151.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-151.xsl +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-152.out +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-152.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-152.xsl +30 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-153.doc +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-153.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-153.xml +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-153.xsl +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-154.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-154.xsl +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-155.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-155.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-155.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-156.err +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-156.imp1.imp +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-156.imp2.imp +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-156.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-156.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-157.err +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-157.out +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-157.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-157.xsl +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-158.doc +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-158.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-158.xml +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-158.xsl +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-159.out +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-159.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-159.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-16-.out +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-16-.xml +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-16-.xsl +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-160.out +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-160.xml +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-160.xsl +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-161.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-161.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-161.xsl +18 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-163.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-163.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-163.xsl +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-164.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-164.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-164.xsl +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-165.err +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-165.xml +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-165.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-166.out +15256 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-166.xml +15255 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-166.xsl +131 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-167.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-167.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-167.xsl +20 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-168.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-168.xml +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-168.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-169.imp +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-169.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-169.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-169.xsl +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-17-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-17-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-17-.xsl +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-170.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-170.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-170.xsl +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-171.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-171.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-171.xsl +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-172.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-172.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-172.xsl +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-173.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-173.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-173.xsl +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-174.err +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-174.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-174.xsl +18 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-175.err +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-175.out +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-175.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-175.xsl +33 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-176.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-176.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-176.xsl +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-177.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-177.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-177.xsl +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-178.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-178.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-178.xsl +18 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-179.out +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-179.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-179.xsl +24 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-18-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-18-.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-18-.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-180.err +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-180.xml +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-180.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-181.out +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-181.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-181.xsl +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-182.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-182.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-182.xsl +21 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-183.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-183.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-183.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-184.err +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-184.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-184.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-186.out +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-186.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-186.xsl +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-187.err +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-187.out +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-187.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-187.xsl +42 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-188-imp.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-188.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-188.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-188.xsl +20 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-189.out +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-189.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-189.xsl +25 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-19-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-19-.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-19-.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-190-imp.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-190.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-190.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-190.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-191-imp.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-191.err +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-191.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-191.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-192.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-192.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-192.xsl +33 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-193.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-193.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-193.xsl +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-194.err +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-194.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-194.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-195.out +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-195.xml +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-195.xsl +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-196.out +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-196.xml +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-196.xsl +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-197.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-197.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-197.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-198.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-198.xml +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-198.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-199.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-199.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-199.xsl +18 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-2-.out +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-2-.xml +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-2-.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-20-.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-20-.xml +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-20-.xsl +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-200.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-200.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-200.xsl +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-201.err +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-201.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-201.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-202.err +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-202.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-202.xsl +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-203.err +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-203.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-203.xsl +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-204.err +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-204.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-204.xsl +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-205.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-205.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-205.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-206.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-206.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-206.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-207.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-207.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-207.xsl +61 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-208.err +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-208.xml +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-208.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-209.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-209.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-209.xsl +21 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-21-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-21-.xml +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-21-.xsl +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-210.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-210.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-210.xsl +20 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-211.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-211.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-211.xsl +26 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-212.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-212.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-212.xsl +25 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-213.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-213.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-213.xsl +26 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-214.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-214.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-214.xsl +25 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-215.err +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-215.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-215.xsl +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-216.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-216.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-216.xsl +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-217.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-217.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-217.xsl +24 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-218.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-218.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-218.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-219.out +68 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-219.xml +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-219.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-22-.out +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-22-.xml +18 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-22-.xsl +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-220.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-220.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-220.xsl +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-221.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-221.xml +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-221.xsl +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-222.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-222.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-222.xsl +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-223-imp.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-223-inc.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-223.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-223.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-223.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-224.out +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-224.xml +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-224.xsl +28 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-225.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-225.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-225.xsl +32 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-23-.out +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-23-.xml +21 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-23-.xsl +20 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-24-.out +27 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-24-.xml +2419 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-24-.xsl +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-25-.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-25-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-25-.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-26-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-26-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-26-.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-27-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-27-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-27-.xsl +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-28-.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-28-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-28-.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-29-.ent +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-29-.out +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-29-.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-29-.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-3-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-3-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-3-.xsl +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-30-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-30-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-30-.xsl +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-31-.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-31-.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-31-.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-32-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-32-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-32-.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-33-.out +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-33-.xml +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-33-.xsl +29 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-35-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-35-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-35-.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-36-.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-36-.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-36-.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-36-inc.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-37-.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-37-.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-37-.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-37-inc.xsl +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-38-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-38-.xml +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-38-.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-39-.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-39-.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-39-.xsl +34 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-4-.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-4-.xml +38 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-4-.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-40-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-40-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-40-.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-41-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-41-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-41-.xsl +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-42-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-42-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-42-.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-43-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-43-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-43-.xsl +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-44-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-44-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-44-.xsl +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-45-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-45-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-45-.xsl +27 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-46-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-46-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-46-.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-47-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-47-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-47-.xsl +18 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-48-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-48-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-48-.xsl +24 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-49-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-49-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-49-.xsl +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-5-.out +954 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-5-.xml +475 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-5-.xsl +158 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-50-.out +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-50-.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-50-.xsl +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-52.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-52.xml +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-52.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-53.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-53.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-53.xsl +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-54.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-54.xml +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-54.xsl +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-55.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-55.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-55.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-56.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-56.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-56.xsl +28 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-57.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-57.xml +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-57.xsl +21 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-58.xsl +274 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-59.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-59.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-59.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-6-.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-6-.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-6-.xsl +32 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-60.err +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-60.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-60.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-60.xsl +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-61.out +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-61.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-61.xsl +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-62-inc.xsl +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-62.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-62.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-62.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-63.out +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-63.xml +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-63.xsl +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-64.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-64.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-64.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-65.ent +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-65.out +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-65.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-65.xsl +26 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-66.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-66.xml +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-66.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-68.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-68.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-68.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-69.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-69.xml +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-69.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-7-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-7-.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-7-.xsl +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-70.out +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-70.xml +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-70.xsl +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-71.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-71.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-71.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-72.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-72.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-72.xsl +31 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-73.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-73.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-73.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-74.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-74.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-74.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-75.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-75.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-75.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-76.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-76.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-76.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-77.out +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-77.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-77.xsl +18 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-78.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-78.xml +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-78.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-79.out +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-79.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-79.xsl +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-8-.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-8-.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-8-.xsl +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-80.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-80.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-80.xsl +29 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-81.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-81.xml +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-81.xsl +18 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-82.out +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-82.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-82.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-83.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-83.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-83.xsl +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-84.out +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-84.xml +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-84.xsl +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-86.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-86.xml +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-86.xsl +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-87.out +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-87.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-87.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-88.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-88.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-88.xsl +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-89.out +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-89.xml +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-89.xsl +105 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-9-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-9-.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-9-.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-90.out +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-90.xml +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-90.xsl +35 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-91.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-91.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-91.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-92.out +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-92.xml +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-92.xsl +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-93-inc.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-93.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-93.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-93.xsl +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-94.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-94.xml +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-94.xsl +35 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-95.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-95.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-95.xsl +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-96.out +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-96.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-96.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-97.out +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-97.xml +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-97.xsl +32 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-98.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-98.xml +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-98.xsl +31 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-99.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-99.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-99.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/character.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/character.xml +23 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/character.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/date_add.out +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/date_add.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/date_add.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/doc.dtd +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/doc.out +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/doc.xml +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/doc.xsl +62 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/inner.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/items.xml +34 -0
- data/vendor-src/libleptris/test/xslt/open_cases.txt +0 -0
- data/vendor-src/libleptris/test/xslt/test_libxslt_suite.cpp +398 -0
- data/vendor-src/libleptris/vcpkg.json +29 -0
- data/vendor-src/utf8proc/CMakeLists.txt +133 -0
- data/vendor-src/utf8proc/Doxyfile +2765 -0
- data/vendor-src/utf8proc/LICENSE.md +93 -0
- data/vendor-src/utf8proc/MANIFEST +9 -0
- data/vendor-src/utf8proc/Makefile +203 -0
- data/vendor-src/utf8proc/NEWS.md +479 -0
- data/vendor-src/utf8proc/README.md +143 -0
- data/vendor-src/utf8proc/appveyor.yml +46 -0
- data/vendor-src/utf8proc/bench/Makefile +40 -0
- data/vendor-src/utf8proc/bench/bench.c +56 -0
- data/vendor-src/utf8proc/bench/icu.c +61 -0
- data/vendor-src/utf8proc/bench/unistring.c +60 -0
- data/vendor-src/utf8proc/bench/util.c +39 -0
- data/vendor-src/utf8proc/bench/util.h +22 -0
- data/vendor-src/utf8proc/cmake/utf8proc-config.cmake.in +5 -0
- data/vendor-src/utf8proc/data/Makefile +62 -0
- data/vendor-src/utf8proc/data/Manifest.toml +16 -0
- data/vendor-src/utf8proc/data/Project.toml +2 -0
- data/vendor-src/utf8proc/data/data_generator.jl +498 -0
- data/vendor-src/utf8proc/libutf8proc.pc.cmakein +10 -0
- data/vendor-src/utf8proc/libutf8proc.pc.in +10 -0
- data/vendor-src/utf8proc/lump.md +27 -0
- data/vendor-src/utf8proc/test/app/CMakeLists.txt +6 -0
- data/vendor-src/utf8proc/test/app/app.c +9 -0
- data/vendor-src/utf8proc/test/case.c +76 -0
- data/vendor-src/utf8proc/test/charwidth.c +91 -0
- data/vendor-src/utf8proc/test/custom.c +28 -0
- data/vendor-src/utf8proc/test/fuzz_main.c +54 -0
- data/vendor-src/utf8proc/test/fuzzer.c +97 -0
- data/vendor-src/utf8proc/test/graphemetest.c +136 -0
- data/vendor-src/utf8proc/test/iscase.c +63 -0
- data/vendor-src/utf8proc/test/iterate.c +168 -0
- data/vendor-src/utf8proc/test/maxdecomposition.c +22 -0
- data/vendor-src/utf8proc/test/misc.c +51 -0
- data/vendor-src/utf8proc/test/normtest.c +64 -0
- data/vendor-src/utf8proc/test/ossfuzz.sh +13 -0
- data/vendor-src/utf8proc/test/printproperty.c +68 -0
- data/vendor-src/utf8proc/test/tests.c +60 -0
- data/vendor-src/utf8proc/test/tests.h +27 -0
- data/vendor-src/utf8proc/test/valid.c +41 -0
- data/vendor-src/utf8proc/utf8proc.c +834 -0
- data/vendor-src/utf8proc/utf8proc.h +794 -0
- data/vendor-src/utf8proc/utf8proc_data.c +17141 -0
- data/vendor-src/utf8proc/utils.cmake +20 -0
- metadata +1528 -2
|
@@ -0,0 +1,2903 @@
|
|
|
1
|
+
/* lib/src/xpath/vm.c — XPath bytecode VM interpreter (TODO 120 Phase F)
|
|
2
|
+
*
|
|
3
|
+
* Stack-based interpreter for the bytecode emitted by compiler.c.
|
|
4
|
+
* The VM holds `struct leptris_xpath_result*` values on its stack.
|
|
5
|
+
*
|
|
6
|
+
* Inline handlers (Phase F):
|
|
7
|
+
* BC_LITERAL_NUMBER / STRING / BOOL
|
|
8
|
+
* → push a fresh XPathResult.
|
|
9
|
+
* BC_PATH_ABSOLUTE
|
|
10
|
+
* → push document root as single-node nodeset.
|
|
11
|
+
* BC_PATH_RELATIVE
|
|
12
|
+
* → push context node as single-node nodeset.
|
|
13
|
+
* BC_AXIS_STEP
|
|
14
|
+
* → pop input nodeset, call evaluate_step(ctx, ast, input),
|
|
15
|
+
* push result nodeset. Reuses the existing axis + node-test
|
|
16
|
+
* + predicate machinery.
|
|
17
|
+
* BC_BINARY_OP
|
|
18
|
+
* → pop two operands, apply arithmetic / comparison / boolean
|
|
19
|
+
* logic inline. Avoids the AST-node walking that
|
|
20
|
+
* evaluate_operator would do.
|
|
21
|
+
* BC_FUNC_CALL
|
|
22
|
+
* → call evaluate_function_call(ctx, ast) directly. Skips the
|
|
23
|
+
* evaluate_expr AST-type switch.
|
|
24
|
+
* BC_FALLBACK_EVAL
|
|
25
|
+
* → call evaluate_expr(ctx, ast). Used for variable refs and
|
|
26
|
+
* any AST shape the compiler doesn't specifically lower.
|
|
27
|
+
* BC_RETURN
|
|
28
|
+
* → pop and return as final result.
|
|
29
|
+
*
|
|
30
|
+
* The VM is COMPLETE: every XPath expression compiles to a sequence
|
|
31
|
+
* of these opcodes and evaluates correctly. The inline handlers
|
|
32
|
+
* exist to reduce dispatch overhead; correctness is identical to
|
|
33
|
+
* direct AST evaluation because the inline handlers call into the
|
|
34
|
+
* same evaluator helpers.
|
|
35
|
+
*/
|
|
36
|
+
#include "bytecode.h"
|
|
37
|
+
#include "xpath_variables.h"
|
|
38
|
+
#include "evaluator_internal.h"
|
|
39
|
+
#include "../dom/document_node.h"
|
|
40
|
+
#include "functions.h"
|
|
41
|
+
#include "../leptris_internal.h"
|
|
42
|
+
#include "../dom/element.h"
|
|
43
|
+
#include "../common/entities.h"
|
|
44
|
+
#include "../dom/element_index.h"
|
|
45
|
+
#include "../dom/text.h"
|
|
46
|
+
#include "../dom/node.h"
|
|
47
|
+
#include "../dom/pi.h"
|
|
48
|
+
#include <stdlib.h>
|
|
49
|
+
#include <string.h>
|
|
50
|
+
#include <stdio.h>
|
|
51
|
+
#include <math.h>
|
|
52
|
+
|
|
53
|
+
typedef struct {
|
|
54
|
+
struct leptris_xpath_result** stack;
|
|
55
|
+
size_t sp;
|
|
56
|
+
size_t cap;
|
|
57
|
+
int error;
|
|
58
|
+
} XPathVM;
|
|
59
|
+
|
|
60
|
+
static int vm_push(XPathVM* vm, struct leptris_xpath_result* v) {
|
|
61
|
+
if (vm->sp >= vm->cap) {
|
|
62
|
+
size_t new_cap = vm->cap ? vm->cap * 2 : 16;
|
|
63
|
+
struct leptris_xpath_result** grown =
|
|
64
|
+
(struct leptris_xpath_result**)realloc(vm->stack,
|
|
65
|
+
new_cap * sizeof(struct leptris_xpath_result*));
|
|
66
|
+
if (!grown) { vm->error = 1; return -1; }
|
|
67
|
+
vm->stack = grown;
|
|
68
|
+
vm->cap = new_cap;
|
|
69
|
+
}
|
|
70
|
+
vm->stack[vm->sp++] = v;
|
|
71
|
+
return 0;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
static struct leptris_xpath_result* vm_pop(XPathVM* vm) {
|
|
75
|
+
if (vm->sp == 0) { vm->error = 1; return NULL; }
|
|
76
|
+
return vm->stack[--vm->sp];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
static uint8_t read_u8(const unsigned char** pc) {
|
|
80
|
+
uint8_t v = *pc[0];
|
|
81
|
+
*pc += 1;
|
|
82
|
+
return v;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
static uint16_t read_u16(const unsigned char** pc) {
|
|
86
|
+
uint16_t v = ((uint16_t)(*pc)[0] << 8) | (*pc)[1];
|
|
87
|
+
*pc += 2;
|
|
88
|
+
return v;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
static double read_double(const unsigned char** pc) {
|
|
92
|
+
double v;
|
|
93
|
+
memcpy(&v, *pc, sizeof(double));
|
|
94
|
+
*pc += sizeof(double);
|
|
95
|
+
return v;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* Build a single-node nodeset from a context element. Caller owns
|
|
99
|
+
* the returned result. */
|
|
100
|
+
static struct leptris_xpath_result* make_singleton_nodeset(void* node) {
|
|
101
|
+
struct leptris_xpath_result* r =
|
|
102
|
+
(struct leptris_xpath_result*)calloc(1, sizeof(*r));
|
|
103
|
+
if (!r) return NULL;
|
|
104
|
+
r->type = XPATH_RESULT_NODESET;
|
|
105
|
+
r->value.nodeset_value = xpath_nodeset_new();
|
|
106
|
+
if (!r->value.nodeset_value) {
|
|
107
|
+
free(r);
|
|
108
|
+
return NULL;
|
|
109
|
+
}
|
|
110
|
+
if (node) xpath_nodeset_add(r->value.nodeset_value, node);
|
|
111
|
+
return r;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/* ----------------------------------------------------------------------- *
|
|
115
|
+
* Specialized axis handlers (TODO 126).
|
|
116
|
+
*
|
|
117
|
+
* Each handler pops the input nodeset from the VM stack, walks the
|
|
118
|
+
* tree inline (bypassing evaluate_step / apply_axis / matches_node_test),
|
|
119
|
+
* and returns a freshly-allocated result.
|
|
120
|
+
*
|
|
121
|
+
* `name` is NULL for wildcards; otherwise a NUL-terminated C string
|
|
122
|
+
* to match against element names. The compiler only emits these
|
|
123
|
+
* opcodes for the no-namespace-prefix case (no ':' in test value).
|
|
124
|
+
* ----------------------------------------------------------------------- */
|
|
125
|
+
|
|
126
|
+
/* Common preamble: pop input nodeset, detach it from the result
|
|
127
|
+
* wrapper, free the wrapper. Returns the detached nodeset or NULL
|
|
128
|
+
* on error (vm->error is set). */
|
|
129
|
+
static XPathNodeSet* vm_detach_input_nodeset(XPathVM* vm) {
|
|
130
|
+
struct leptris_xpath_result* input = vm_pop(vm);
|
|
131
|
+
if (!input || input->type != XPATH_RESULT_NODESET) {
|
|
132
|
+
if (input) xpath_result_free(input);
|
|
133
|
+
vm->error = 1;
|
|
134
|
+
return NULL;
|
|
135
|
+
}
|
|
136
|
+
XPathNodeSet* ns = input->value.nodeset_value;
|
|
137
|
+
input->value.nodeset_value = NULL;
|
|
138
|
+
xpath_result_free(input);
|
|
139
|
+
return ns;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/* Helper: is this node an element (vs attribute / text / etc.)?
|
|
143
|
+
* The VM opcodes only accept element input; non-element inputs are
|
|
144
|
+
* skipped (matches the existing axis behavior for non-element context). */
|
|
145
|
+
static int node_is_element(void* node) {
|
|
146
|
+
if (!node) return 0;
|
|
147
|
+
/* Unified tag space (issue #477): every node — real DOM node or
|
|
148
|
+
* synthetic attribute/namespace/text node — is classified by its
|
|
149
|
+
* first int; 0 is the public element tag, nothing else uses it. */
|
|
150
|
+
return *(LeptrisNodeType*)node == LEPTRIS_NODE_ELEMENT;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
struct leptris_xpath_result* vm_apply_axis_child(XPathContext* ctx, XPathVM* vm,
|
|
154
|
+
const char* name, int wild);
|
|
155
|
+
struct leptris_xpath_result* vm_apply_axis_attribute(XPathContext* ctx, XPathVM* vm,
|
|
156
|
+
const char* name, int wild);
|
|
157
|
+
struct leptris_xpath_result* vm_apply_axis_self(XPathContext* ctx, XPathVM* vm,
|
|
158
|
+
const char* name, int wild);
|
|
159
|
+
struct leptris_xpath_result* vm_apply_axis_parent(XPathContext* ctx, XPathVM* vm,
|
|
160
|
+
const char* name, int wild);
|
|
161
|
+
struct leptris_xpath_result* vm_apply_axis_descendant(XPathContext* ctx, XPathVM* vm,
|
|
162
|
+
const char* name, int wild,
|
|
163
|
+
int include_self);
|
|
164
|
+
|
|
165
|
+
/* Forward decl for fused handler (TODO 134). */
|
|
166
|
+
static struct leptris_xpath_result* vm_apply_axis_descendant_pred_attr(
|
|
167
|
+
XPathContext* ctx, XPathVM* vm,
|
|
168
|
+
const char* attr_name, const char* attr_value,
|
|
169
|
+
int value_match, int include_self);
|
|
170
|
+
|
|
171
|
+
/* Forward decl: descendant_walk is defined below, but vm_apply_absolute
|
|
172
|
+
* uses it. */
|
|
173
|
+
static void descendant_walk(XPathContext* ctx, XPathNodeSet* out, LeptrisElement elem,
|
|
174
|
+
const char* name, int wild, int include_self);
|
|
175
|
+
|
|
176
|
+
/* Absolute-path handlers (TODO 129). Like vm_apply_axis_descendant
|
|
177
|
+
* but starts from the document root element directly, with the
|
|
178
|
+
* document-root semantics: `/foo` matches root itself (not its
|
|
179
|
+
* children), `//foo` walks the entire tree.
|
|
180
|
+
*
|
|
181
|
+
* `mode` controls behavior:
|
|
182
|
+
* 0 = root-match only: push [root] if root matches name/wild.
|
|
183
|
+
* Used for BC_ABSOLUTE_ROOT_MATCH (child axis from document).
|
|
184
|
+
* 1 = descendant: push all descendants of root matching name.
|
|
185
|
+
* Used for BC_ABSOLUTE_DESCENDANT (descendant axis).
|
|
186
|
+
* 2 = descendant-or-self: push root if matches + descendants
|
|
187
|
+
* matching. Used for BC_ABSOLUTE_DESCENDANT_OR_SELF. */
|
|
188
|
+
/* Absolute `//type-test` (issue #485): one pre-order walk of the
|
|
189
|
+
* root subtree emitting matching nodes directly in document order.
|
|
190
|
+
* This replaces the generic two-step form (descendant-or-self::node()
|
|
191
|
+
* + child::type()) whose per-context merge needs a doc-order sort.
|
|
192
|
+
* `want`: 0=node(), 1=text(), 2=comment(), 3=processing-instruction().
|
|
193
|
+
* pi_target is only consulted for want==3 (NULL = any target). */
|
|
194
|
+
static void vm_absolute_type_walk(XPathNodeSet* out, LeptrisElement elem,
|
|
195
|
+
int want, const char* pi_target) {
|
|
196
|
+
LeptrisNode* child = leptris_elem_first_child(elem);
|
|
197
|
+
while (child) {
|
|
198
|
+
int match = 0;
|
|
199
|
+
switch (want) {
|
|
200
|
+
case 0: /* node() */
|
|
201
|
+
match = 1;
|
|
202
|
+
break;
|
|
203
|
+
case 1: /* text() — CDATA sections count as text */
|
|
204
|
+
match = (child->type == LEPTRIS_NODE_TYPE_TEXT ||
|
|
205
|
+
child->type == LEPTRIS_NODE_TYPE_CDATA);
|
|
206
|
+
break;
|
|
207
|
+
case 2: /* comment() */
|
|
208
|
+
match = (child->type == LEPTRIS_NODE_TYPE_COMMENT);
|
|
209
|
+
break;
|
|
210
|
+
case 3: /* processing-instruction([target]) */
|
|
211
|
+
if (child->type == LEPTRIS_NODE_TYPE_PI) {
|
|
212
|
+
if (pi_target) {
|
|
213
|
+
LeptrisPINode* pi = (LeptrisPINode*)child;
|
|
214
|
+
match = pi->target &&
|
|
215
|
+
strcmp(pi->target, pi_target) == 0;
|
|
216
|
+
} else {
|
|
217
|
+
match = 1;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
break;
|
|
221
|
+
default:
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
if (match) xpath_nodeset_add_fast(out, child);
|
|
225
|
+
if (child->type == LEPTRIS_NODE_TYPE_ELEMENT) {
|
|
226
|
+
vm_absolute_type_walk(out, (LeptrisElement)child, want, pi_target);
|
|
227
|
+
}
|
|
228
|
+
child = leptris_node_get_next_sibling(child);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/* Issue #525 (XPath 1.0 §2.3): an UNPREFIXED name test matches only
|
|
233
|
+
* elements in NO namespace — a default-xmlns element is in a
|
|
234
|
+
* namespace even though it has no prefix. Documents without any
|
|
235
|
+
* namespace declaration skip the check (zero-cost common case). */
|
|
236
|
+
static struct leptris_document* xpath_context_document(
|
|
237
|
+
XPathContext* ctx) {
|
|
238
|
+
if (!ctx || !ctx->context_node) return ctx ? ctx->document : NULL;
|
|
239
|
+
LeptrisNode* cn = (LeptrisNode*)ctx->context_node;
|
|
240
|
+
/* Non-element contexts (pattern matching on text()/comment()/PI)
|
|
241
|
+
* walk any-kind parent links up to the nearest ELEMENT first -
|
|
242
|
+
* leptris_element_get_document would misread their layout. */
|
|
243
|
+
if (cn->type != LEPTRIS_NODE_TYPE_ELEMENT) {
|
|
244
|
+
LeptrisElement e = leptris_node_parent((LeptrisNodeRef)cn);
|
|
245
|
+
if (!e) return ctx->document;
|
|
246
|
+
cn = (LeptrisNode*)e;
|
|
247
|
+
}
|
|
248
|
+
struct leptris_document* nd =
|
|
249
|
+
leptris_element_get_document((LeptrisElement)cn);
|
|
250
|
+
return nd ? nd : ctx->document;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
static inline int vm_unprefixed_name_matches(XPathContext* ctx,
|
|
254
|
+
LeptrisElement e,
|
|
255
|
+
const char* name) {
|
|
256
|
+
/* Prefixed QNames (issue #564): resolve through the context's
|
|
257
|
+
* namespace bindings — the same semantics as the interpreter's
|
|
258
|
+
* matches_node_test. A bound prefix matches by namespace URI
|
|
259
|
+
* (any element prefix or the default ns); an unbound prefix
|
|
260
|
+
* falls back to the literal prefix comparison. */
|
|
261
|
+
const char* colon = name ? strchr(name, ':') : NULL;
|
|
262
|
+
if (colon) {
|
|
263
|
+
size_t plen = (size_t)(colon - name);
|
|
264
|
+
const char* local = colon + 1;
|
|
265
|
+
const char* en = leptris_element_get_name(e);
|
|
266
|
+
if (!en || strcmp(en, local) != 0) return 0;
|
|
267
|
+
const char* test_uri = ctx
|
|
268
|
+
? leptris_xpath_ns_lookup(
|
|
269
|
+
(const struct leptris_xpath_ns_map*)ctx->ns_set,
|
|
270
|
+
name, plen)
|
|
271
|
+
: NULL;
|
|
272
|
+
if (test_uri) {
|
|
273
|
+
const char* node_uri = leptris_element_get_namespace_uri(e);
|
|
274
|
+
return node_uri && strcmp(node_uri, test_uri) == 0;
|
|
275
|
+
}
|
|
276
|
+
const char* node_prefix = leptris_element_get_prefix(e);
|
|
277
|
+
return node_prefix &&
|
|
278
|
+
strlen(node_prefix) == plen &&
|
|
279
|
+
strncmp(node_prefix, name, plen) == 0;
|
|
280
|
+
}
|
|
281
|
+
const char* en = leptris_element_get_name(e);
|
|
282
|
+
if (!en || strcmp(en, name) != 0) return 0;
|
|
283
|
+
if (!ctx || !ctx->document || !ctx->document->has_namespaces) return 1;
|
|
284
|
+
const char* uri = leptris_element_get_namespace_uri(e);
|
|
285
|
+
return !uri || !uri[0];
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
static struct leptris_xpath_result* vm_apply_absolute_type(
|
|
289
|
+
XPathContext* ctx, const char* type_name, const char* pi_target) {
|
|
290
|
+
if (!ctx || !ctx->document) return NULL;
|
|
291
|
+
LeptrisElement root = (LeptrisElement)ctx->document->new_dom_root;
|
|
292
|
+
if (!root) return NULL;
|
|
293
|
+
|
|
294
|
+
int want = -1;
|
|
295
|
+
if (strcmp(type_name, "node") == 0) want = 0;
|
|
296
|
+
else if (strcmp(type_name, "text") == 0) want = 1;
|
|
297
|
+
else if (strcmp(type_name, "comment") == 0) want = 2;
|
|
298
|
+
else if (strcmp(type_name, "processing-instruction") == 0) want = 3;
|
|
299
|
+
if (want < 0) return NULL;
|
|
300
|
+
|
|
301
|
+
XPathNodeSet* out = xpath_nodeset_new();
|
|
302
|
+
if (!out) return NULL;
|
|
303
|
+
/* `//node()` per XPath 1.0 selects every node in the document
|
|
304
|
+
* except the document node itself — the root element included
|
|
305
|
+
* (it is a child of the document node). The walk covers the
|
|
306
|
+
* root's descendants, so node() needs the root itself added
|
|
307
|
+
* first. The other type tests never match an element, so the
|
|
308
|
+
* descendant walk already is their complete result.
|
|
309
|
+
* #580: document-level comments/PIs are descendants of the
|
|
310
|
+
* document too — the chain walks in document order (prolog
|
|
311
|
+
* nodes, root, subtree, epilog nodes). */
|
|
312
|
+
{
|
|
313
|
+
LeptrisNode* start = (LeptrisNode*)ctx->document->doc_children_head;
|
|
314
|
+
if (!start) start = (LeptrisNode*)root;
|
|
315
|
+
for (LeptrisNode* c = start; c;
|
|
316
|
+
c = leptris_node_get_next_sibling(c)) {
|
|
317
|
+
if (c->type == LEPTRIS_NODE_TYPE_ELEMENT) {
|
|
318
|
+
if (want == 0) xpath_nodeset_add_fast(out, root);
|
|
319
|
+
vm_absolute_type_walk(out, root, want, pi_target);
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
int match = (want == 0); /* node() matches all kinds */
|
|
323
|
+
if (want == 1) {
|
|
324
|
+
match = (c->type == LEPTRIS_NODE_TYPE_TEXT ||
|
|
325
|
+
c->type == LEPTRIS_NODE_TYPE_CDATA);
|
|
326
|
+
} else if (want == 2) {
|
|
327
|
+
match = (c->type == LEPTRIS_NODE_TYPE_COMMENT);
|
|
328
|
+
} else if (want == 3 && c->type == LEPTRIS_NODE_TYPE_PI) {
|
|
329
|
+
if (pi_target) {
|
|
330
|
+
LeptrisPINode* pi = (LeptrisPINode*)c;
|
|
331
|
+
match = pi->target && strcmp(pi->target, pi_target) == 0;
|
|
332
|
+
} else {
|
|
333
|
+
match = 1;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
if (match) xpath_nodeset_add_fast(out, c);
|
|
337
|
+
}
|
|
338
|
+
if (!ctx->document->doc_children_head) {
|
|
339
|
+
/* No chain (no doc-level nodes): plain subtree walk. */
|
|
340
|
+
if (want == 0) xpath_nodeset_add_fast(out, root);
|
|
341
|
+
vm_absolute_type_walk(out, root, want, pi_target);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_NODESET);
|
|
346
|
+
if (!r) { xpath_nodeset_free(out); return NULL; }
|
|
347
|
+
r->value.nodeset_value = out;
|
|
348
|
+
return r;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/* Prefixed-QName bucket path (issue #564): the index keys elements
|
|
352
|
+
* by LOCAL name, so a prefixed test resolves through the local
|
|
353
|
+
* bucket and verifies each (small) candidate with the ns-aware
|
|
354
|
+
* matcher — instead of walking the whole tree. */
|
|
355
|
+
static void vm_add_prefixed_bucket(XPathContext* ctx,
|
|
356
|
+
struct leptris_element_index* idx,
|
|
357
|
+
const char* qname,
|
|
358
|
+
XPathNodeSet* out) {
|
|
359
|
+
const char* colon = strchr(qname, ':');
|
|
360
|
+
if (!colon) return;
|
|
361
|
+
const LeptrisElementIndexBucket* bucket =
|
|
362
|
+
leptris_element_index_lookup(idx, colon + 1);
|
|
363
|
+
if (!bucket) return;
|
|
364
|
+
for (size_t i = 0; i < bucket->count; i++) {
|
|
365
|
+
LeptrisElement m = (LeptrisElement)bucket->matches[i];
|
|
366
|
+
if (vm_unprefixed_name_matches(ctx, m, qname))
|
|
367
|
+
xpath_nodeset_add_fast(out, m);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
static struct leptris_xpath_result* vm_apply_absolute(XPathContext* ctx,
|
|
372
|
+
const char* name,
|
|
373
|
+
int wild,
|
|
374
|
+
int mode) {
|
|
375
|
+
if (!ctx || !ctx->document) return NULL;
|
|
376
|
+
/* Absolute paths root at the CONTEXT NODE'S document (libxslt
|
|
377
|
+
* semantics): document() output and RTF fragments must not see
|
|
378
|
+
* the transform source tree. */
|
|
379
|
+
struct leptris_document* ctx_doc = xpath_context_document(ctx);
|
|
380
|
+
LeptrisElement root = (LeptrisElement)ctx_doc->new_dom_root;
|
|
381
|
+
if (!root) return NULL;
|
|
382
|
+
|
|
383
|
+
/* Mode 0 (root match only) — short-circuit, no descendant walk. */
|
|
384
|
+
if (mode == 0) {
|
|
385
|
+
XPathNodeSet* out = xpath_nodeset_new();
|
|
386
|
+
if (!out) return NULL;
|
|
387
|
+
if (wild) {
|
|
388
|
+
xpath_nodeset_add_fast(out, root);
|
|
389
|
+
} else {
|
|
390
|
+
if (vm_unprefixed_name_matches(ctx, root, name)) {
|
|
391
|
+
xpath_nodeset_add_fast(out, root);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_NODESET);
|
|
395
|
+
if (!r) { xpath_nodeset_free(out); return NULL; }
|
|
396
|
+
r->value.nodeset_value = out;
|
|
397
|
+
return r;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/* Mode 2 (whole tree incl. the root): use the element index with
|
|
401
|
+
* a memcpy fast path (TODO 137). Replaces the per-element
|
|
402
|
+
* fast_add loop with a single malloc+memcpy of the relevant
|
|
403
|
+
* index slice. ~10x faster for the loop portion of descendant::*.
|
|
404
|
+
* (Mode 1 — element-relative descendant, root excluded — was
|
|
405
|
+
* removed: every absolute descendant form takes mode 2 because
|
|
406
|
+
* its context is the document node.)
|
|
407
|
+
*
|
|
408
|
+
* Layout invariants:
|
|
409
|
+
* - all_elements[0] = root (preorder starts at root)
|
|
410
|
+
* - name_bucket.matches: all elements with that name in preorder
|
|
411
|
+
*/
|
|
412
|
+
struct leptris_element_index* idx = ctx_doc->element_index;
|
|
413
|
+
/* TODO 190: build on the SECOND axis query. The build costs
|
|
414
|
+
* two tree walks + per-name bucket allocations; a document
|
|
415
|
+
* that sees one query pays less walking directly. */
|
|
416
|
+
if (!idx && ++ctx_doc->axis_query_count >= 2) {
|
|
417
|
+
idx = leptris_element_index_build(ctx_doc);
|
|
418
|
+
ctx_doc->element_index = idx;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
XPathNodeSet* out = xpath_nodeset_new();
|
|
422
|
+
if (!out) return NULL;
|
|
423
|
+
|
|
424
|
+
if (idx) {
|
|
425
|
+
if (wild) {
|
|
426
|
+
/* Result = all_elements (the root included). */
|
|
427
|
+
void** src = (void**)idx->all_elements;
|
|
428
|
+
size_t n = idx->all_count;
|
|
429
|
+
if (n > 0) {
|
|
430
|
+
void** arr = (void**)malloc(n * sizeof(void*));
|
|
431
|
+
if (arr) {
|
|
432
|
+
memcpy(arr, src, n * sizeof(void*));
|
|
433
|
+
out->nodes = arr;
|
|
434
|
+
out->count = n;
|
|
435
|
+
out->capacity = n;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
} else if (strchr(name, ':')) {
|
|
439
|
+
/* Prefixed test: local-name bucket + ns verification. */
|
|
440
|
+
vm_add_prefixed_bucket(ctx, idx, name, out);
|
|
441
|
+
} else {
|
|
442
|
+
const LeptrisElementIndexBucket* bucket =
|
|
443
|
+
leptris_element_index_lookup(idx, name);
|
|
444
|
+
if (bucket) {
|
|
445
|
+
/* #525 gate: on namespace-bearing documents the
|
|
446
|
+
* bucket keys by LOCAL name — verify each entry
|
|
447
|
+
* (unprefixed tests match no-namespace elements
|
|
448
|
+
* only). The plain fast memcpy stays for
|
|
449
|
+
* namespace-free documents. */
|
|
450
|
+
if (ctx && ctx->document && ctx->document->has_namespaces) {
|
|
451
|
+
for (size_t i = 0; i < bucket->count; i++) {
|
|
452
|
+
LeptrisElement m = (LeptrisElement)bucket->matches[i];
|
|
453
|
+
if (vm_unprefixed_name_matches(ctx, m, name))
|
|
454
|
+
xpath_nodeset_add_fast(out, m);
|
|
455
|
+
}
|
|
456
|
+
struct leptris_xpath_result* rg =
|
|
457
|
+
xpath_result_new(XPATH_RESULT_NODESET);
|
|
458
|
+
if (!rg) { xpath_nodeset_free(out); return NULL; }
|
|
459
|
+
rg->value.nodeset_value = out;
|
|
460
|
+
return rg;
|
|
461
|
+
}
|
|
462
|
+
void** src = (void**)bucket->matches;
|
|
463
|
+
size_t n = bucket->count;
|
|
464
|
+
if (n > 0) {
|
|
465
|
+
/* Copy all matches (root included — document
|
|
466
|
+
* context). */
|
|
467
|
+
void** arr = (void**)malloc(n * sizeof(void*));
|
|
468
|
+
if (arr) {
|
|
469
|
+
memcpy(arr, src, n * sizeof(void*));
|
|
470
|
+
out->nodes = arr;
|
|
471
|
+
out->count = n;
|
|
472
|
+
out->capacity = n;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
} else {
|
|
478
|
+
/* Index build failed — fall back to walk. */
|
|
479
|
+
/* descendant-or-self::name matches the root only when the
|
|
480
|
+
* root's name matches (or it's a wildcard). The index path
|
|
481
|
+
* applies the same filter via the name bucket; this walk
|
|
482
|
+
* path ran only on index-build failure until TODO 190 made
|
|
483
|
+
* first queries walk directly — the unconditional root add
|
|
484
|
+
* was a latent off-by-one for named // queries (exposed by
|
|
485
|
+
* count(//book) returning root+books). */
|
|
486
|
+
if (wild || vm_unprefixed_name_matches(ctx, root, name)) {
|
|
487
|
+
xpath_nodeset_add_fast(out, root);
|
|
488
|
+
}
|
|
489
|
+
descendant_walk(ctx, out, root, name, wild, 0);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_NODESET);
|
|
493
|
+
if (!r) { xpath_nodeset_free(out); return NULL; }
|
|
494
|
+
r->value.nodeset_value = out;
|
|
495
|
+
return r;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
struct leptris_xpath_result* vm_apply_axis_child(XPathContext* ctx, XPathVM* vm,
|
|
499
|
+
const char* name, int wild) {
|
|
500
|
+
XPathNodeSet* input = vm_detach_input_nodeset(vm);
|
|
501
|
+
if (!input) return NULL;
|
|
502
|
+
|
|
503
|
+
XPathNodeSet* out = xpath_nodeset_new();
|
|
504
|
+
if (!out) { xpath_nodeset_free(input); return NULL; }
|
|
505
|
+
|
|
506
|
+
for (size_t i = 0; i < input->count; i++) {
|
|
507
|
+
LeptrisNode* nd = input->nodes[i];
|
|
508
|
+
/* Document node: child axis = the document child chain —
|
|
509
|
+
* prolog nodes, the root element, epilog nodes (#580). */
|
|
510
|
+
if (nd && nd->type == LEPTRIS_NODE_TYPE_DOCUMENT) {
|
|
511
|
+
struct leptris_document* d = ((LeptrisDocumentNode*)nd)->doc;
|
|
512
|
+
LeptrisNode* start = (LeptrisNode*)d->doc_children_head;
|
|
513
|
+
if (!start) {
|
|
514
|
+
start = (LeptrisNode*)d->new_dom_root;
|
|
515
|
+
if (!start) start = (LeptrisNode*)d->root;
|
|
516
|
+
}
|
|
517
|
+
for (LeptrisNode* c = start; c;
|
|
518
|
+
c = leptris_node_get_next_sibling(c)) {
|
|
519
|
+
if (wild ||
|
|
520
|
+
(c->type == LEPTRIS_NODE_TYPE_ELEMENT &&
|
|
521
|
+
vm_unprefixed_name_matches(ctx, (LeptrisElement)c,
|
|
522
|
+
name)))
|
|
523
|
+
xpath_nodeset_add_fast(out, c);
|
|
524
|
+
}
|
|
525
|
+
continue;
|
|
526
|
+
}
|
|
527
|
+
if (!node_is_element(nd)) continue;
|
|
528
|
+
LeptrisElement elem = (LeptrisElement)nd;
|
|
529
|
+
LeptrisElement child = leptris_element_get_first_child(elem);
|
|
530
|
+
while (child) {
|
|
531
|
+
if (wild) {
|
|
532
|
+
xpath_nodeset_add_fast(out, child);
|
|
533
|
+
} else {
|
|
534
|
+
if (vm_unprefixed_name_matches(ctx, child, name)) {
|
|
535
|
+
xpath_nodeset_add_fast(out, child);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
child = leptris_element_get_next_sibling(child);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
xpath_nodeset_free(input);
|
|
543
|
+
|
|
544
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_NODESET);
|
|
545
|
+
if (!r) { xpath_nodeset_free(out); return NULL; }
|
|
546
|
+
r->value.nodeset_value = out;
|
|
547
|
+
return r;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/* Fused child::NAME[k] (issue #645): the k-th child matching NAME
|
|
551
|
+
* of EACH input context node. A forward axis's step position is
|
|
552
|
+
* per-context by definition — count matching children and stop at
|
|
553
|
+
* k, no intermediate nodeset, no predicate frame. Document-node
|
|
554
|
+
* inputs walk the doc child chain like vm_apply_axis_child. */
|
|
555
|
+
static struct leptris_xpath_result* vm_apply_axis_child_name_pos(
|
|
556
|
+
XPathContext* ctx, XPathVM* vm, const char* name, uint16_t pos) {
|
|
557
|
+
XPathNodeSet* input = vm_detach_input_nodeset(vm);
|
|
558
|
+
if (!input) return NULL;
|
|
559
|
+
|
|
560
|
+
XPathNodeSet* out = xpath_nodeset_new();
|
|
561
|
+
if (!out) { xpath_nodeset_free(input); return NULL; }
|
|
562
|
+
|
|
563
|
+
for (size_t i = 0; i < input->count; i++) {
|
|
564
|
+
LeptrisNode* nd = input->nodes[i];
|
|
565
|
+
if (nd && nd->type == LEPTRIS_NODE_TYPE_DOCUMENT) {
|
|
566
|
+
struct leptris_document* d = ((LeptrisDocumentNode*)nd)->doc;
|
|
567
|
+
LeptrisNode* start = (LeptrisNode*)d->doc_children_head;
|
|
568
|
+
if (!start) {
|
|
569
|
+
start = (LeptrisNode*)d->new_dom_root;
|
|
570
|
+
if (!start) start = (LeptrisNode*)d->root;
|
|
571
|
+
}
|
|
572
|
+
unsigned count = 0;
|
|
573
|
+
for (LeptrisNode* c = start; c;
|
|
574
|
+
c = leptris_node_get_next_sibling(c)) {
|
|
575
|
+
if (c->type == LEPTRIS_NODE_TYPE_ELEMENT &&
|
|
576
|
+
vm_unprefixed_name_matches(ctx, (LeptrisElement)c,
|
|
577
|
+
name) &&
|
|
578
|
+
++count == pos) {
|
|
579
|
+
xpath_nodeset_add_fast(out, c);
|
|
580
|
+
break;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
continue;
|
|
584
|
+
}
|
|
585
|
+
if (!node_is_element(nd)) continue;
|
|
586
|
+
LeptrisElement elem = (LeptrisElement)nd;
|
|
587
|
+
LeptrisElement child = leptris_element_get_first_child(elem);
|
|
588
|
+
unsigned count = 0;
|
|
589
|
+
while (child) {
|
|
590
|
+
if (vm_unprefixed_name_matches(ctx, child, name) &&
|
|
591
|
+
++count == pos) {
|
|
592
|
+
xpath_nodeset_add_fast(out, child);
|
|
593
|
+
break;
|
|
594
|
+
}
|
|
595
|
+
child = leptris_element_get_next_sibling(child);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
xpath_nodeset_free(input);
|
|
600
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_NODESET);
|
|
601
|
+
if (!r) { xpath_nodeset_free(out); return NULL; }
|
|
602
|
+
r->value.nodeset_value = out;
|
|
603
|
+
return r;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
struct leptris_xpath_result* vm_apply_axis_attribute(XPathContext* ctx, XPathVM* vm,
|
|
607
|
+
const char* name, int wild) {
|
|
608
|
+
XPathNodeSet* input = vm_detach_input_nodeset(vm);
|
|
609
|
+
if (!input) return NULL;
|
|
610
|
+
|
|
611
|
+
XPathNodeSet* out = xpath_nodeset_new();
|
|
612
|
+
if (!out) { xpath_nodeset_free(input); return NULL; }
|
|
613
|
+
|
|
614
|
+
/* Attribute axis produces LeptrisAttributeNode* entries. The
|
|
615
|
+
* result must own them so they're freed when the result is. */
|
|
616
|
+
out->owns_attributes = 1;
|
|
617
|
+
|
|
618
|
+
/* A prefixed name test resolves through the binding set and
|
|
619
|
+
* matches (URI, local) — the attribute's own spelling may use a
|
|
620
|
+
* different prefix for the same namespace (libxslt bug-97). */
|
|
621
|
+
const char* tcolon = name ? strchr(name, ':') : NULL;
|
|
622
|
+
const char* test_uri = NULL;
|
|
623
|
+
if (tcolon && ctx->ns_set) {
|
|
624
|
+
test_uri = leptris_xpath_ns_lookup(
|
|
625
|
+
(const struct leptris_xpath_ns_map*)ctx->ns_set,
|
|
626
|
+
name, (size_t)(tcolon - name));
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
for (size_t i = 0; i < input->count; i++) {
|
|
630
|
+
if (!node_is_element(input->nodes[i])) continue;
|
|
631
|
+
LeptrisElement elem = (LeptrisElement)input->nodes[i];
|
|
632
|
+
struct leptris_attribute* attr = leptris_element_get_first_attribute(elem);
|
|
633
|
+
while (attr) {
|
|
634
|
+
LeptrisStringView nv = attr->name_view;
|
|
635
|
+
int matches = 0;
|
|
636
|
+
if (wild) {
|
|
637
|
+
matches = 1;
|
|
638
|
+
} else if (test_uri && nv.length > 0 && nv.data) {
|
|
639
|
+
const char* ac =
|
|
640
|
+
(const char*)memchr(nv.data, ':', nv.length);
|
|
641
|
+
const char* ans = leptris_attribute_namespace_uri(
|
|
642
|
+
(LeptrisAttribute)attr);
|
|
643
|
+
if (ac && ans) {
|
|
644
|
+
size_t ll = nv.length - (size_t)(ac - nv.data) - 1;
|
|
645
|
+
size_t tl = strlen(tcolon + 1);
|
|
646
|
+
matches =
|
|
647
|
+
ll == tl &&
|
|
648
|
+
memcmp(ac + 1, tcolon + 1, tl) == 0 &&
|
|
649
|
+
strcmp(ans, test_uri) == 0;
|
|
650
|
+
}
|
|
651
|
+
} else if (name && nv.length > 0 && nv.data) {
|
|
652
|
+
matches = (strlen(name) == nv.length &&
|
|
653
|
+
memcmp(name, nv.data, nv.length) == 0);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
if (matches) {
|
|
657
|
+
/* Allocate a LeptrisAttributeNode mirroring
|
|
658
|
+
* create_attribute_node in evaluator_axes.c. */
|
|
659
|
+
LeptrisAttributeNode* an = LEPTRIS_ALLOC(LeptrisAttributeNode);
|
|
660
|
+
if (!an) { attr = leptris_attr_next(attr); continue; }
|
|
661
|
+
an->node_type = LEPTRIS_NODE_ATTRIBUTE;
|
|
662
|
+
|
|
663
|
+
/* Copy name (single representation: from the view) */
|
|
664
|
+
if (nv.length > 0 && nv.data) {
|
|
665
|
+
an->name = (char*)malloc(nv.length + 1);
|
|
666
|
+
if (an->name) {
|
|
667
|
+
memcpy(an->name, nv.data, nv.length);
|
|
668
|
+
an->name[nv.length] = '\0';
|
|
669
|
+
}
|
|
670
|
+
} else {
|
|
671
|
+
an->name = NULL;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
/* Copy value (single representation: from the view).
|
|
675
|
+
* Entity-bearing views decode first — the axis must
|
|
676
|
+
* return the same string the accessor returns (the
|
|
677
|
+
* raw & bytes double-escaped downstream, bug-59). */
|
|
678
|
+
LeptrisStringView vv = leptris_attr_value_sv(attr);
|
|
679
|
+
if (attr_has_entities(attr) && vv.length > 0 && vv.data) {
|
|
680
|
+
LeptrisMemoryPool* pool =
|
|
681
|
+
leptris_element_get_pool(elem);
|
|
682
|
+
char* dec = pool
|
|
683
|
+
? leptris_decode_entities_view(&vv, pool)
|
|
684
|
+
: NULL;
|
|
685
|
+
if (dec) {
|
|
686
|
+
an->value = leptris_strdup(dec);
|
|
687
|
+
} else {
|
|
688
|
+
an->value = (char*)malloc(vv.length + 1);
|
|
689
|
+
if (an->value) {
|
|
690
|
+
memcpy(an->value, vv.data, vv.length);
|
|
691
|
+
an->value[vv.length] = '\0';
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
} else if (vv.length > 0 && vv.data) {
|
|
695
|
+
an->value = (char*)malloc(vv.length + 1);
|
|
696
|
+
if (an->value) {
|
|
697
|
+
memcpy(an->value, vv.data, vv.length);
|
|
698
|
+
an->value[vv.length] = '\0';
|
|
699
|
+
}
|
|
700
|
+
} else {
|
|
701
|
+
an->value = NULL;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
an->namespace_uri = NULL;
|
|
705
|
+
an->owner = elem;
|
|
706
|
+
|
|
707
|
+
xpath_nodeset_add_fast(out, an);
|
|
708
|
+
}
|
|
709
|
+
attr = leptris_attr_next(attr);
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
xpath_nodeset_free(input);
|
|
714
|
+
|
|
715
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_NODESET);
|
|
716
|
+
if (!r) { xpath_nodeset_free(out); return NULL; }
|
|
717
|
+
r->value.nodeset_value = out;
|
|
718
|
+
return r;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
struct leptris_xpath_result* vm_apply_axis_self(XPathContext* ctx, XPathVM* vm,
|
|
722
|
+
const char* name, int wild) {
|
|
723
|
+
(void)ctx;
|
|
724
|
+
XPathNodeSet* input = vm_detach_input_nodeset(vm);
|
|
725
|
+
if (!input) return NULL;
|
|
726
|
+
|
|
727
|
+
XPathNodeSet* out = xpath_nodeset_new();
|
|
728
|
+
if (!out) { xpath_nodeset_free(input); return NULL; }
|
|
729
|
+
|
|
730
|
+
for (size_t i = 0; i < input->count; i++) {
|
|
731
|
+
LeptrisNode* nd = input->nodes[i];
|
|
732
|
+
if (!node_is_element(nd)) {
|
|
733
|
+
/* self::node() (wild) passes ANY node through — text/
|
|
734
|
+
* comment/PI/attribute/namespace contexts (e.g. `.` in
|
|
735
|
+
* a for-each over namespace::*). Name tests never match
|
|
736
|
+
* non-elements. */
|
|
737
|
+
if (nd && wild) xpath_nodeset_add_fast(out, nd);
|
|
738
|
+
continue;
|
|
739
|
+
}
|
|
740
|
+
LeptrisElement elem = (LeptrisElement)nd;
|
|
741
|
+
if (wild) {
|
|
742
|
+
xpath_nodeset_add_fast(out, elem);
|
|
743
|
+
} else {
|
|
744
|
+
if (vm_unprefixed_name_matches(ctx, elem, name)) {
|
|
745
|
+
xpath_nodeset_add_fast(out, elem);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
xpath_nodeset_free(input);
|
|
751
|
+
|
|
752
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_NODESET);
|
|
753
|
+
if (!r) { xpath_nodeset_free(out); return NULL; }
|
|
754
|
+
r->value.nodeset_value = out;
|
|
755
|
+
return r;
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
struct leptris_xpath_result* vm_apply_axis_parent(XPathContext* ctx, XPathVM* vm,
|
|
759
|
+
const char* name, int wild) {
|
|
760
|
+
(void)ctx;
|
|
761
|
+
XPathNodeSet* input = vm_detach_input_nodeset(vm);
|
|
762
|
+
if (!input) return NULL;
|
|
763
|
+
|
|
764
|
+
XPathNodeSet* out = xpath_nodeset_new();
|
|
765
|
+
if (!out) { xpath_nodeset_free(input); return NULL; }
|
|
766
|
+
|
|
767
|
+
/* Parent axis can produce duplicates (multiple children → same
|
|
768
|
+
* parent). Inline a pointer-equality dedup. */
|
|
769
|
+
for (size_t i = 0; i < input->count; i++) {
|
|
770
|
+
LeptrisNode* in = input->nodes[i];
|
|
771
|
+
LeptrisElement parent;
|
|
772
|
+
if (in && in->type == LEPTRIS_NODE_NAMESPACE) {
|
|
773
|
+
/* Namespace nodes' parent is the OWNER element (63). */
|
|
774
|
+
parent = ((LeptrisNamespaceNode*)in)->owner;
|
|
775
|
+
} else if (node_is_element(in)) {
|
|
776
|
+
parent = leptris_element_get_parent((LeptrisElement)in);
|
|
777
|
+
} else {
|
|
778
|
+
/* Text/comment/PI contexts resolve through the
|
|
779
|
+
* any-kind parent (key use expressions, bug-133). */
|
|
780
|
+
parent = leptris_node_parent((LeptrisNodeRef)in);
|
|
781
|
+
}
|
|
782
|
+
if (!parent) continue;
|
|
783
|
+
|
|
784
|
+
if (!wild) {
|
|
785
|
+
if (!vm_unprefixed_name_matches(ctx, parent, name)) continue;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
/* Dedup */
|
|
789
|
+
int dup = 0;
|
|
790
|
+
for (size_t j = 0; j < out->count; j++) {
|
|
791
|
+
if (out->nodes[j] == parent) { dup = 1; break; }
|
|
792
|
+
}
|
|
793
|
+
if (!dup) xpath_nodeset_add_fast(out, parent);
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
xpath_nodeset_free(input);
|
|
797
|
+
|
|
798
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_NODESET);
|
|
799
|
+
if (!r) { xpath_nodeset_free(out); return NULL; }
|
|
800
|
+
r->value.nodeset_value = out;
|
|
801
|
+
return r;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
/* Recursive subtree walk for descendant / descendant-or-self.
|
|
805
|
+
* Appends matching elements to `out`. No dedup at this layer —
|
|
806
|
+
* the caller decides based on input size. */
|
|
807
|
+
/* Process a single element during a subtree walk: add to out if it
|
|
808
|
+
* matches the name filter. Inlined for tight loop performance. */
|
|
809
|
+
static inline void descendant_visit(XPathContext* ctx, XPathNodeSet* out,
|
|
810
|
+
LeptrisElement elem,
|
|
811
|
+
const char* name, int wild) {
|
|
812
|
+
if (wild) {
|
|
813
|
+
xpath_nodeset_add_fast(out, elem);
|
|
814
|
+
} else if (vm_unprefixed_name_matches(ctx, elem, name)) {
|
|
815
|
+
xpath_nodeset_add_fast(out, elem);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
/* Iterative pre-order subtree walk (TODO 131). Replaces the previous
|
|
820
|
+
* recursive version which paid function-call overhead per element.
|
|
821
|
+
*
|
|
822
|
+
* The walk uses the tree's own parent / first_child / next_sibling
|
|
823
|
+
* links to track position — no explicit stack needed. For an N-element
|
|
824
|
+
* subtree, total work is O(N) with constant per-element overhead.
|
|
825
|
+
*
|
|
826
|
+
* `name` / `wild` filter which elements get added to `out`.
|
|
827
|
+
* `include_self`: if 1, visit `elem` itself before descending; if 0,
|
|
828
|
+
* skip `elem` (it's been handled by the caller, e.g., vm_apply_absolute
|
|
829
|
+
* adds root separately for descendant-or-self). */
|
|
830
|
+
static void descendant_walk(XPathContext* ctx, XPathNodeSet* out, LeptrisElement elem,
|
|
831
|
+
const char* name, int wild, int include_self) {
|
|
832
|
+
if (!elem) return;
|
|
833
|
+
|
|
834
|
+
/* Pre-grow the output nodeset to skip the inline→heap transition
|
|
835
|
+
* that would otherwise trigger on the 17th add. For typical
|
|
836
|
+
* medium docs (~50 elements) this avoids 1-2 grow operations. */
|
|
837
|
+
if (out->capacity < 32) {
|
|
838
|
+
void** new_nodes = (void**)malloc(32 * sizeof(void*));
|
|
839
|
+
if (new_nodes) {
|
|
840
|
+
if (out->count > 0) {
|
|
841
|
+
memcpy(new_nodes, out->nodes, out->count * sizeof(void*));
|
|
842
|
+
}
|
|
843
|
+
/* Inline storage is part of the struct; nothing to free. */
|
|
844
|
+
out->nodes = new_nodes;
|
|
845
|
+
out->capacity = 32;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
if (include_self) {
|
|
850
|
+
descendant_visit(ctx, out, elem, name, wild);
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
LeptrisElement cur = leptris_element_get_first_child(elem);
|
|
854
|
+
while (cur) {
|
|
855
|
+
descendant_visit(ctx, out, cur, name, wild);
|
|
856
|
+
|
|
857
|
+
LeptrisElement next = leptris_element_get_first_child(cur);
|
|
858
|
+
if (next) {
|
|
859
|
+
cur = next;
|
|
860
|
+
continue;
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
/* No child — walk up via parent links until we find a sibling
|
|
864
|
+
* or reach `elem` (the subtree root). */
|
|
865
|
+
while (cur && cur != elem) {
|
|
866
|
+
LeptrisElement sib = leptris_element_get_next_sibling(cur);
|
|
867
|
+
if (sib) {
|
|
868
|
+
cur = sib;
|
|
869
|
+
break;
|
|
870
|
+
}
|
|
871
|
+
cur = leptris_element_get_parent(cur);
|
|
872
|
+
}
|
|
873
|
+
if (cur == elem) break; /* exhausted subtree */
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
/* Pre-order all-nodes walk: n itself, then (for elements) each
|
|
878
|
+
* subtree. Matches descendant_walk's recursion risk profile. */
|
|
879
|
+
static void all_nodes_preorder(XPathNodeSet* out, LeptrisNode* n) {
|
|
880
|
+
xpath_nodeset_add_fast(out, n);
|
|
881
|
+
if (n->type == LEPTRIS_NODE_TYPE_ELEMENT) {
|
|
882
|
+
for (LeptrisNode* c = leptris_elem_first_child((LeptrisElement)n); c;
|
|
883
|
+
c = leptris_node_get_next_sibling(c))
|
|
884
|
+
all_nodes_preorder(out, c);
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
struct leptris_xpath_result* vm_apply_axis_descendant(XPathContext* ctx, XPathVM* vm,
|
|
889
|
+
const char* name, int wild,
|
|
890
|
+
int include_self) {
|
|
891
|
+
XPathNodeSet* input = vm_detach_input_nodeset(vm);
|
|
892
|
+
if (!input) return NULL;
|
|
893
|
+
|
|
894
|
+
/* The element index keys buckets on LOCAL names; a prefixed test
|
|
895
|
+
* (issue #630: .//ns:x from element context) resolves the local
|
|
896
|
+
* bucket and filters each match namespace-aware — the raw
|
|
897
|
+
* qualified lookup missed every bucket and returned empty. */
|
|
898
|
+
const char* name_colon = (!wild && name) ? strchr(name, ':') : NULL;
|
|
899
|
+
const char* bucket_key = name_colon ? name_colon + 1 : name;
|
|
900
|
+
|
|
901
|
+
XPathNodeSet* out = xpath_nodeset_new();
|
|
902
|
+
if (!out) { xpath_nodeset_free(input); return NULL; }
|
|
903
|
+
|
|
904
|
+
/* Fast path: single-element input that IS the document root.
|
|
905
|
+
* Use the element index (TODO 132) for O(K) lookup. */
|
|
906
|
+
LeptrisElement doc_root = (ctx && ctx->document)
|
|
907
|
+
? (LeptrisElement)ctx->document->new_dom_root : NULL;
|
|
908
|
+
|
|
909
|
+
if (input->count == 1 && doc_root &&
|
|
910
|
+
input->nodes[0] == doc_root && node_is_element(input->nodes[0])) {
|
|
911
|
+
struct leptris_element_index* idx = ctx->document->element_index;
|
|
912
|
+
/* TODO 190: build on the SECOND axis query. The build costs
|
|
913
|
+
* two tree walks + per-name bucket allocations; a document
|
|
914
|
+
* that sees one query pays less walking directly. */
|
|
915
|
+
if (!idx && ++ctx->document->axis_query_count >= 2) {
|
|
916
|
+
idx = leptris_element_index_build(ctx->document);
|
|
917
|
+
ctx->document->element_index = idx;
|
|
918
|
+
}
|
|
919
|
+
if (idx) {
|
|
920
|
+
/* Memcpy fast path (TODO 137). Single malloc + memcpy
|
|
921
|
+
* instead of per-element add. Root at all_elements[0]. */
|
|
922
|
+
if (wild) {
|
|
923
|
+
if (include_self) {
|
|
924
|
+
/* root + all descendants = all_elements */
|
|
925
|
+
if (idx->all_count > 0) {
|
|
926
|
+
void** arr = (void**)malloc(idx->all_count * sizeof(void*));
|
|
927
|
+
if (arr) {
|
|
928
|
+
memcpy(arr, idx->all_elements, idx->all_count * sizeof(void*));
|
|
929
|
+
out->nodes = arr;
|
|
930
|
+
out->count = idx->all_count;
|
|
931
|
+
out->capacity = idx->all_count;
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
} else {
|
|
935
|
+
/* all descendants except root = all_elements[1..] */
|
|
936
|
+
if (idx->all_count > 1) {
|
|
937
|
+
size_t n = idx->all_count - 1;
|
|
938
|
+
void** arr = (void**)malloc(n * sizeof(void*));
|
|
939
|
+
if (arr) {
|
|
940
|
+
memcpy(arr, idx->all_elements + 1, n * sizeof(void*));
|
|
941
|
+
out->nodes = arr;
|
|
942
|
+
out->count = n;
|
|
943
|
+
out->capacity = n;
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
} else {
|
|
948
|
+
const LeptrisElementIndexBucket* bucket =
|
|
949
|
+
leptris_element_index_lookup(idx, bucket_key);
|
|
950
|
+
if (name_colon) {
|
|
951
|
+
/* Prefixed test: filter the local bucket's matches
|
|
952
|
+
* namespace-aware (issue #630). */
|
|
953
|
+
if (bucket) {
|
|
954
|
+
for (size_t i = 0; i < bucket->count; i++) {
|
|
955
|
+
LeptrisElement m = bucket->matches[i];
|
|
956
|
+
if (!include_self && m == doc_root) continue;
|
|
957
|
+
if (vm_unprefixed_name_matches(ctx, m, name))
|
|
958
|
+
xpath_nodeset_add_fast(out, m);
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
} else if (bucket) {
|
|
962
|
+
if (include_self) {
|
|
963
|
+
/* all matches including root */
|
|
964
|
+
if (bucket->count > 0) {
|
|
965
|
+
void** arr = (void**)malloc(bucket->count * sizeof(void*));
|
|
966
|
+
if (arr) {
|
|
967
|
+
memcpy(arr, bucket->matches, bucket->count * sizeof(void*));
|
|
968
|
+
out->nodes = arr;
|
|
969
|
+
out->count = bucket->count;
|
|
970
|
+
out->capacity = bucket->count;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
} else {
|
|
974
|
+
/* matches except root */
|
|
975
|
+
size_t skip = (size_t)-1;
|
|
976
|
+
for (size_t i = 0; i < bucket->count; i++) {
|
|
977
|
+
if (bucket->matches[i] == doc_root) { skip = i; break; }
|
|
978
|
+
}
|
|
979
|
+
if (skip == (size_t)-1) {
|
|
980
|
+
if (bucket->count > 0) {
|
|
981
|
+
void** arr = (void**)malloc(bucket->count * sizeof(void*));
|
|
982
|
+
if (arr) {
|
|
983
|
+
memcpy(arr, bucket->matches, bucket->count * sizeof(void*));
|
|
984
|
+
out->nodes = arr;
|
|
985
|
+
out->count = bucket->count;
|
|
986
|
+
out->capacity = bucket->count;
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
} else if (bucket->count > 1) {
|
|
990
|
+
size_t n = bucket->count - 1;
|
|
991
|
+
void** arr = (void**)malloc(n * sizeof(void*));
|
|
992
|
+
if (arr) {
|
|
993
|
+
size_t k = 0;
|
|
994
|
+
for (size_t i = 0; i < skip; i++) arr[k++] = bucket->matches[i];
|
|
995
|
+
for (size_t i = skip + 1; i < bucket->count; i++) arr[k++] = bucket->matches[i];
|
|
996
|
+
out->nodes = arr;
|
|
997
|
+
out->count = n;
|
|
998
|
+
out->capacity = n;
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
if (out->count > 0 || !include_self) {
|
|
1006
|
+
xpath_nodeset_free(input);
|
|
1007
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_NODESET);
|
|
1008
|
+
if (!r) { xpath_nodeset_free(out); return NULL; }
|
|
1009
|
+
r->value.nodeset_value = out;
|
|
1010
|
+
return r;
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
/* Index build failed — fall through to walk. */
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
/* TODO 192: subtree-interval index for non-root contexts — the
|
|
1017
|
+
* fast path above handled the doc-root input; this one serves
|
|
1018
|
+
* .//name and chained a//b steps from any context set. Intervals
|
|
1019
|
+
* are preorder ranges; name-bucket matches store their preorder
|
|
1020
|
+
* positions, so each context costs a binary search plus its own
|
|
1021
|
+
* hits instead of a subtree walk. */
|
|
1022
|
+
if (!wild && ctx && ctx->document && input->count > 0) {
|
|
1023
|
+
struct leptris_element_index* idx = ctx->document->element_index;
|
|
1024
|
+
if (!idx && ++ctx->document->axis_query_count >= 2) {
|
|
1025
|
+
idx = leptris_element_index_build(ctx->document);
|
|
1026
|
+
ctx->document->element_index = idx;
|
|
1027
|
+
}
|
|
1028
|
+
if (idx && idx->subtree_end) {
|
|
1029
|
+
const LeptrisElementIndexBucket* bucket =
|
|
1030
|
+
leptris_element_index_lookup(idx, bucket_key);
|
|
1031
|
+
/* No bucket / empty bucket: the name does not occur in
|
|
1032
|
+
* this document, so every subtree yields empty — but a
|
|
1033
|
+
* partially-built index without positions must fall back. */
|
|
1034
|
+
if (!bucket || (bucket->count > 0 && bucket->match_positions)) {
|
|
1035
|
+
size_t n_ctx = 0;
|
|
1036
|
+
for (size_t i = 0; i < input->count; i++) {
|
|
1037
|
+
if (node_is_element(input->nodes[i])) n_ctx++;
|
|
1038
|
+
}
|
|
1039
|
+
if (n_ctx > 0) {
|
|
1040
|
+
size_t* los = (size_t*)malloc(n_ctx * sizeof(size_t));
|
|
1041
|
+
size_t* his = (size_t*)malloc(n_ctx * sizeof(size_t));
|
|
1042
|
+
int all_found = (los && his);
|
|
1043
|
+
size_t k = 0;
|
|
1044
|
+
for (size_t i = 0; all_found && i < input->count; i++) {
|
|
1045
|
+
if (!node_is_element(input->nodes[i])) continue;
|
|
1046
|
+
all_found = leptris_element_index_subtree_interval(
|
|
1047
|
+
idx, (LeptrisElement)input->nodes[i],
|
|
1048
|
+
&los[k], &his[k]);
|
|
1049
|
+
if (all_found) k++;
|
|
1050
|
+
}
|
|
1051
|
+
if (all_found) {
|
|
1052
|
+
/* Sort intervals by start; subtrees are either
|
|
1053
|
+
* disjoint or nested, so skipping any interval
|
|
1054
|
+
* contained in a previous one removes all overlap
|
|
1055
|
+
* — no dedup pass needed and output stays in
|
|
1056
|
+
* document order (bucket positions ascend). */
|
|
1057
|
+
for (size_t a = 1; a < k; a++) {
|
|
1058
|
+
size_t l = los[a], h = his[a], b = a;
|
|
1059
|
+
while (b > 0 && los[b - 1] > l) {
|
|
1060
|
+
los[b] = los[b - 1];
|
|
1061
|
+
his[b] = his[b - 1];
|
|
1062
|
+
b--;
|
|
1063
|
+
}
|
|
1064
|
+
los[b] = l;
|
|
1065
|
+
his[b] = h;
|
|
1066
|
+
}
|
|
1067
|
+
size_t prev_hi = 0;
|
|
1068
|
+
int have_prev = 0;
|
|
1069
|
+
for (size_t a = 0; a < k; a++) {
|
|
1070
|
+
if (have_prev && los[a] <= prev_hi) continue;
|
|
1071
|
+
if (bucket && bucket->count > 0) {
|
|
1072
|
+
size_t lo2 = los[a], hi2 = his[a];
|
|
1073
|
+
size_t l = 0, r = bucket->count;
|
|
1074
|
+
while (l < r) {
|
|
1075
|
+
size_t mid = l + (r - l) / 2;
|
|
1076
|
+
if (bucket->match_positions[mid] < lo2) {
|
|
1077
|
+
l = mid + 1;
|
|
1078
|
+
} else {
|
|
1079
|
+
r = mid;
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
for (size_t j = l;
|
|
1083
|
+
j < bucket->count &&
|
|
1084
|
+
bucket->match_positions[j] <= hi2;
|
|
1085
|
+
j++) {
|
|
1086
|
+
if (!include_self &&
|
|
1087
|
+
bucket->match_positions[j] == lo2) {
|
|
1088
|
+
continue;
|
|
1089
|
+
}
|
|
1090
|
+
if (name_colon &&
|
|
1091
|
+
!vm_unprefixed_name_matches(
|
|
1092
|
+
ctx,
|
|
1093
|
+
(LeptrisElement)bucket->matches[j],
|
|
1094
|
+
name)) {
|
|
1095
|
+
continue;
|
|
1096
|
+
}
|
|
1097
|
+
xpath_nodeset_add_fast(
|
|
1098
|
+
out, bucket->matches[j]);
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
prev_hi = his[a];
|
|
1102
|
+
have_prev = 1;
|
|
1103
|
+
}
|
|
1104
|
+
free(los);
|
|
1105
|
+
free(his);
|
|
1106
|
+
xpath_nodeset_free(input);
|
|
1107
|
+
struct leptris_xpath_result* r =
|
|
1108
|
+
xpath_result_new(XPATH_RESULT_NODESET);
|
|
1109
|
+
if (!r) {
|
|
1110
|
+
xpath_nodeset_free(out);
|
|
1111
|
+
return NULL;
|
|
1112
|
+
}
|
|
1113
|
+
r->value.nodeset_value = out;
|
|
1114
|
+
return r;
|
|
1115
|
+
}
|
|
1116
|
+
free(los);
|
|
1117
|
+
free(his);
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
/* General path: walk subtrees from each input element. */
|
|
1124
|
+
int need_dedup = (input->count > 1);
|
|
1125
|
+
|
|
1126
|
+
for (size_t i = 0; i < input->count; i++) {
|
|
1127
|
+
if (!node_is_element(input->nodes[i])) continue;
|
|
1128
|
+
LeptrisElement elem = (LeptrisElement)input->nodes[i];
|
|
1129
|
+
|
|
1130
|
+
size_t mark = out->count;
|
|
1131
|
+
descendant_walk(ctx, out, elem, name, wild, include_self);
|
|
1132
|
+
|
|
1133
|
+
if (need_dedup) {
|
|
1134
|
+
for (size_t k = mark; k < out->count; k++) {
|
|
1135
|
+
int dup = 0;
|
|
1136
|
+
for (size_t j = 0; j < mark; j++) {
|
|
1137
|
+
if (out->nodes[j] == out->nodes[k]) {
|
|
1138
|
+
dup = 1;
|
|
1139
|
+
break;
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
if (dup) {
|
|
1143
|
+
out->nodes[k] = out->nodes[out->count - 1];
|
|
1144
|
+
out->count--;
|
|
1145
|
+
k--;
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
xpath_nodeset_free(input);
|
|
1152
|
+
|
|
1153
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_NODESET);
|
|
1154
|
+
if (!r) { xpath_nodeset_free(out); return NULL; }
|
|
1155
|
+
r->value.nodeset_value = out;
|
|
1156
|
+
return r;
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
/* Fused axis+predicate handler (TODO 134). Walks descendant::* and
|
|
1160
|
+
* filters by attribute in a single pass — no intermediate nodeset.
|
|
1161
|
+
* When input is the document root, uses the attribute index for
|
|
1162
|
+
* O(K) lookup where K = match count.
|
|
1163
|
+
*
|
|
1164
|
+
* `value_match`: if 0, presence check (attr exists). If 1, equality
|
|
1165
|
+
* check (attr value == attr_value). */
|
|
1166
|
+
|
|
1167
|
+
/* Attribute-predicate matcher — pulled out of the previous macro so
|
|
1168
|
+
* the file compiles under MSVC (which rejects GCC statement-expression
|
|
1169
|
+
* extension `({ ... })`). Walks the element's attribute list once. */
|
|
1170
|
+
static int attr_pred_match(LeptrisElement e,
|
|
1171
|
+
const char* attr_name, size_t attr_name_len,
|
|
1172
|
+
int value_match,
|
|
1173
|
+
const char* attr_value, size_t value_len) {
|
|
1174
|
+
struct leptris_attribute* a = leptris_element_get_first_attribute(e);
|
|
1175
|
+
while (a) {
|
|
1176
|
+
LeptrisStringView nv = a->name_view;
|
|
1177
|
+
if (attr_name && nv.length == attr_name_len && nv.length > 0 && nv.data &&
|
|
1178
|
+
memcmp(attr_name, nv.data, nv.length) == 0) {
|
|
1179
|
+
if (!value_match) return 1;
|
|
1180
|
+
LeptrisStringView vv = leptris_attr_value_sv(a);
|
|
1181
|
+
if (vv.length == value_len && vv.length > 0 && vv.data &&
|
|
1182
|
+
memcmp(attr_value, vv.data, vv.length) == 0) {
|
|
1183
|
+
return 1;
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
a = leptris_attr_next(a);
|
|
1187
|
+
}
|
|
1188
|
+
return 0;
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
static struct leptris_xpath_result* vm_apply_axis_descendant_pred_attr(
|
|
1192
|
+
XPathContext* ctx, XPathVM* vm,
|
|
1193
|
+
const char* attr_name, const char* attr_value,
|
|
1194
|
+
int value_match, int include_self) {
|
|
1195
|
+
|
|
1196
|
+
XPathNodeSet* input = vm_detach_input_nodeset(vm);
|
|
1197
|
+
if (!input) return NULL;
|
|
1198
|
+
|
|
1199
|
+
XPathNodeSet* out = xpath_nodeset_new();
|
|
1200
|
+
if (!out) { xpath_nodeset_free(input); return NULL; }
|
|
1201
|
+
|
|
1202
|
+
LeptrisElement doc_root = (ctx && ctx->document)
|
|
1203
|
+
? (LeptrisElement)ctx->document->new_dom_root : NULL;
|
|
1204
|
+
|
|
1205
|
+
/* Index fast path: single-element input that IS the document root.
|
|
1206
|
+
* Look up attr_bucket directly. */
|
|
1207
|
+
if (input->count == 1 && doc_root &&
|
|
1208
|
+
input->nodes[0] == doc_root && node_is_element(input->nodes[0])) {
|
|
1209
|
+
|
|
1210
|
+
struct leptris_element_index* idx = ctx->document->element_index;
|
|
1211
|
+
/* TODO 190: build on the SECOND axis query. The build costs
|
|
1212
|
+
* two tree walks + per-name bucket allocations; a document
|
|
1213
|
+
* that sees one query pays less walking directly. */
|
|
1214
|
+
if (!idx && ++ctx->document->axis_query_count >= 2) {
|
|
1215
|
+
idx = leptris_element_index_build(ctx->document);
|
|
1216
|
+
ctx->document->element_index = idx;
|
|
1217
|
+
}
|
|
1218
|
+
if (idx) {
|
|
1219
|
+
const LeptrisElementIndexAttrBucket* abucket =
|
|
1220
|
+
leptris_element_index_lookup_attr(idx, attr_name);
|
|
1221
|
+
if (abucket) {
|
|
1222
|
+
if (!value_match) {
|
|
1223
|
+
/* [@attr] — return all matches (root is in the
|
|
1224
|
+
* bucket iff it has the attr; same for both
|
|
1225
|
+
* descendant and descendant-or-self). */
|
|
1226
|
+
for (size_t i = 0; i < abucket->count; i++) {
|
|
1227
|
+
if (!include_self && abucket->matches[i] == doc_root) continue;
|
|
1228
|
+
xpath_nodeset_add_fast(out, abucket->matches[i]);
|
|
1229
|
+
}
|
|
1230
|
+
} else {
|
|
1231
|
+
const LeptrisElementIndexAttrValue* vbucket =
|
|
1232
|
+
leptris_element_index_attr_lookup_value(abucket, attr_value);
|
|
1233
|
+
if (vbucket) {
|
|
1234
|
+
for (size_t i = 0; i < vbucket->count; i++) {
|
|
1235
|
+
if (!include_self && vbucket->matches[i] == doc_root) continue;
|
|
1236
|
+
xpath_nodeset_add_fast(out, vbucket->matches[i]);
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
xpath_nodeset_free(input);
|
|
1242
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_NODESET);
|
|
1243
|
+
if (!r) { xpath_nodeset_free(out); return NULL; }
|
|
1244
|
+
r->value.nodeset_value = out;
|
|
1245
|
+
return r;
|
|
1246
|
+
}
|
|
1247
|
+
/* Index build failed — fall through to walk+filter. */
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
/* Walk+filter fallback. Single pass: visit each descendant and
|
|
1251
|
+
* check the attribute inline. Avoids the intermediate nodeset
|
|
1252
|
+
* that the two-opcode form would allocate. */
|
|
1253
|
+
size_t attr_name_len = attr_name ? strlen(attr_name) : 0;
|
|
1254
|
+
size_t value_len = attr_value ? strlen(attr_value) : 0;
|
|
1255
|
+
|
|
1256
|
+
/* Helper: check if `e` has the matching attr. */
|
|
1257
|
+
#define ATTR_MATCHES(e) \
|
|
1258
|
+
attr_pred_match((e), attr_name, attr_name_len, \
|
|
1259
|
+
value_match, attr_value, value_len)
|
|
1260
|
+
|
|
1261
|
+
for (size_t i = 0; i < input->count; i++) {
|
|
1262
|
+
if (!node_is_element(input->nodes[i])) continue;
|
|
1263
|
+
LeptrisElement elem = (LeptrisElement)input->nodes[i];
|
|
1264
|
+
|
|
1265
|
+
/* include_self: check the input element itself. */
|
|
1266
|
+
if (include_self && ATTR_MATCHES(elem)) {
|
|
1267
|
+
xpath_nodeset_add_fast(out, elem);
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
/* Inline subtree walk + attr filter. */
|
|
1271
|
+
LeptrisElement cur = leptris_element_get_first_child(elem);
|
|
1272
|
+
while (cur) {
|
|
1273
|
+
if (ATTR_MATCHES(cur)) xpath_nodeset_add_fast(out, cur);
|
|
1274
|
+
|
|
1275
|
+
/* Descend or backtrack. */
|
|
1276
|
+
LeptrisElement next = leptris_element_get_first_child(cur);
|
|
1277
|
+
if (next) {
|
|
1278
|
+
cur = next;
|
|
1279
|
+
continue;
|
|
1280
|
+
}
|
|
1281
|
+
while (cur && cur != elem) {
|
|
1282
|
+
LeptrisElement sib = leptris_element_get_next_sibling(cur);
|
|
1283
|
+
if (sib) { cur = sib; break; }
|
|
1284
|
+
cur = leptris_element_get_parent(cur);
|
|
1285
|
+
}
|
|
1286
|
+
if (cur == elem) break;
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
#undef ATTR_MATCHES
|
|
1290
|
+
|
|
1291
|
+
xpath_nodeset_free(input);
|
|
1292
|
+
|
|
1293
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_NODESET);
|
|
1294
|
+
if (!r) { xpath_nodeset_free(out); return NULL; }
|
|
1295
|
+
r->value.nodeset_value = out;
|
|
1296
|
+
return r;
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
/* Numeric relational comparison for the any-pair loops below. */
|
|
1300
|
+
static int vm_relational_cmp(XPathOperatorType op, double a, double b) {
|
|
1301
|
+
switch (op) {
|
|
1302
|
+
case XPATH_OP_LESS: return a < b;
|
|
1303
|
+
case XPATH_OP_LESS_EQUAL: return a <= b;
|
|
1304
|
+
case XPATH_OP_GREATER: return a > b;
|
|
1305
|
+
case XPATH_OP_GREATER_EQUAL: return a >= b;
|
|
1306
|
+
default: return 0;
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
/* Inline binary-operator dispatch. Pops right then left, computes,
|
|
1311
|
+
* pushes the result. Returns 0 on success, -1 on error.
|
|
1312
|
+
*
|
|
1313
|
+
* Short-circuit semantics for AND/OR: this implementation evaluates
|
|
1314
|
+
* both operands eagerly. XPath has no side effects, so the only
|
|
1315
|
+
* cost is the redundant work, which is rare in real expressions. */
|
|
1316
|
+
static int vm_apply_binary_op(XPathVM* vm, XPathContext* ctx,
|
|
1317
|
+
XPathOperatorType op) {
|
|
1318
|
+
struct leptris_xpath_result* right = vm_pop(vm);
|
|
1319
|
+
struct leptris_xpath_result* left = vm_pop(vm);
|
|
1320
|
+
if (!left || !right) {
|
|
1321
|
+
if (left) xpath_result_free(left);
|
|
1322
|
+
if (right) xpath_result_free(right);
|
|
1323
|
+
return -1;
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
struct leptris_xpath_result* result = NULL;
|
|
1327
|
+
|
|
1328
|
+
/* Boolean operators. */
|
|
1329
|
+
if (op == XPATH_OP_AND) {
|
|
1330
|
+
result = xpath_result_new(XPATH_RESULT_BOOLEAN);
|
|
1331
|
+
if (result) result->value.boolean_value =
|
|
1332
|
+
xpath_to_boolean(left) && xpath_to_boolean(right);
|
|
1333
|
+
} else if (op == XPATH_OP_OR) {
|
|
1334
|
+
result = xpath_result_new(XPATH_RESULT_BOOLEAN);
|
|
1335
|
+
if (result) result->value.boolean_value =
|
|
1336
|
+
xpath_to_boolean(left) || xpath_to_boolean(right);
|
|
1337
|
+
}
|
|
1338
|
+
/* Arithmetic. */
|
|
1339
|
+
else if (op == XPATH_OP_PLUS || op == XPATH_OP_MINUS ||
|
|
1340
|
+
op == XPATH_OP_MULTIPLY || op == XPATH_OP_DIV ||
|
|
1341
|
+
op == XPATH_OP_MOD) {
|
|
1342
|
+
double lval = xpath_to_number(left);
|
|
1343
|
+
double rval = xpath_to_number(right);
|
|
1344
|
+
result = xpath_result_new(XPATH_RESULT_NUMBER);
|
|
1345
|
+
if (result) {
|
|
1346
|
+
switch (op) {
|
|
1347
|
+
case XPATH_OP_PLUS: result->value.number_value = lval + rval; break;
|
|
1348
|
+
case XPATH_OP_MINUS: result->value.number_value = lval - rval; break;
|
|
1349
|
+
case XPATH_OP_MULTIPLY: result->value.number_value = lval * rval; break;
|
|
1350
|
+
case XPATH_OP_DIV: result->value.number_value = lval / rval; break;
|
|
1351
|
+
case XPATH_OP_MOD: result->value.number_value = fmod(lval, rval); break;
|
|
1352
|
+
default: break;
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
/* Unary negation — right is unused (compiler emits only one operand). */
|
|
1357
|
+
else if (op == XPATH_OP_NEGATION) {
|
|
1358
|
+
double lval = xpath_to_number(left);
|
|
1359
|
+
result = xpath_result_new(XPATH_RESULT_NUMBER);
|
|
1360
|
+
if (result) result->value.number_value = -lval;
|
|
1361
|
+
}
|
|
1362
|
+
/* Union — both must be nodesets; concatenate with dedup.
|
|
1363
|
+
* XPath requires no duplicates and document order; we dedup but
|
|
1364
|
+
* don't enforce document order (the existing evaluator doesn't
|
|
1365
|
+
* either — see compare_document_order note in evaluator_operators.c). */
|
|
1366
|
+
else if (op == XPATH_OP_UNION) {
|
|
1367
|
+
result = xpath_result_new(XPATH_RESULT_NODESET);
|
|
1368
|
+
if (result) {
|
|
1369
|
+
result->value.nodeset_value = xpath_nodeset_new();
|
|
1370
|
+
if (result->value.nodeset_value) {
|
|
1371
|
+
XPathNodeSet* ln = left->type == XPATH_RESULT_NODESET
|
|
1372
|
+
? left->value.nodeset_value : NULL;
|
|
1373
|
+
XPathNodeSet* rn = right->type == XPATH_RESULT_NODESET
|
|
1374
|
+
? right->value.nodeset_value : NULL;
|
|
1375
|
+
/* Concatenate both sides; the sort dedups adjacent
|
|
1376
|
+
* duplicates. The old per-candidate linear duplicate
|
|
1377
|
+
* scan was O(n^2) — 99% of //name | //item time on
|
|
1378
|
+
* 20k-element documents. */
|
|
1379
|
+
if (ln) for (size_t i = 0; i < ln->count; i++)
|
|
1380
|
+
xpath_nodeset_add(result->value.nodeset_value, ln->nodes[i]);
|
|
1381
|
+
if (rn) for (size_t i = 0; i < rn->count; i++)
|
|
1382
|
+
xpath_nodeset_add_fast(result->value.nodeset_value, rn->nodes[i]);
|
|
1383
|
+
/* Document order per XPath 1.0 — the merged order is
|
|
1384
|
+
* left-then-right append, not document order (issue
|
|
1385
|
+
* #485). */
|
|
1386
|
+
xpath_nodeset_sort_doc_order(
|
|
1387
|
+
ctx, result->value.nodeset_value, 0);
|
|
1388
|
+
|
|
1389
|
+
/* Issue #514: transfer synthetic-node ownership from
|
|
1390
|
+
* the operands — see the twin fix in
|
|
1391
|
+
* evaluator_operators.c. */
|
|
1392
|
+
if (ln && rn) {
|
|
1393
|
+
result->value.nodeset_value->owns_attributes =
|
|
1394
|
+
ln->owns_attributes || rn->owns_attributes;
|
|
1395
|
+
result->value.nodeset_value->owns_namespaces =
|
|
1396
|
+
ln->owns_namespaces || rn->owns_namespaces;
|
|
1397
|
+
result->value.nodeset_value->owns_synthetic_text =
|
|
1398
|
+
ln->owns_synthetic_text ||
|
|
1399
|
+
rn->owns_synthetic_text;
|
|
1400
|
+
ln->owns_attributes = 0;
|
|
1401
|
+
ln->owns_namespaces = 0;
|
|
1402
|
+
ln->owns_synthetic_text = 0;
|
|
1403
|
+
rn->owns_attributes = 0;
|
|
1404
|
+
rn->owns_namespaces = 0;
|
|
1405
|
+
rn->owns_synthetic_text = 0;
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
/* Comparisons. */
|
|
1411
|
+
else if (op == XPATH_OP_EQUAL || op == XPATH_OP_NOT_EQUAL ||
|
|
1412
|
+
op == XPATH_OP_LESS || op == XPATH_OP_LESS_EQUAL ||
|
|
1413
|
+
op == XPATH_OP_GREATER || op == XPATH_OP_GREATER_EQUAL) {
|
|
1414
|
+
/* XPath comparison semantics depend on operand types:
|
|
1415
|
+
* - nodeset vs nodeset: any-pair match
|
|
1416
|
+
* - nodeset vs number/string/boolean: any-node match
|
|
1417
|
+
* - otherwise: convert both to number and compare
|
|
1418
|
+
* A nodeset operand needs the §3.4 any-node loop — the old
|
|
1419
|
+
* first-node shortcut silently broke variable nodesets on
|
|
1420
|
+
* the VM path (libxslt bug-76: union of $var nodesets). */
|
|
1421
|
+
int matches = 0;
|
|
1422
|
+
int l_is_ns = (left->type == XPATH_RESULT_NODESET);
|
|
1423
|
+
int r_is_ns = (right->type == XPATH_RESULT_NODESET);
|
|
1424
|
+
if (l_is_ns || r_is_ns) {
|
|
1425
|
+
int relational = (op != XPATH_OP_EQUAL && op != XPATH_OP_NOT_EQUAL);
|
|
1426
|
+
int negate = (op == XPATH_OP_NOT_EQUAL);
|
|
1427
|
+
int boolean_side = (l_is_ns ? right->type : left->type)
|
|
1428
|
+
== XPATH_RESULT_BOOLEAN;
|
|
1429
|
+
XPathNodeSet* ns = l_is_ns ? left->value.nodeset_value
|
|
1430
|
+
: right->value.nodeset_value;
|
|
1431
|
+
if (boolean_side && !relational) {
|
|
1432
|
+
/* boolean vs nodeset: boolean(nodeset) OP boolean. */
|
|
1433
|
+
int lb = xpath_to_boolean(left);
|
|
1434
|
+
int rb = xpath_to_boolean(right);
|
|
1435
|
+
matches = negate ? (lb != rb) : (lb == rb);
|
|
1436
|
+
} else if (l_is_ns && r_is_ns) {
|
|
1437
|
+
XPathNodeSet* other = right->value.nodeset_value;
|
|
1438
|
+
for (size_t i = 0; !matches && ns && i < ns->count; i++) {
|
|
1439
|
+
char* a = get_node_text(ns->nodes[i]);
|
|
1440
|
+
if (!a) continue;
|
|
1441
|
+
for (size_t j = 0; !matches && other && j < other->count; j++) {
|
|
1442
|
+
char* b = get_node_text(other->nodes[j]);
|
|
1443
|
+
if (!b) continue;
|
|
1444
|
+
if (relational) {
|
|
1445
|
+
double av = atof(a);
|
|
1446
|
+
double bv = atof(b);
|
|
1447
|
+
matches = vm_relational_cmp(op, av, bv);
|
|
1448
|
+
} else {
|
|
1449
|
+
matches = negate ? (strcmp(a, b) != 0)
|
|
1450
|
+
: (strcmp(a, b) == 0);
|
|
1451
|
+
}
|
|
1452
|
+
free(b);
|
|
1453
|
+
}
|
|
1454
|
+
free(a);
|
|
1455
|
+
}
|
|
1456
|
+
} else {
|
|
1457
|
+
/* nodeset vs scalar: per-node string (equality) or
|
|
1458
|
+
* number (relational) compare against the scalar. */
|
|
1459
|
+
if (relational) {
|
|
1460
|
+
/* Operand order is part of the semantics (#965):
|
|
1461
|
+
* nodeset on the RIGHT compares scalar op node. */
|
|
1462
|
+
double scalar = xpath_to_number(
|
|
1463
|
+
l_is_ns ? right : left);
|
|
1464
|
+
for (size_t i = 0; !matches && ns && i < ns->count; i++) {
|
|
1465
|
+
char* a = get_node_text(ns->nodes[i]);
|
|
1466
|
+
if (!a) continue;
|
|
1467
|
+
matches = l_is_ns
|
|
1468
|
+
? vm_relational_cmp(op, atof(a), scalar)
|
|
1469
|
+
: vm_relational_cmp(op, scalar, atof(a));
|
|
1470
|
+
free(a);
|
|
1471
|
+
}
|
|
1472
|
+
} else {
|
|
1473
|
+
char* scalar = xpath_to_string(l_is_ns ? right : left);
|
|
1474
|
+
for (size_t i = 0; !matches && ns && scalar &&
|
|
1475
|
+
i < ns->count; i++) {
|
|
1476
|
+
char* a = get_node_text(ns->nodes[i]);
|
|
1477
|
+
if (!a) continue;
|
|
1478
|
+
matches = negate ? (strcmp(a, scalar) != 0)
|
|
1479
|
+
: (strcmp(a, scalar) == 0);
|
|
1480
|
+
free(a);
|
|
1481
|
+
}
|
|
1482
|
+
if (scalar) free(scalar);
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
} else {
|
|
1486
|
+
double lnum = xpath_to_number(left);
|
|
1487
|
+
double rnum = xpath_to_number(right);
|
|
1488
|
+
char* lstr_owned = xpath_to_string(left);
|
|
1489
|
+
char* rstr_owned = xpath_to_string(right);
|
|
1490
|
+
int eq_str = (lstr_owned && rstr_owned &&
|
|
1491
|
+
strcmp(lstr_owned, rstr_owned) == 0);
|
|
1492
|
+
int eq_num = (lnum == rnum);
|
|
1493
|
+
int eq = eq_str || eq_num;
|
|
1494
|
+
if (lstr_owned) free(lstr_owned);
|
|
1495
|
+
if (rstr_owned) free(rstr_owned);
|
|
1496
|
+
|
|
1497
|
+
switch (op) {
|
|
1498
|
+
case XPATH_OP_EQUAL: matches = eq; break;
|
|
1499
|
+
case XPATH_OP_NOT_EQUAL: matches = !eq; break;
|
|
1500
|
+
case XPATH_OP_LESS: matches = (lnum < rnum); break;
|
|
1501
|
+
case XPATH_OP_LESS_EQUAL: matches = (lnum <= rnum); break;
|
|
1502
|
+
case XPATH_OP_GREATER: matches = (lnum > rnum); break;
|
|
1503
|
+
case XPATH_OP_GREATER_EQUAL: matches = (lnum >= rnum); break;
|
|
1504
|
+
default: break;
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
result = xpath_result_new(XPATH_RESULT_BOOLEAN);
|
|
1508
|
+
if (result) result->value.boolean_value = matches;
|
|
1509
|
+
(void)ctx;
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
xpath_result_free(left);
|
|
1513
|
+
xpath_result_free(right);
|
|
1514
|
+
|
|
1515
|
+
if (!result) { vm->error = 1; return -1; }
|
|
1516
|
+
vm_push(vm, result);
|
|
1517
|
+
return 0;
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
|
|
1521
|
+
|
|
1522
|
+
static struct leptris_xpath_result* vm_run(LeptrisXPathBytecode* bc,
|
|
1523
|
+
XPathContext* ctx) {
|
|
1524
|
+
XPathVM vm = {0};
|
|
1525
|
+
const unsigned char* pc = bc->code;
|
|
1526
|
+
const unsigned char* end = bc->code + bc->code_len;
|
|
1527
|
+
|
|
1528
|
+
while (pc < end && !vm.error) {
|
|
1529
|
+
XPathOpcode op = (XPathOpcode)*pc++;
|
|
1530
|
+
switch (op) {
|
|
1531
|
+
case XPATH_BC_NOP:
|
|
1532
|
+
break;
|
|
1533
|
+
|
|
1534
|
+
case XPATH_BC_LITERAL_NUMBER: {
|
|
1535
|
+
uint16_t idx = read_u16(&pc);
|
|
1536
|
+
if (idx >= bc->const_count) { vm.error = 1; break; }
|
|
1537
|
+
struct leptris_xpath_result* r =
|
|
1538
|
+
xpath_result_new(XPATH_RESULT_NUMBER);
|
|
1539
|
+
if (!r) { vm.error = 1; break; }
|
|
1540
|
+
r->value.number_value = bc->constants[idx].v.number;
|
|
1541
|
+
vm_push(&vm, r);
|
|
1542
|
+
break;
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
case XPATH_BC_LITERAL_STRING: {
|
|
1546
|
+
uint16_t idx = read_u16(&pc);
|
|
1547
|
+
if (idx >= bc->const_count) { vm.error = 1; break; }
|
|
1548
|
+
struct leptris_xpath_result* r =
|
|
1549
|
+
xpath_result_new(XPATH_RESULT_STRING);
|
|
1550
|
+
if (!r) { vm.error = 1; break; }
|
|
1551
|
+
r->value.string_value =
|
|
1552
|
+
leptris_strdup(bc->constants[idx].v.string);
|
|
1553
|
+
if (!r->value.string_value) {
|
|
1554
|
+
xpath_result_free(r);
|
|
1555
|
+
vm.error = 1;
|
|
1556
|
+
break;
|
|
1557
|
+
}
|
|
1558
|
+
vm_push(&vm, r);
|
|
1559
|
+
break;
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
case XPATH_BC_LITERAL_BOOL: {
|
|
1563
|
+
uint8_t b = read_u8(&pc);
|
|
1564
|
+
struct leptris_xpath_result* r =
|
|
1565
|
+
xpath_result_new(XPATH_RESULT_BOOLEAN);
|
|
1566
|
+
if (!r) { vm.error = 1; break; }
|
|
1567
|
+
r->value.boolean_value = b ? 1 : 0;
|
|
1568
|
+
vm_push(&vm, r);
|
|
1569
|
+
break;
|
|
1570
|
+
}
|
|
1571
|
+
|
|
1572
|
+
case XPATH_BC_PATH_ABSOLUTE: {
|
|
1573
|
+
LeptrisElement root =
|
|
1574
|
+
(LeptrisElement)ctx->document->new_dom_root;
|
|
1575
|
+
struct leptris_xpath_result* r = make_singleton_nodeset(root);
|
|
1576
|
+
if (!r) { vm.error = 1; break; }
|
|
1577
|
+
vm_push(&vm, r);
|
|
1578
|
+
break;
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1581
|
+
case XPATH_BC_PATH_RELATIVE: {
|
|
1582
|
+
struct leptris_xpath_result* r =
|
|
1583
|
+
make_singleton_nodeset(ctx->context_node);
|
|
1584
|
+
if (!r) { vm.error = 1; break; }
|
|
1585
|
+
vm_push(&vm, r);
|
|
1586
|
+
break;
|
|
1587
|
+
}
|
|
1588
|
+
|
|
1589
|
+
case XPATH_BC_AXIS_STEP: {
|
|
1590
|
+
uint16_t idx = read_u16(&pc);
|
|
1591
|
+
if (idx >= bc->const_count ||
|
|
1592
|
+
bc->constants[idx].type != XPATH_CONST_AST_NODE) {
|
|
1593
|
+
vm.error = 1;
|
|
1594
|
+
break;
|
|
1595
|
+
}
|
|
1596
|
+
XPathASTNode* step_ast = bc->constants[idx].v.ast;
|
|
1597
|
+
|
|
1598
|
+
struct leptris_xpath_result* input = vm_pop(&vm);
|
|
1599
|
+
if (!input || input->type != XPATH_RESULT_NODESET) {
|
|
1600
|
+
if (input) xpath_result_free(input);
|
|
1601
|
+
vm.error = 1;
|
|
1602
|
+
break;
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
XPathNodeSet* input_ns = input->value.nodeset_value;
|
|
1606
|
+
input->value.nodeset_value = NULL;
|
|
1607
|
+
xpath_result_free(input);
|
|
1608
|
+
|
|
1609
|
+
struct leptris_xpath_result* step_result =
|
|
1610
|
+
evaluate_step(ctx, step_ast, input_ns);
|
|
1611
|
+
xpath_nodeset_free(input_ns);
|
|
1612
|
+
if (!step_result) { vm.error = 1; break; }
|
|
1613
|
+
vm_push(&vm, step_result);
|
|
1614
|
+
break;
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
/* Specialized axis handlers (TODO 126). Each is a tight
|
|
1618
|
+
* loop over the input nodeset that bypasses the
|
|
1619
|
+
* evaluate_step scaffolding. The handlers cover the
|
|
1620
|
+
* common shapes: single name test or wildcard, no
|
|
1621
|
+
* namespace prefix, no predicates. Anything else
|
|
1622
|
+
* stays on BC_AXIS_STEP. */
|
|
1623
|
+
|
|
1624
|
+
case XPATH_BC_AXIS_CHILD_NAME: {
|
|
1625
|
+
uint16_t idx = read_u16(&pc);
|
|
1626
|
+
const char* name = (idx < bc->const_count &&
|
|
1627
|
+
bc->constants[idx].type == XPATH_CONST_STRING)
|
|
1628
|
+
? bc->constants[idx].v.string : NULL;
|
|
1629
|
+
struct leptris_xpath_result* r =
|
|
1630
|
+
vm_apply_axis_child(ctx, &vm, name, 0);
|
|
1631
|
+
if (!r) { vm.error = 1; break; }
|
|
1632
|
+
vm_push(&vm, r);
|
|
1633
|
+
break;
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1636
|
+
case XPATH_BC_AXIS_CHILD_WILD: {
|
|
1637
|
+
struct leptris_xpath_result* r =
|
|
1638
|
+
vm_apply_axis_child(ctx, &vm, NULL, 1);
|
|
1639
|
+
if (!r) { vm.error = 1; break; }
|
|
1640
|
+
vm_push(&vm, r);
|
|
1641
|
+
break;
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1644
|
+
case XPATH_BC_AXIS_CHILD_NAME_POS: {
|
|
1645
|
+
uint16_t name_idx = read_u16(&pc);
|
|
1646
|
+
uint16_t pos = read_u16(&pc);
|
|
1647
|
+
const char* name =
|
|
1648
|
+
(name_idx < bc->const_count &&
|
|
1649
|
+
bc->constants[name_idx].type == XPATH_CONST_STRING)
|
|
1650
|
+
? bc->constants[name_idx].v.string : NULL;
|
|
1651
|
+
struct leptris_xpath_result* r =
|
|
1652
|
+
vm_apply_axis_child_name_pos(ctx, &vm, name, pos);
|
|
1653
|
+
if (!r) { vm.error = 1; break; }
|
|
1654
|
+
vm_push(&vm, r);
|
|
1655
|
+
break;
|
|
1656
|
+
}
|
|
1657
|
+
|
|
1658
|
+
case XPATH_BC_AXIS_ATTRIBUTE_NAME: {
|
|
1659
|
+
uint16_t idx = read_u16(&pc);
|
|
1660
|
+
const char* name = (idx < bc->const_count &&
|
|
1661
|
+
bc->constants[idx].type == XPATH_CONST_STRING)
|
|
1662
|
+
? bc->constants[idx].v.string : NULL;
|
|
1663
|
+
struct leptris_xpath_result* r =
|
|
1664
|
+
vm_apply_axis_attribute(ctx, &vm, name, 0);
|
|
1665
|
+
if (!r) { vm.error = 1; break; }
|
|
1666
|
+
vm_push(&vm, r);
|
|
1667
|
+
break;
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1670
|
+
case XPATH_BC_AXIS_ATTRIBUTE_WILD: {
|
|
1671
|
+
struct leptris_xpath_result* r =
|
|
1672
|
+
vm_apply_axis_attribute(ctx, &vm, NULL, 1);
|
|
1673
|
+
if (!r) { vm.error = 1; break; }
|
|
1674
|
+
vm_push(&vm, r);
|
|
1675
|
+
break;
|
|
1676
|
+
}
|
|
1677
|
+
|
|
1678
|
+
case XPATH_BC_AXIS_SELF_NAME: {
|
|
1679
|
+
uint16_t idx = read_u16(&pc);
|
|
1680
|
+
const char* name = (idx < bc->const_count &&
|
|
1681
|
+
bc->constants[idx].type == XPATH_CONST_STRING)
|
|
1682
|
+
? bc->constants[idx].v.string : NULL;
|
|
1683
|
+
struct leptris_xpath_result* r =
|
|
1684
|
+
vm_apply_axis_self(ctx, &vm, name, 0);
|
|
1685
|
+
if (!r) { vm.error = 1; break; }
|
|
1686
|
+
vm_push(&vm, r);
|
|
1687
|
+
break;
|
|
1688
|
+
}
|
|
1689
|
+
|
|
1690
|
+
case XPATH_BC_AXIS_SELF_WILD: {
|
|
1691
|
+
struct leptris_xpath_result* r =
|
|
1692
|
+
vm_apply_axis_self(ctx, &vm, NULL, 1);
|
|
1693
|
+
if (!r) { vm.error = 1; break; }
|
|
1694
|
+
vm_push(&vm, r);
|
|
1695
|
+
break;
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
case XPATH_BC_AXIS_PARENT_NAME: {
|
|
1699
|
+
uint16_t idx = read_u16(&pc);
|
|
1700
|
+
const char* name = (idx < bc->const_count &&
|
|
1701
|
+
bc->constants[idx].type == XPATH_CONST_STRING)
|
|
1702
|
+
? bc->constants[idx].v.string : NULL;
|
|
1703
|
+
struct leptris_xpath_result* r =
|
|
1704
|
+
vm_apply_axis_parent(ctx, &vm, name, 0);
|
|
1705
|
+
if (!r) { vm.error = 1; break; }
|
|
1706
|
+
vm_push(&vm, r);
|
|
1707
|
+
break;
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1710
|
+
case XPATH_BC_AXIS_PARENT_WILD: {
|
|
1711
|
+
struct leptris_xpath_result* r =
|
|
1712
|
+
vm_apply_axis_parent(ctx, &vm, NULL, 1);
|
|
1713
|
+
if (!r) { vm.error = 1; break; }
|
|
1714
|
+
vm_push(&vm, r);
|
|
1715
|
+
break;
|
|
1716
|
+
}
|
|
1717
|
+
|
|
1718
|
+
case XPATH_BC_AXIS_DESCENDANT_NAME: {
|
|
1719
|
+
uint16_t idx = read_u16(&pc);
|
|
1720
|
+
const char* name = (idx < bc->const_count &&
|
|
1721
|
+
bc->constants[idx].type == XPATH_CONST_STRING)
|
|
1722
|
+
? bc->constants[idx].v.string : NULL;
|
|
1723
|
+
struct leptris_xpath_result* r =
|
|
1724
|
+
vm_apply_axis_descendant(ctx, &vm, name, 0, 0);
|
|
1725
|
+
if (!r) { vm.error = 1; break; }
|
|
1726
|
+
vm_push(&vm, r);
|
|
1727
|
+
break;
|
|
1728
|
+
}
|
|
1729
|
+
|
|
1730
|
+
case XPATH_BC_AXIS_DESCENDANT_WILD: {
|
|
1731
|
+
struct leptris_xpath_result* r =
|
|
1732
|
+
vm_apply_axis_descendant(ctx, &vm, NULL, 1, 0);
|
|
1733
|
+
if (!r) { vm.error = 1; break; }
|
|
1734
|
+
vm_push(&vm, r);
|
|
1735
|
+
break;
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1738
|
+
case XPATH_BC_AXIS_DESCENDANT_NAME_ATTREQ: {
|
|
1739
|
+
/* TODO 192c: relative descendant::name[@attr='value']
|
|
1740
|
+
* served from the index — each context element's
|
|
1741
|
+
* subtree interval windows the attr-VALUE bucket's
|
|
1742
|
+
* preorder positions. O(log B + hits) per context. */
|
|
1743
|
+
uint16_t name_idx = read_u16(&pc);
|
|
1744
|
+
uint16_t attr_idx = read_u16(&pc);
|
|
1745
|
+
uint16_t value_idx = read_u16(&pc);
|
|
1746
|
+
const char* name = (name_idx < bc->const_count &&
|
|
1747
|
+
bc->constants[name_idx].type == XPATH_CONST_STRING)
|
|
1748
|
+
? bc->constants[name_idx].v.string : NULL;
|
|
1749
|
+
const char* attr_name = (attr_idx < bc->const_count &&
|
|
1750
|
+
bc->constants[attr_idx].type == XPATH_CONST_STRING)
|
|
1751
|
+
? bc->constants[attr_idx].v.string : NULL;
|
|
1752
|
+
/* 0xFFFF = no value operand: attr-EXISTS predicate. */
|
|
1753
|
+
const char* value = (value_idx != 0xFFFF &&
|
|
1754
|
+
value_idx < bc->const_count &&
|
|
1755
|
+
bc->constants[value_idx].type == XPATH_CONST_STRING)
|
|
1756
|
+
? bc->constants[value_idx].v.string : NULL;
|
|
1757
|
+
if (!name || !attr_name || (value_idx != 0xFFFF && !value)) {
|
|
1758
|
+
vm.error = 1;
|
|
1759
|
+
break;
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
XPathNodeSet* input = vm_detach_input_nodeset(&vm);
|
|
1763
|
+
if (!input) { vm.error = 1; break; }
|
|
1764
|
+
XPathNodeSet* out = xpath_nodeset_new();
|
|
1765
|
+
if (!out) { xpath_nodeset_free(input); vm.error = 1; break; }
|
|
1766
|
+
|
|
1767
|
+
struct leptris_element_index* index =
|
|
1768
|
+
(ctx && ctx->document) ? ctx->document->element_index : NULL;
|
|
1769
|
+
if (!index && ctx && ctx->document &&
|
|
1770
|
+
++ctx->document->axis_query_count >= 2) {
|
|
1771
|
+
index = leptris_element_index_build(ctx->document);
|
|
1772
|
+
ctx->document->element_index = index;
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
int served = 0;
|
|
1776
|
+
if (index && index->subtree_end) {
|
|
1777
|
+
const LeptrisElementIndexAttrBucket* abucket =
|
|
1778
|
+
leptris_element_index_lookup_attr(index, attr_name);
|
|
1779
|
+
/* Equality reads the value bucket; existence reads
|
|
1780
|
+
* the any-value bucket (TODO 192e). No bucket for
|
|
1781
|
+
* this attribute anywhere: empty answer. A bucket
|
|
1782
|
+
* without positions must fall back. */
|
|
1783
|
+
const LeptrisElement* bucket_matches = NULL;
|
|
1784
|
+
const size_t* bucket_positions = NULL;
|
|
1785
|
+
size_t bucket_count = 0;
|
|
1786
|
+
int bucket_valid = 0;
|
|
1787
|
+
if (value) {
|
|
1788
|
+
const LeptrisElementIndexAttrValue* vbucket =
|
|
1789
|
+
abucket ? leptris_element_index_attr_lookup_value(abucket, value)
|
|
1790
|
+
: NULL;
|
|
1791
|
+
if (!vbucket ||
|
|
1792
|
+
(vbucket->count > 0 && vbucket->match_positions)) {
|
|
1793
|
+
bucket_valid = 1;
|
|
1794
|
+
if (vbucket) {
|
|
1795
|
+
bucket_matches = vbucket->matches;
|
|
1796
|
+
bucket_positions = vbucket->match_positions;
|
|
1797
|
+
bucket_count = vbucket->count;
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1800
|
+
} else if (!abucket ||
|
|
1801
|
+
(abucket->count > 0 && abucket->match_positions)) {
|
|
1802
|
+
bucket_valid = 1;
|
|
1803
|
+
if (abucket) {
|
|
1804
|
+
bucket_matches = abucket->matches;
|
|
1805
|
+
bucket_positions = abucket->match_positions;
|
|
1806
|
+
bucket_count = abucket->count;
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
if (bucket_valid) {
|
|
1810
|
+
size_t n_ctx = 0;
|
|
1811
|
+
for (size_t i = 0; i < input->count; i++) {
|
|
1812
|
+
if (node_is_element(input->nodes[i])) n_ctx++;
|
|
1813
|
+
}
|
|
1814
|
+
size_t* los = (n_ctx > 0)
|
|
1815
|
+
? (size_t*)malloc(n_ctx * sizeof(size_t)) : NULL;
|
|
1816
|
+
size_t* his = (n_ctx > 0)
|
|
1817
|
+
? (size_t*)malloc(n_ctx * sizeof(size_t)) : NULL;
|
|
1818
|
+
int all_found = (n_ctx == 0) || (los && his);
|
|
1819
|
+
size_t k = 0;
|
|
1820
|
+
for (size_t i = 0; all_found && i < input->count; i++) {
|
|
1821
|
+
if (!node_is_element(input->nodes[i])) continue;
|
|
1822
|
+
all_found = leptris_element_index_subtree_interval(
|
|
1823
|
+
index, (LeptrisElement)input->nodes[i],
|
|
1824
|
+
&los[k], &his[k]);
|
|
1825
|
+
if (all_found) k++;
|
|
1826
|
+
}
|
|
1827
|
+
if (all_found) {
|
|
1828
|
+
/* Same ordering argument as the name path:
|
|
1829
|
+
* bucket positions ascend, subtrees are
|
|
1830
|
+
* disjoint-or-nested, skip contained ones. */
|
|
1831
|
+
for (size_t a = 1; a < k; a++) {
|
|
1832
|
+
size_t l = los[a], h = his[a], b = a;
|
|
1833
|
+
while (b > 0 && los[b - 1] > l) {
|
|
1834
|
+
los[b] = los[b - 1];
|
|
1835
|
+
his[b] = his[b - 1];
|
|
1836
|
+
b--;
|
|
1837
|
+
}
|
|
1838
|
+
los[b] = l;
|
|
1839
|
+
his[b] = h;
|
|
1840
|
+
}
|
|
1841
|
+
size_t prev_hi = 0;
|
|
1842
|
+
int have_prev = 0;
|
|
1843
|
+
for (size_t a = 0; a < k; a++) {
|
|
1844
|
+
if (have_prev && los[a] <= prev_hi) continue;
|
|
1845
|
+
if (bucket_count > 0) {
|
|
1846
|
+
size_t lo2 = los[a], hi2 = his[a];
|
|
1847
|
+
size_t l = 0, r = bucket_count;
|
|
1848
|
+
while (l < r) {
|
|
1849
|
+
size_t mid = l + (r - l) / 2;
|
|
1850
|
+
if (bucket_positions[mid] < lo2) {
|
|
1851
|
+
l = mid + 1;
|
|
1852
|
+
} else {
|
|
1853
|
+
r = mid;
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1856
|
+
for (size_t j = l;
|
|
1857
|
+
j < bucket_count &&
|
|
1858
|
+
bucket_positions[j] <= hi2;
|
|
1859
|
+
j++) {
|
|
1860
|
+
if (vm_unprefixed_name_matches(
|
|
1861
|
+
ctx, bucket_matches[j], name)) {
|
|
1862
|
+
xpath_nodeset_add_fast(
|
|
1863
|
+
out, bucket_matches[j]);
|
|
1864
|
+
}
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
prev_hi = his[a];
|
|
1868
|
+
have_prev = 1;
|
|
1869
|
+
}
|
|
1870
|
+
served = 1;
|
|
1871
|
+
}
|
|
1872
|
+
free(los);
|
|
1873
|
+
free(his);
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
|
|
1877
|
+
if (!served) {
|
|
1878
|
+
/* Fallback: subtree walk + inline attr filter
|
|
1879
|
+
* (hash-prefiltered walk, the PRED_ATTR_EXISTS
|
|
1880
|
+
* handler's pattern). */
|
|
1881
|
+
uint16_t attr_hash =
|
|
1882
|
+
attr_hash15(attr_name, strlen(attr_name));
|
|
1883
|
+
for (size_t i = 0; i < input->count; i++) {
|
|
1884
|
+
if (!node_is_element(input->nodes[i])) continue;
|
|
1885
|
+
LeptrisElement elem = (LeptrisElement)input->nodes[i];
|
|
1886
|
+
size_t mark = out->count;
|
|
1887
|
+
descendant_walk(ctx, out, elem, name, 0, 0);
|
|
1888
|
+
for (size_t w = mark; w < out->count;) {
|
|
1889
|
+
LeptrisElement e2 = (LeptrisElement)out->nodes[w];
|
|
1890
|
+
const char* v = NULL;
|
|
1891
|
+
for (struct leptris_attribute* a =
|
|
1892
|
+
leptris_element_get_first_attribute(e2);
|
|
1893
|
+
a; a = leptris_attr_next(a)) {
|
|
1894
|
+
if (attr_name_hash(a) == attr_hash &&
|
|
1895
|
+
attr_cname(a) &&
|
|
1896
|
+
strcmp(attr_cname(a), attr_name) == 0) {
|
|
1897
|
+
v = attr_cvalue(a);
|
|
1898
|
+
break;
|
|
1899
|
+
}
|
|
1900
|
+
}
|
|
1901
|
+
if (value ? (v && strcmp(v, value) == 0)
|
|
1902
|
+
: (v != NULL)) {
|
|
1903
|
+
w++;
|
|
1904
|
+
} else {
|
|
1905
|
+
out->nodes[w] = out->nodes[out->count - 1];
|
|
1906
|
+
out->count--;
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
|
|
1912
|
+
xpath_nodeset_free(input);
|
|
1913
|
+
struct leptris_xpath_result* r =
|
|
1914
|
+
xpath_result_new(XPATH_RESULT_NODESET);
|
|
1915
|
+
if (!r) { xpath_nodeset_free(out); vm.error = 1; break; }
|
|
1916
|
+
r->value.nodeset_value = out;
|
|
1917
|
+
vm_push(&vm, r);
|
|
1918
|
+
break;
|
|
1919
|
+
}
|
|
1920
|
+
|
|
1921
|
+
/* Fused axis+predicate (TODO 134). */
|
|
1922
|
+
case XPATH_BC_AXIS_DESCENDANT_WILD_PRED_ATTR_EXISTS: {
|
|
1923
|
+
uint16_t idx = read_u16(&pc);
|
|
1924
|
+
const char* attr_name = (idx < bc->const_count &&
|
|
1925
|
+
bc->constants[idx].type == XPATH_CONST_STRING)
|
|
1926
|
+
? bc->constants[idx].v.string : NULL;
|
|
1927
|
+
struct leptris_xpath_result* r =
|
|
1928
|
+
vm_apply_axis_descendant_pred_attr(ctx, &vm, attr_name, NULL, 0, 0);
|
|
1929
|
+
if (!r) { vm.error = 1; break; }
|
|
1930
|
+
vm_push(&vm, r);
|
|
1931
|
+
break;
|
|
1932
|
+
}
|
|
1933
|
+
|
|
1934
|
+
case XPATH_BC_AXIS_DESCENDANT_WILD_PRED_ATTR_EQ_STRING: {
|
|
1935
|
+
uint16_t name_idx = read_u16(&pc);
|
|
1936
|
+
uint16_t value_idx = read_u16(&pc);
|
|
1937
|
+
const char* attr_name = (name_idx < bc->const_count &&
|
|
1938
|
+
bc->constants[name_idx].type == XPATH_CONST_STRING)
|
|
1939
|
+
? bc->constants[name_idx].v.string : NULL;
|
|
1940
|
+
const char* attr_value = (value_idx < bc->const_count &&
|
|
1941
|
+
bc->constants[value_idx].type == XPATH_CONST_STRING)
|
|
1942
|
+
? bc->constants[value_idx].v.string : NULL;
|
|
1943
|
+
struct leptris_xpath_result* r =
|
|
1944
|
+
vm_apply_axis_descendant_pred_attr(ctx, &vm, attr_name, attr_value, 1, 0);
|
|
1945
|
+
if (!r) { vm.error = 1; break; }
|
|
1946
|
+
vm_push(&vm, r);
|
|
1947
|
+
break;
|
|
1948
|
+
}
|
|
1949
|
+
|
|
1950
|
+
case XPATH_BC_AXIS_DESCENDANT_OR_SELF_WILD_PRED_ATTR_EXISTS: {
|
|
1951
|
+
uint16_t idx = read_u16(&pc);
|
|
1952
|
+
const char* attr_name = (idx < bc->const_count &&
|
|
1953
|
+
bc->constants[idx].type == XPATH_CONST_STRING)
|
|
1954
|
+
? bc->constants[idx].v.string : NULL;
|
|
1955
|
+
struct leptris_xpath_result* r =
|
|
1956
|
+
vm_apply_axis_descendant_pred_attr(ctx, &vm, attr_name, NULL, 0, 1);
|
|
1957
|
+
if (!r) { vm.error = 1; break; }
|
|
1958
|
+
vm_push(&vm, r);
|
|
1959
|
+
break;
|
|
1960
|
+
}
|
|
1961
|
+
|
|
1962
|
+
case XPATH_BC_AXIS_DESCENDANT_OR_SELF_WILD_PRED_ATTR_EQ_STRING: {
|
|
1963
|
+
uint16_t name_idx = read_u16(&pc);
|
|
1964
|
+
uint16_t value_idx = read_u16(&pc);
|
|
1965
|
+
const char* attr_name = (name_idx < bc->const_count &&
|
|
1966
|
+
bc->constants[name_idx].type == XPATH_CONST_STRING)
|
|
1967
|
+
? bc->constants[name_idx].v.string : NULL;
|
|
1968
|
+
const char* attr_value = (value_idx < bc->const_count &&
|
|
1969
|
+
bc->constants[value_idx].type == XPATH_CONST_STRING)
|
|
1970
|
+
? bc->constants[value_idx].v.string : NULL;
|
|
1971
|
+
struct leptris_xpath_result* r =
|
|
1972
|
+
vm_apply_axis_descendant_pred_attr(ctx, &vm, attr_name, attr_value, 1, 1);
|
|
1973
|
+
if (!r) { vm.error = 1; break; }
|
|
1974
|
+
vm_push(&vm, r);
|
|
1975
|
+
break;
|
|
1976
|
+
}
|
|
1977
|
+
|
|
1978
|
+
case XPATH_BC_AXIS_DESCENDANT_OR_SELF_NAME: {
|
|
1979
|
+
uint16_t idx = read_u16(&pc);
|
|
1980
|
+
const char* name = (idx < bc->const_count &&
|
|
1981
|
+
bc->constants[idx].type == XPATH_CONST_STRING)
|
|
1982
|
+
? bc->constants[idx].v.string : NULL;
|
|
1983
|
+
struct leptris_xpath_result* r =
|
|
1984
|
+
vm_apply_axis_descendant(ctx, &vm, name, 0, 1);
|
|
1985
|
+
if (!r) { vm.error = 1; break; }
|
|
1986
|
+
vm_push(&vm, r);
|
|
1987
|
+
break;
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
case XPATH_BC_AXIS_DESCENDANT_OR_SELF_WILD: {
|
|
1991
|
+
struct leptris_xpath_result* r =
|
|
1992
|
+
vm_apply_axis_descendant(ctx, &vm, NULL, 1, 1);
|
|
1993
|
+
if (!r) { vm.error = 1; break; }
|
|
1994
|
+
vm_push(&vm, r);
|
|
1995
|
+
break;
|
|
1996
|
+
}
|
|
1997
|
+
|
|
1998
|
+
/* Absolute-path first-step opcodes (TODO 129). Each
|
|
1999
|
+
* pushes a nodeset directly — no pop. These start a
|
|
2000
|
+
* new path evaluation from the document root. */
|
|
2001
|
+
case XPATH_BC_ABSOLUTE_ROOT_MATCH_NAME: {
|
|
2002
|
+
uint16_t idx = read_u16(&pc);
|
|
2003
|
+
const char* name = (idx < bc->const_count &&
|
|
2004
|
+
bc->constants[idx].type == XPATH_CONST_STRING)
|
|
2005
|
+
? bc->constants[idx].v.string : NULL;
|
|
2006
|
+
/* `/foo` = root if root.name == foo. No descendants. */
|
|
2007
|
+
struct leptris_xpath_result* r =
|
|
2008
|
+
vm_apply_absolute(ctx, name, 0, 0 /* root-match only */);
|
|
2009
|
+
if (!r) { vm.error = 1; break; }
|
|
2010
|
+
vm_push(&vm, r);
|
|
2011
|
+
break;
|
|
2012
|
+
}
|
|
2013
|
+
|
|
2014
|
+
case XPATH_BC_ABSOLUTE_ROOT_MATCH_WILD: {
|
|
2015
|
+
/* Absolute root with wildcard match = root node. */
|
|
2016
|
+
struct leptris_xpath_result* r =
|
|
2017
|
+
vm_apply_absolute(ctx, NULL, 1, 0);
|
|
2018
|
+
if (!r) { vm.error = 1; break; }
|
|
2019
|
+
vm_push(&vm, r);
|
|
2020
|
+
break;
|
|
2021
|
+
}
|
|
2022
|
+
|
|
2023
|
+
case XPATH_BC_ABSOLUTE_DESCENDANT_NAME: {
|
|
2024
|
+
uint16_t idx = read_u16(&pc);
|
|
2025
|
+
const char* name = (idx < bc->const_count &&
|
|
2026
|
+
bc->constants[idx].type == XPATH_CONST_STRING)
|
|
2027
|
+
? bc->constants[idx].v.string : NULL;
|
|
2028
|
+
/* `/descendant::foo`: the context is the DOCUMENT node,
|
|
2029
|
+
* so the root element is itself a descendant — mode 2
|
|
2030
|
+
* includes it (mode 1's root-skip implemented element-
|
|
2031
|
+
* relative semantics; NsAbsolutePaths regression). */
|
|
2032
|
+
struct leptris_xpath_result* r =
|
|
2033
|
+
vm_apply_absolute(ctx, name, 0, 2);
|
|
2034
|
+
if (!r) { vm.error = 1; break; }
|
|
2035
|
+
vm_push(&vm, r);
|
|
2036
|
+
break;
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2039
|
+
case XPATH_BC_ABSOLUTE_DESCENDANT_TYPE: {
|
|
2040
|
+
uint16_t idx = read_u16(&pc);
|
|
2041
|
+
uint16_t tgt = read_u16(&pc);
|
|
2042
|
+
const char* type_name = (idx < bc->const_count &&
|
|
2043
|
+
bc->constants[idx].type == XPATH_CONST_STRING)
|
|
2044
|
+
? bc->constants[idx].v.string : NULL;
|
|
2045
|
+
const char* pi_target = (tgt != 0xFFFF && tgt < bc->const_count &&
|
|
2046
|
+
bc->constants[tgt].type == XPATH_CONST_STRING)
|
|
2047
|
+
? bc->constants[tgt].v.string : NULL;
|
|
2048
|
+
struct leptris_xpath_result* r =
|
|
2049
|
+
vm_apply_absolute_type(ctx, type_name, pi_target);
|
|
2050
|
+
if (!r) { vm.error = 1; break; }
|
|
2051
|
+
vm_push(&vm, r);
|
|
2052
|
+
break;
|
|
2053
|
+
}
|
|
2054
|
+
|
|
2055
|
+
case XPATH_BC_ABSOLUTE_DESCENDANT_WILD: {
|
|
2056
|
+
/* Same document-context semantics as the NAME variant:
|
|
2057
|
+
* /descendant::* includes the root element. */
|
|
2058
|
+
struct leptris_xpath_result* r =
|
|
2059
|
+
vm_apply_absolute(ctx, NULL, 1, 2);
|
|
2060
|
+
if (!r) { vm.error = 1; break; }
|
|
2061
|
+
vm_push(&vm, r);
|
|
2062
|
+
break;
|
|
2063
|
+
}
|
|
2064
|
+
|
|
2065
|
+
case XPATH_BC_ABSOLUTE_DESCENDANT_OR_SELF_NAME: {
|
|
2066
|
+
uint16_t idx = read_u16(&pc);
|
|
2067
|
+
const char* name = (idx < bc->const_count &&
|
|
2068
|
+
bc->constants[idx].type == XPATH_CONST_STRING)
|
|
2069
|
+
? bc->constants[idx].v.string : NULL;
|
|
2070
|
+
/* `//foo` = root if matches + all matching descendants. */
|
|
2071
|
+
struct leptris_xpath_result* r =
|
|
2072
|
+
vm_apply_absolute(ctx, name, 0, 2);
|
|
2073
|
+
if (!r) { vm.error = 1; break; }
|
|
2074
|
+
vm_push(&vm, r);
|
|
2075
|
+
break;
|
|
2076
|
+
}
|
|
2077
|
+
|
|
2078
|
+
case XPATH_BC_ABSOLUTE_DESCENDANT_NAME_ATTREQ: {
|
|
2079
|
+
/* TODO 192d: `//name[@attr='value']` served from the
|
|
2080
|
+
* index. The value bucket holds exactly the elements
|
|
2081
|
+
* carrying attr=value (root included when it matches),
|
|
2082
|
+
* so one name-filtered scan IS the answer — no name
|
|
2083
|
+
* bucket materialization, no per-element attr walks. */
|
|
2084
|
+
uint16_t name_idx = read_u16(&pc);
|
|
2085
|
+
uint16_t attr_idx = read_u16(&pc);
|
|
2086
|
+
uint16_t value_idx = read_u16(&pc);
|
|
2087
|
+
const char* name = (name_idx < bc->const_count &&
|
|
2088
|
+
bc->constants[name_idx].type == XPATH_CONST_STRING)
|
|
2089
|
+
? bc->constants[name_idx].v.string : NULL;
|
|
2090
|
+
const char* attr_name = (attr_idx < bc->const_count &&
|
|
2091
|
+
bc->constants[attr_idx].type == XPATH_CONST_STRING)
|
|
2092
|
+
? bc->constants[attr_idx].v.string : NULL;
|
|
2093
|
+
/* 0xFFFF = no value operand: attr-EXISTS predicate. */
|
|
2094
|
+
const char* value = (value_idx != 0xFFFF &&
|
|
2095
|
+
value_idx < bc->const_count &&
|
|
2096
|
+
bc->constants[value_idx].type == XPATH_CONST_STRING)
|
|
2097
|
+
? bc->constants[value_idx].v.string : NULL;
|
|
2098
|
+
if (!name || !attr_name || (value_idx != 0xFFFF && !value)) {
|
|
2099
|
+
vm.error = 1;
|
|
2100
|
+
break;
|
|
2101
|
+
}
|
|
2102
|
+
|
|
2103
|
+
struct leptris_element_index* index =
|
|
2104
|
+
(ctx && ctx->document) ? ctx->document->element_index : NULL;
|
|
2105
|
+
if (!index && ctx && ctx->document &&
|
|
2106
|
+
++ctx->document->axis_query_count >= 2) {
|
|
2107
|
+
index = leptris_element_index_build(ctx->document);
|
|
2108
|
+
ctx->document->element_index = index;
|
|
2109
|
+
}
|
|
2110
|
+
|
|
2111
|
+
XPathNodeSet* out = xpath_nodeset_new();
|
|
2112
|
+
if (!out) { vm.error = 1; break; }
|
|
2113
|
+
|
|
2114
|
+
int served = 0;
|
|
2115
|
+
if (index && index->subtree_end) {
|
|
2116
|
+
const LeptrisElementIndexAttrBucket* abucket =
|
|
2117
|
+
leptris_element_index_lookup_attr(index, attr_name);
|
|
2118
|
+
/* Equality reads the value bucket; existence reads
|
|
2119
|
+
* the any-value bucket (TODO 192e). */
|
|
2120
|
+
const LeptrisElement* bucket_matches = NULL;
|
|
2121
|
+
size_t bucket_count = 0;
|
|
2122
|
+
int bucket_valid = 0;
|
|
2123
|
+
if (value) {
|
|
2124
|
+
const LeptrisElementIndexAttrValue* vbucket =
|
|
2125
|
+
abucket ? leptris_element_index_attr_lookup_value(abucket, value)
|
|
2126
|
+
: NULL;
|
|
2127
|
+
if (!vbucket ||
|
|
2128
|
+
(vbucket->count > 0 && vbucket->match_positions)) {
|
|
2129
|
+
bucket_valid = 1;
|
|
2130
|
+
if (vbucket) {
|
|
2131
|
+
bucket_matches = vbucket->matches;
|
|
2132
|
+
bucket_count = vbucket->count;
|
|
2133
|
+
}
|
|
2134
|
+
}
|
|
2135
|
+
} else if (!abucket ||
|
|
2136
|
+
(abucket->count > 0 && abucket->match_positions)) {
|
|
2137
|
+
bucket_valid = 1;
|
|
2138
|
+
if (abucket) {
|
|
2139
|
+
bucket_matches = abucket->matches;
|
|
2140
|
+
bucket_count = abucket->count;
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2143
|
+
if (bucket_valid) {
|
|
2144
|
+
for (size_t j = 0; j < bucket_count; j++) {
|
|
2145
|
+
if (vm_unprefixed_name_matches(
|
|
2146
|
+
ctx, bucket_matches[j], name)) {
|
|
2147
|
+
xpath_nodeset_add_fast(out, bucket_matches[j]);
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
served = 1;
|
|
2151
|
+
}
|
|
2152
|
+
}
|
|
2153
|
+
|
|
2154
|
+
if (!served) {
|
|
2155
|
+
/* Fallback: full walk from root with inline
|
|
2156
|
+
* hash-prefiltered attr filter. */
|
|
2157
|
+
LeptrisElement root = (ctx && ctx->document)
|
|
2158
|
+
? (LeptrisElement)ctx->document->new_dom_root : NULL;
|
|
2159
|
+
if (root) {
|
|
2160
|
+
uint16_t attr_hash =
|
|
2161
|
+
attr_hash15(attr_name, strlen(attr_name));
|
|
2162
|
+
size_t mark = out->count;
|
|
2163
|
+
descendant_walk(ctx, out, root, name, 0, 1);
|
|
2164
|
+
for (size_t w = mark; w < out->count;) {
|
|
2165
|
+
LeptrisElement e2 = (LeptrisElement)out->nodes[w];
|
|
2166
|
+
const char* v = NULL;
|
|
2167
|
+
for (struct leptris_attribute* a =
|
|
2168
|
+
leptris_element_get_first_attribute(e2);
|
|
2169
|
+
a; a = leptris_attr_next(a)) {
|
|
2170
|
+
if (attr_name_hash(a) == attr_hash &&
|
|
2171
|
+
attr_cname(a) &&
|
|
2172
|
+
strcmp(attr_cname(a), attr_name) == 0) {
|
|
2173
|
+
v = attr_cvalue(a);
|
|
2174
|
+
break;
|
|
2175
|
+
}
|
|
2176
|
+
}
|
|
2177
|
+
if (value ? (v && strcmp(v, value) == 0)
|
|
2178
|
+
: (v != NULL)) {
|
|
2179
|
+
w++;
|
|
2180
|
+
} else {
|
|
2181
|
+
out->nodes[w] = out->nodes[out->count - 1];
|
|
2182
|
+
out->count--;
|
|
2183
|
+
}
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
|
|
2188
|
+
struct leptris_xpath_result* r =
|
|
2189
|
+
xpath_result_new(XPATH_RESULT_NODESET);
|
|
2190
|
+
if (!r) { xpath_nodeset_free(out); vm.error = 1; break; }
|
|
2191
|
+
r->value.nodeset_value = out;
|
|
2192
|
+
vm_push(&vm, r);
|
|
2193
|
+
break;
|
|
2194
|
+
}
|
|
2195
|
+
|
|
2196
|
+
case XPATH_BC_ABSOLUTE_DESCENDANT_NAME_ATTREQ_VAR: {
|
|
2197
|
+
/* `//name[@attr=$var]` (issue #565): RHS resolved at
|
|
2198
|
+
* run time from the context's variable set, then the
|
|
2199
|
+
* attr-VALUE bucket + name check — one variable read
|
|
2200
|
+
* per query, no per-element XPath evaluation. */
|
|
2201
|
+
uint16_t name_idx = read_u16(&pc);
|
|
2202
|
+
uint16_t attr_idx = read_u16(&pc);
|
|
2203
|
+
uint16_t var_idx = read_u16(&pc);
|
|
2204
|
+
const char* name = (name_idx < bc->const_count &&
|
|
2205
|
+
bc->constants[name_idx].type == XPATH_CONST_STRING)
|
|
2206
|
+
? bc->constants[name_idx].v.string : NULL;
|
|
2207
|
+
const char* attr_name = (attr_idx < bc->const_count &&
|
|
2208
|
+
bc->constants[attr_idx].type == XPATH_CONST_STRING)
|
|
2209
|
+
? bc->constants[attr_idx].v.string : NULL;
|
|
2210
|
+
const char* var_name = (var_idx < bc->const_count &&
|
|
2211
|
+
bc->constants[var_idx].type == XPATH_CONST_STRING)
|
|
2212
|
+
? bc->constants[var_idx].v.string : NULL;
|
|
2213
|
+
if (!name || !attr_name || !var_name) {
|
|
2214
|
+
vm.error = 1; break;
|
|
2215
|
+
}
|
|
2216
|
+
if (!ctx->variable_set) {
|
|
2217
|
+
snprintf(ctx->error_msg, sizeof(ctx->error_msg),
|
|
2218
|
+
"Variable '%s' not found (no variable set provided)",
|
|
2219
|
+
var_name);
|
|
2220
|
+
vm.error = 1; break;
|
|
2221
|
+
}
|
|
2222
|
+
const XPathVariable* var = xpath_variable_set_get_const(
|
|
2223
|
+
(XPathVariableSet*)ctx->variable_set, var_name);
|
|
2224
|
+
if (!var) {
|
|
2225
|
+
snprintf(ctx->error_msg, sizeof(ctx->error_msg),
|
|
2226
|
+
"Undefined variable: %s", var_name);
|
|
2227
|
+
vm.error = 1; break;
|
|
2228
|
+
}
|
|
2229
|
+
/* string($var) via the shared converter — borrows the
|
|
2230
|
+
* variable's storage; only the produced string is ours. */
|
|
2231
|
+
struct leptris_xpath_result tmp;
|
|
2232
|
+
memset(&tmp, 0, sizeof(tmp));
|
|
2233
|
+
switch (var->value.type) {
|
|
2234
|
+
case XPATH_VAR_TYPE_BOOLEAN:
|
|
2235
|
+
tmp.type = XPATH_RESULT_BOOLEAN;
|
|
2236
|
+
tmp.value.boolean_value = var->value.v.boolean_value;
|
|
2237
|
+
break;
|
|
2238
|
+
case XPATH_VAR_TYPE_NUMBER:
|
|
2239
|
+
tmp.type = XPATH_RESULT_NUMBER;
|
|
2240
|
+
tmp.value.number_value = var->value.v.number_value;
|
|
2241
|
+
break;
|
|
2242
|
+
case XPATH_VAR_TYPE_NODE_SET:
|
|
2243
|
+
tmp.type = XPATH_RESULT_NODESET;
|
|
2244
|
+
tmp.value.nodeset_value = var->value.v.nodeset_value;
|
|
2245
|
+
break;
|
|
2246
|
+
default:
|
|
2247
|
+
tmp.type = XPATH_RESULT_STRING;
|
|
2248
|
+
tmp.value.string_value = var->value.v.string_value
|
|
2249
|
+
? var->value.v.string_value : (char*)"";
|
|
2250
|
+
break;
|
|
2251
|
+
}
|
|
2252
|
+
char* value = xpath_to_string(&tmp);
|
|
2253
|
+
if (!value) { vm.error = 1; break; }
|
|
2254
|
+
|
|
2255
|
+
struct leptris_element_index* index =
|
|
2256
|
+
(ctx && ctx->document) ? ctx->document->element_index : NULL;
|
|
2257
|
+
if (!index && ctx && ctx->document &&
|
|
2258
|
+
++ctx->document->axis_query_count >= 2) {
|
|
2259
|
+
index = leptris_element_index_build(ctx->document);
|
|
2260
|
+
ctx->document->element_index = index;
|
|
2261
|
+
}
|
|
2262
|
+
|
|
2263
|
+
XPathNodeSet* out = xpath_nodeset_new();
|
|
2264
|
+
if (!out) { free(value); vm.error = 1; break; }
|
|
2265
|
+
|
|
2266
|
+
/* Same serve order as the literal ATTREQ opcode: the
|
|
2267
|
+
* attr-VALUE bucket + name filter when the index has
|
|
2268
|
+
* it, otherwise one hash-prefiltered walk. */
|
|
2269
|
+
int served = 0;
|
|
2270
|
+
if (index && index->subtree_end) {
|
|
2271
|
+
const LeptrisElementIndexAttrBucket* abucket =
|
|
2272
|
+
leptris_element_index_lookup_attr(index, attr_name);
|
|
2273
|
+
const LeptrisElementIndexAttrValue* vbucket = abucket
|
|
2274
|
+
? leptris_element_index_attr_lookup_value(abucket, value)
|
|
2275
|
+
: NULL;
|
|
2276
|
+
if (!vbucket ||
|
|
2277
|
+
(vbucket->count > 0 && vbucket->match_positions)) {
|
|
2278
|
+
served = 1;
|
|
2279
|
+
if (vbucket) {
|
|
2280
|
+
for (size_t j = 0; j < vbucket->count; j++) {
|
|
2281
|
+
if (vm_unprefixed_name_matches(
|
|
2282
|
+
ctx, vbucket->matches[j], name))
|
|
2283
|
+
xpath_nodeset_add_fast(out,
|
|
2284
|
+
vbucket->matches[j]);
|
|
2285
|
+
}
|
|
2286
|
+
}
|
|
2287
|
+
}
|
|
2288
|
+
}
|
|
2289
|
+
|
|
2290
|
+
if (!served) {
|
|
2291
|
+
LeptrisElement root = (ctx && ctx->document)
|
|
2292
|
+
? (LeptrisElement)ctx->document->new_dom_root : NULL;
|
|
2293
|
+
if (root) {
|
|
2294
|
+
uint16_t attr_hash =
|
|
2295
|
+
attr_hash15(attr_name, strlen(attr_name));
|
|
2296
|
+
size_t mark = out->count;
|
|
2297
|
+
descendant_walk(ctx, out, root, name, 0, 1);
|
|
2298
|
+
for (size_t w = mark; w < out->count;) {
|
|
2299
|
+
LeptrisElement e2 = (LeptrisElement)out->nodes[w];
|
|
2300
|
+
const char* v = NULL;
|
|
2301
|
+
for (struct leptris_attribute* a =
|
|
2302
|
+
leptris_element_get_first_attribute(e2);
|
|
2303
|
+
a; a = leptris_attr_next(a)) {
|
|
2304
|
+
if (attr_name_hash(a) == attr_hash &&
|
|
2305
|
+
attr_cname(a) &&
|
|
2306
|
+
strcmp(attr_cname(a), attr_name) == 0) {
|
|
2307
|
+
v = attr_cvalue(a);
|
|
2308
|
+
break;
|
|
2309
|
+
}
|
|
2310
|
+
}
|
|
2311
|
+
if (v && strcmp(v, value) == 0) {
|
|
2312
|
+
w++;
|
|
2313
|
+
} else {
|
|
2314
|
+
out->nodes[w] = out->nodes[out->count - 1];
|
|
2315
|
+
out->count--;
|
|
2316
|
+
}
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
free(value);
|
|
2321
|
+
|
|
2322
|
+
struct leptris_xpath_result* r =
|
|
2323
|
+
xpath_result_new(XPATH_RESULT_NODESET);
|
|
2324
|
+
if (!r) { xpath_nodeset_free(out); vm.error = 1; break; }
|
|
2325
|
+
r->value.nodeset_value = out;
|
|
2326
|
+
vm_push(&vm, r);
|
|
2327
|
+
break;
|
|
2328
|
+
}
|
|
2329
|
+
|
|
2330
|
+
case XPATH_BC_ABSOLUTE_DESCENDANT_OR_SELF_WILD: {
|
|
2331
|
+
struct leptris_xpath_result* r =
|
|
2332
|
+
vm_apply_absolute(ctx, NULL, 1, 2);
|
|
2333
|
+
if (!r) { vm.error = 1; break; }
|
|
2334
|
+
vm_push(&vm, r);
|
|
2335
|
+
break;
|
|
2336
|
+
}
|
|
2337
|
+
|
|
2338
|
+
case XPATH_BC_ABSOLUTE_ELEMENTS_AND_DOC: {
|
|
2339
|
+
/* Doc node + every element (root first) — the exact
|
|
2340
|
+
* context set for //NAME[...] (#645). */
|
|
2341
|
+
struct leptris_xpath_result* els =
|
|
2342
|
+
vm_apply_absolute(ctx, NULL, 1, 2);
|
|
2343
|
+
if (!els || !els->value.nodeset_value) {
|
|
2344
|
+
if (els) leptris_xpath_result_free(els);
|
|
2345
|
+
vm.error = 1;
|
|
2346
|
+
break;
|
|
2347
|
+
}
|
|
2348
|
+
XPathNodeSet* src = els->value.nodeset_value;
|
|
2349
|
+
XPathNodeSet* out = xpath_nodeset_new_with_capacity(
|
|
2350
|
+
src->count + 1);
|
|
2351
|
+
if (!out) {
|
|
2352
|
+
leptris_xpath_result_free(els);
|
|
2353
|
+
vm.error = 1;
|
|
2354
|
+
break;
|
|
2355
|
+
}
|
|
2356
|
+
LeptrisNodeRef dn = (LeptrisNodeRef)
|
|
2357
|
+
leptris_document_get_node(ctx->document);
|
|
2358
|
+
if (dn) xpath_nodeset_add_fast(out, (LeptrisNode*)dn);
|
|
2359
|
+
for (size_t i = 0; i < src->count; i++)
|
|
2360
|
+
xpath_nodeset_add_fast(out, src->nodes[i]);
|
|
2361
|
+
leptris_xpath_result_free(els);
|
|
2362
|
+
struct leptris_xpath_result* r =
|
|
2363
|
+
xpath_result_new(XPATH_RESULT_NODESET);
|
|
2364
|
+
if (!r) { xpath_nodeset_free(out); vm.error = 1; break; }
|
|
2365
|
+
r->value.nodeset_value = out;
|
|
2366
|
+
vm_push(&vm, r);
|
|
2367
|
+
break;
|
|
2368
|
+
}
|
|
2369
|
+
|
|
2370
|
+
case XPATH_BC_ABSOLUTE_DOS_ALL_NODES: {
|
|
2371
|
+
/* Exact /descendant-or-self::node(): the doc node,
|
|
2372
|
+
* then every node in document order (#645). */
|
|
2373
|
+
XPathNodeSet* out = xpath_nodeset_new();
|
|
2374
|
+
if (!out) { vm.error = 1; break; }
|
|
2375
|
+
LeptrisNodeRef dn = (LeptrisNodeRef)
|
|
2376
|
+
leptris_document_get_node(ctx->document);
|
|
2377
|
+
if (dn) {
|
|
2378
|
+
xpath_nodeset_add_fast(out, (LeptrisNode*)dn);
|
|
2379
|
+
/* Doc-node children = the document child chain
|
|
2380
|
+
* (#580), root included. */
|
|
2381
|
+
struct leptris_document* d = ctx->document;
|
|
2382
|
+
LeptrisNode* start = (LeptrisNode*)d->doc_children_head;
|
|
2383
|
+
if (!start) start = (LeptrisNode*)d->new_dom_root;
|
|
2384
|
+
for (LeptrisNode* c = start; c;
|
|
2385
|
+
c = leptris_node_get_next_sibling(c))
|
|
2386
|
+
all_nodes_preorder(out, c);
|
|
2387
|
+
} else if (ctx->document->new_dom_root) {
|
|
2388
|
+
all_nodes_preorder(
|
|
2389
|
+
out, (LeptrisNode*)ctx->document->new_dom_root);
|
|
2390
|
+
}
|
|
2391
|
+
struct leptris_xpath_result* r =
|
|
2392
|
+
xpath_result_new(XPATH_RESULT_NODESET);
|
|
2393
|
+
if (!r) { xpath_nodeset_free(out); vm.error = 1; break; }
|
|
2394
|
+
r->value.nodeset_value = out;
|
|
2395
|
+
vm_push(&vm, r);
|
|
2396
|
+
break;
|
|
2397
|
+
}
|
|
2398
|
+
|
|
2399
|
+
/* Simple predicate handlers (TODO 128). Each pops the
|
|
2400
|
+
* input nodeset, filters inline, pushes the filtered
|
|
2401
|
+
* result. The compiler emits these after a specialized
|
|
2402
|
+
* axis opcode for the common predicate shapes
|
|
2403
|
+
* ([@attr], [@attr = 'lit'], [N]). */
|
|
2404
|
+
|
|
2405
|
+
case XPATH_BC_PRED_ATTR_EXISTS: {
|
|
2406
|
+
uint16_t idx = read_u16(&pc);
|
|
2407
|
+
const char* attr_name = (idx < bc->const_count &&
|
|
2408
|
+
bc->constants[idx].type == XPATH_CONST_STRING)
|
|
2409
|
+
? bc->constants[idx].v.string : NULL;
|
|
2410
|
+
XPathNodeSet* input = vm_detach_input_nodeset(&vm);
|
|
2411
|
+
if (!input) { vm.error = 1; break; }
|
|
2412
|
+
|
|
2413
|
+
/* TODO 159 Phase E: hoist strlen + hash out of the
|
|
2414
|
+
* inner attribute-walk loop. Previous code called
|
|
2415
|
+
* strlen(attr_name) inside the loop body, redundant
|
|
2416
|
+
* per-attr. */
|
|
2417
|
+
size_t name_len = attr_name ? strlen(attr_name) : 0;
|
|
2418
|
+
uint16_t name_hash = attr_name ? attr_hash15(attr_name, name_len) : 0;
|
|
2419
|
+
|
|
2420
|
+
size_t write = 0;
|
|
2421
|
+
for (size_t read = 0; read < input->count; read++) {
|
|
2422
|
+
void* node = input->nodes[read];
|
|
2423
|
+
if (!node_is_element(node)) continue;
|
|
2424
|
+
LeptrisElement elem = (LeptrisElement)node;
|
|
2425
|
+
struct leptris_attribute* a =
|
|
2426
|
+
leptris_element_get_first_attribute(elem);
|
|
2427
|
+
int found = 0;
|
|
2428
|
+
while (a) {
|
|
2429
|
+
/* Hash pre-filter first; only fall through to
|
|
2430
|
+
* length + memcmp on hash match. Lazy compute
|
|
2431
|
+
* on first read (TODO 172). */
|
|
2432
|
+
if (attr_name && attr_name_hash(a) == name_hash &&
|
|
2433
|
+
a->name_view.length == name_len &&
|
|
2434
|
+
a->name_view.data &&
|
|
2435
|
+
memcmp(attr_name, a->name_view.data, name_len) == 0) {
|
|
2436
|
+
found = 1;
|
|
2437
|
+
break;
|
|
2438
|
+
}
|
|
2439
|
+
a = leptris_attr_next(a);
|
|
2440
|
+
}
|
|
2441
|
+
if (found) {
|
|
2442
|
+
if (write != read) input->nodes[write] = node;
|
|
2443
|
+
write++;
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
input->count = write;
|
|
2447
|
+
|
|
2448
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_NODESET);
|
|
2449
|
+
if (!r) { xpath_nodeset_free(input); vm.error = 1; break; }
|
|
2450
|
+
r->value.nodeset_value = input;
|
|
2451
|
+
vm_push(&vm, r);
|
|
2452
|
+
break;
|
|
2453
|
+
}
|
|
2454
|
+
|
|
2455
|
+
case XPATH_BC_PRED_ATTR_EQ_STRING: {
|
|
2456
|
+
/* Two u16 operands: attr name idx, value idx. */
|
|
2457
|
+
uint16_t name_idx = read_u16(&pc);
|
|
2458
|
+
uint16_t value_idx = read_u16(&pc);
|
|
2459
|
+
const char* attr_name = (name_idx < bc->const_count &&
|
|
2460
|
+
bc->constants[name_idx].type == XPATH_CONST_STRING)
|
|
2461
|
+
? bc->constants[name_idx].v.string : NULL;
|
|
2462
|
+
const char* expected = (value_idx < bc->const_count &&
|
|
2463
|
+
bc->constants[value_idx].type == XPATH_CONST_STRING)
|
|
2464
|
+
? bc->constants[value_idx].v.string : NULL;
|
|
2465
|
+
XPathNodeSet* input = vm_detach_input_nodeset(&vm);
|
|
2466
|
+
if (!input) { vm.error = 1; break; }
|
|
2467
|
+
|
|
2468
|
+
/* TODO 159 Phase E: hoist strlen's out of the inner
|
|
2469
|
+
* loop. Previous code called strlen(attr_name) and
|
|
2470
|
+
* strlen(expected) once per attribute per element. */
|
|
2471
|
+
size_t name_len = attr_name ? strlen(attr_name) : 0;
|
|
2472
|
+
size_t value_len = expected ? strlen(expected) : 0;
|
|
2473
|
+
uint16_t name_hash = attr_name ? attr_hash15(attr_name, name_len) : 0;
|
|
2474
|
+
|
|
2475
|
+
size_t write = 0;
|
|
2476
|
+
for (size_t read = 0; read < input->count; read++) {
|
|
2477
|
+
void* node = input->nodes[read];
|
|
2478
|
+
if (!node_is_element(node)) continue;
|
|
2479
|
+
LeptrisElement elem = (LeptrisElement)node;
|
|
2480
|
+
struct leptris_attribute* a =
|
|
2481
|
+
leptris_element_get_first_attribute(elem);
|
|
2482
|
+
int match = 0;
|
|
2483
|
+
while (a) {
|
|
2484
|
+
/* Hash + length pre-filter before memcmp. Lazy hash. */
|
|
2485
|
+
if (attr_name && expected &&
|
|
2486
|
+
attr_name_hash(a) == name_hash &&
|
|
2487
|
+
a->name_view.length == name_len &&
|
|
2488
|
+
leptris_attr_value_sv(a).length == value_len &&
|
|
2489
|
+
a->name_view.data && leptris_attr_value_sv(a).data &&
|
|
2490
|
+
memcmp(attr_name, a->name_view.data, name_len) == 0 &&
|
|
2491
|
+
memcmp(expected, leptris_attr_value_sv(a).data, value_len) == 0) {
|
|
2492
|
+
match = 1;
|
|
2493
|
+
break;
|
|
2494
|
+
}
|
|
2495
|
+
a = leptris_attr_next(a);
|
|
2496
|
+
}
|
|
2497
|
+
if (match) {
|
|
2498
|
+
if (write != read) input->nodes[write] = node;
|
|
2499
|
+
write++;
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2502
|
+
input->count = write;
|
|
2503
|
+
|
|
2504
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_NODESET);
|
|
2505
|
+
if (!r) { xpath_nodeset_free(input); vm.error = 1; break; }
|
|
2506
|
+
r->value.nodeset_value = input;
|
|
2507
|
+
vm_push(&vm, r);
|
|
2508
|
+
break;
|
|
2509
|
+
}
|
|
2510
|
+
|
|
2511
|
+
case XPATH_BC_PRED_POSITION: {
|
|
2512
|
+
uint8_t pos = read_u8(&pc);
|
|
2513
|
+
XPathNodeSet* input = vm_detach_input_nodeset(&vm);
|
|
2514
|
+
if (!input) { vm.error = 1; break; }
|
|
2515
|
+
|
|
2516
|
+
/* Keep only the pos-th element (1-based). */
|
|
2517
|
+
if (pos == 0 || (size_t)pos > input->count) {
|
|
2518
|
+
input->count = 0;
|
|
2519
|
+
} else {
|
|
2520
|
+
void* keep = input->nodes[pos - 1];
|
|
2521
|
+
input->nodes[0] = keep;
|
|
2522
|
+
input->count = 1;
|
|
2523
|
+
}
|
|
2524
|
+
|
|
2525
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_NODESET);
|
|
2526
|
+
if (!r) { xpath_nodeset_free(input); vm.error = 1; break; }
|
|
2527
|
+
r->value.nodeset_value = input;
|
|
2528
|
+
vm_push(&vm, r);
|
|
2529
|
+
break;
|
|
2530
|
+
}
|
|
2531
|
+
|
|
2532
|
+
case XPATH_BC_PRED_CHILD_NUM_CMP: {
|
|
2533
|
+
/* Fused child-axis numeric comparison (TODO 159).
|
|
2534
|
+
* Inline encoding: u8 op, u16 name idx, f64 RHS. */
|
|
2535
|
+
uint8_t op_type = read_u8(&pc);
|
|
2536
|
+
uint16_t name_idx = read_u16(&pc);
|
|
2537
|
+
double rhs = read_double(&pc);
|
|
2538
|
+
const char* child_name = (name_idx < bc->const_count &&
|
|
2539
|
+
bc->constants[name_idx].type == XPATH_CONST_STRING)
|
|
2540
|
+
? bc->constants[name_idx].v.string : NULL;
|
|
2541
|
+
XPathNodeSet* input = vm_detach_input_nodeset(&vm);
|
|
2542
|
+
if (!input || !child_name) {
|
|
2543
|
+
if (input) xpath_nodeset_free(input);
|
|
2544
|
+
vm.error = 1;
|
|
2545
|
+
break;
|
|
2546
|
+
}
|
|
2547
|
+
|
|
2548
|
+
/* Pre-compute the target hash so we can compare 2 bytes
|
|
2549
|
+
* before strcmp on every child. */
|
|
2550
|
+
uint16_t target_hash = leptris_name_hash_compute(child_name);
|
|
2551
|
+
XPathOperatorType step_op = (XPathOperatorType)op_type;
|
|
2552
|
+
size_t child_name_len = strlen(child_name);
|
|
2553
|
+
|
|
2554
|
+
size_t write = 0;
|
|
2555
|
+
for (size_t read = 0; read < input->count; read++) {
|
|
2556
|
+
void* node = input->nodes[read];
|
|
2557
|
+
if (!node_is_element(node)) continue;
|
|
2558
|
+
LeptrisElement elem = (LeptrisElement)node;
|
|
2559
|
+
|
|
2560
|
+
/* Walk this element's children looking for a
|
|
2561
|
+
* child::name match. Hash pre-filter rejects
|
|
2562
|
+
* non-matching children in ~1ns. */
|
|
2563
|
+
LeptrisNode* child = (LeptrisNode*)leptris_elem_first_child(elem);
|
|
2564
|
+
LeptrisElement match = NULL;
|
|
2565
|
+
while (child) {
|
|
2566
|
+
if (child->type == LEPTRIS_NODE_TYPE_ELEMENT) {
|
|
2567
|
+
LeptrisElement ce = (LeptrisElement)child;
|
|
2568
|
+
if (ce->name_hash == target_hash && ce->name &&
|
|
2569
|
+
strlen(ce->name) == child_name_len &&
|
|
2570
|
+
memcmp(ce->name, child_name, child_name_len) == 0) {
|
|
2571
|
+
match = ce;
|
|
2572
|
+
break;
|
|
2573
|
+
}
|
|
2574
|
+
}
|
|
2575
|
+
child = leptris_node_get_next_sibling(child);
|
|
2576
|
+
}
|
|
2577
|
+
if (!match) continue;
|
|
2578
|
+
|
|
2579
|
+
/* Fast path: single text child is the common shape
|
|
2580
|
+
* for <price>42.50</price>. Read its content view
|
|
2581
|
+
* without allocating. */
|
|
2582
|
+
double lhs;
|
|
2583
|
+
LeptrisNode* tn = (LeptrisNode*)leptris_elem_first_child(match);
|
|
2584
|
+
if (tn && tn->type == LEPTRIS_NODE_TYPE_TEXT &&
|
|
2585
|
+
leptris_elem_next_sibling(match) == NULL) {
|
|
2586
|
+
const char* s =
|
|
2587
|
+
leptris_text_get_content((LeptrisTextNode*)tn);
|
|
2588
|
+
lhs = s ? strtod(s, NULL) : NAN;
|
|
2589
|
+
} else {
|
|
2590
|
+
char* s = leptris_element_get_text_content(match);
|
|
2591
|
+
if (s) {
|
|
2592
|
+
lhs = strtod(s, NULL);
|
|
2593
|
+
leptris_free(s);
|
|
2594
|
+
} else {
|
|
2595
|
+
lhs = NAN;
|
|
2596
|
+
}
|
|
2597
|
+
}
|
|
2598
|
+
|
|
2599
|
+
int match_flag = 0;
|
|
2600
|
+
switch (step_op) {
|
|
2601
|
+
case XPATH_OP_EQUAL: match_flag = (lhs == rhs); break;
|
|
2602
|
+
case XPATH_OP_NOT_EQUAL: match_flag = (lhs != rhs); break;
|
|
2603
|
+
case XPATH_OP_LESS: match_flag = (lhs < rhs); break;
|
|
2604
|
+
case XPATH_OP_LESS_EQUAL: match_flag = (lhs <= rhs); break;
|
|
2605
|
+
case XPATH_OP_GREATER: match_flag = (lhs > rhs); break;
|
|
2606
|
+
case XPATH_OP_GREATER_EQUAL: match_flag = (lhs >= rhs); break;
|
|
2607
|
+
default: break;
|
|
2608
|
+
}
|
|
2609
|
+
if (match_flag) {
|
|
2610
|
+
if (write != read) input->nodes[write] = node;
|
|
2611
|
+
write++;
|
|
2612
|
+
}
|
|
2613
|
+
}
|
|
2614
|
+
input->count = write;
|
|
2615
|
+
|
|
2616
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_NODESET);
|
|
2617
|
+
if (!r) { xpath_nodeset_free(input); vm.error = 1; break; }
|
|
2618
|
+
r->value.nodeset_value = input;
|
|
2619
|
+
vm_push(&vm, r);
|
|
2620
|
+
break;
|
|
2621
|
+
}
|
|
2622
|
+
|
|
2623
|
+
case XPATH_BC_BINARY_OP: {
|
|
2624
|
+
uint8_t op_type = read_u8(&pc);
|
|
2625
|
+
if (vm_apply_binary_op(&vm, ctx,
|
|
2626
|
+
(XPathOperatorType)op_type) != 0) {
|
|
2627
|
+
vm.error = 1;
|
|
2628
|
+
}
|
|
2629
|
+
break;
|
|
2630
|
+
}
|
|
2631
|
+
|
|
2632
|
+
case XPATH_BC_FUNC_CALL: {
|
|
2633
|
+
uint16_t idx = read_u16(&pc);
|
|
2634
|
+
if (idx >= bc->const_count ||
|
|
2635
|
+
bc->constants[idx].type != XPATH_CONST_AST_NODE) {
|
|
2636
|
+
vm.error = 1;
|
|
2637
|
+
break;
|
|
2638
|
+
}
|
|
2639
|
+
XPathASTNode* fc_ast = bc->constants[idx].v.ast;
|
|
2640
|
+
struct leptris_xpath_result* r =
|
|
2641
|
+
evaluate_function_call_inline(ctx, fc_ast);
|
|
2642
|
+
if (!r) { vm.error = 1; break; }
|
|
2643
|
+
vm_push(&vm, r);
|
|
2644
|
+
break;
|
|
2645
|
+
}
|
|
2646
|
+
|
|
2647
|
+
/* Inline function handlers (TODO 130). Each pops its
|
|
2648
|
+
* args from the stack and pushes the result. The
|
|
2649
|
+
* compiler emits <arg bytecode> + BC_FUNC_<NAME>
|
|
2650
|
+
* instead of BC_FUNC_CALL for the common XPath
|
|
2651
|
+
* functions. The VM evaluates args via normal dispatch
|
|
2652
|
+
* (which uses the fast specialized axis opcodes), then
|
|
2653
|
+
* applies the function inline. */
|
|
2654
|
+
|
|
2655
|
+
case XPATH_BC_FUNC_COUNT: {
|
|
2656
|
+
struct leptris_xpath_result* arg = vm_pop(&vm);
|
|
2657
|
+
if (!arg) { vm.error = 1; break; }
|
|
2658
|
+
/* atomic = one item (XQuery sequences; the twin
|
|
2659
|
+
* of xpath_func_count's QT3 fix) */
|
|
2660
|
+
size_t count = 1;
|
|
2661
|
+
if (arg->type == XPATH_RESULT_NODESET) {
|
|
2662
|
+
count = arg->value.nodeset_value
|
|
2663
|
+
? arg->value.nodeset_value->count
|
|
2664
|
+
: 0;
|
|
2665
|
+
}
|
|
2666
|
+
xpath_result_free(arg);
|
|
2667
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_NUMBER);
|
|
2668
|
+
if (!r) { vm.error = 1; break; }
|
|
2669
|
+
r->value.number_value = (double)count;
|
|
2670
|
+
vm_push(&vm, r);
|
|
2671
|
+
break;
|
|
2672
|
+
}
|
|
2673
|
+
|
|
2674
|
+
case XPATH_BC_FUNC_SUM: {
|
|
2675
|
+
struct leptris_xpath_result* arg = vm_pop(&vm);
|
|
2676
|
+
if (!arg) { vm.error = 1; break; }
|
|
2677
|
+
double sum = 0.0;
|
|
2678
|
+
if (arg->type == XPATH_RESULT_NODESET && arg->value.nodeset_value) {
|
|
2679
|
+
XPathNodeSet* ns = arg->value.nodeset_value;
|
|
2680
|
+
for (size_t i = 0; i < ns->count; i++) {
|
|
2681
|
+
char* txt = get_node_text(ns->nodes[i]);
|
|
2682
|
+
if (txt) {
|
|
2683
|
+
sum += atof(txt);
|
|
2684
|
+
free(txt);
|
|
2685
|
+
}
|
|
2686
|
+
}
|
|
2687
|
+
}
|
|
2688
|
+
xpath_result_free(arg);
|
|
2689
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_NUMBER);
|
|
2690
|
+
if (!r) { vm.error = 1; break; }
|
|
2691
|
+
r->value.number_value = sum;
|
|
2692
|
+
vm_push(&vm, r);
|
|
2693
|
+
break;
|
|
2694
|
+
}
|
|
2695
|
+
|
|
2696
|
+
case XPATH_BC_FUNC_POSITION: {
|
|
2697
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_NUMBER);
|
|
2698
|
+
if (!r) { vm.error = 1; break; }
|
|
2699
|
+
r->value.number_value = (double)ctx->context_position;
|
|
2700
|
+
vm_push(&vm, r);
|
|
2701
|
+
break;
|
|
2702
|
+
}
|
|
2703
|
+
|
|
2704
|
+
case XPATH_BC_FUNC_LAST: {
|
|
2705
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_NUMBER);
|
|
2706
|
+
if (!r) { vm.error = 1; break; }
|
|
2707
|
+
r->value.number_value = (double)ctx->context_size;
|
|
2708
|
+
vm_push(&vm, r);
|
|
2709
|
+
break;
|
|
2710
|
+
}
|
|
2711
|
+
|
|
2712
|
+
case XPATH_BC_FUNC_TRUE: {
|
|
2713
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_BOOLEAN);
|
|
2714
|
+
if (!r) { vm.error = 1; break; }
|
|
2715
|
+
r->value.boolean_value = 1;
|
|
2716
|
+
vm_push(&vm, r);
|
|
2717
|
+
break;
|
|
2718
|
+
}
|
|
2719
|
+
|
|
2720
|
+
case XPATH_BC_FUNC_FALSE: {
|
|
2721
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_BOOLEAN);
|
|
2722
|
+
if (!r) { vm.error = 1; break; }
|
|
2723
|
+
r->value.boolean_value = 0;
|
|
2724
|
+
vm_push(&vm, r);
|
|
2725
|
+
break;
|
|
2726
|
+
}
|
|
2727
|
+
|
|
2728
|
+
case XPATH_BC_FUNC_NOT: {
|
|
2729
|
+
struct leptris_xpath_result* arg = vm_pop(&vm);
|
|
2730
|
+
if (!arg) { vm.error = 1; break; }
|
|
2731
|
+
int b = xpath_to_boolean(arg);
|
|
2732
|
+
xpath_result_free(arg);
|
|
2733
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_BOOLEAN);
|
|
2734
|
+
if (!r) { vm.error = 1; break; }
|
|
2735
|
+
r->value.boolean_value = !b;
|
|
2736
|
+
vm_push(&vm, r);
|
|
2737
|
+
break;
|
|
2738
|
+
}
|
|
2739
|
+
|
|
2740
|
+
case XPATH_BC_FUNC_BOOLEAN: {
|
|
2741
|
+
struct leptris_xpath_result* arg = vm_pop(&vm);
|
|
2742
|
+
if (!arg) { vm.error = 1; break; }
|
|
2743
|
+
int b = xpath_to_boolean(arg);
|
|
2744
|
+
xpath_result_free(arg);
|
|
2745
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_BOOLEAN);
|
|
2746
|
+
if (!r) { vm.error = 1; break; }
|
|
2747
|
+
r->value.boolean_value = b;
|
|
2748
|
+
vm_push(&vm, r);
|
|
2749
|
+
break;
|
|
2750
|
+
}
|
|
2751
|
+
|
|
2752
|
+
case XPATH_BC_FUNC_NUMBER: {
|
|
2753
|
+
struct leptris_xpath_result* arg = vm_pop(&vm);
|
|
2754
|
+
if (!arg) { vm.error = 1; break; }
|
|
2755
|
+
double n = xpath_to_number(arg);
|
|
2756
|
+
xpath_result_free(arg);
|
|
2757
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_NUMBER);
|
|
2758
|
+
if (!r) { vm.error = 1; break; }
|
|
2759
|
+
r->value.number_value = n;
|
|
2760
|
+
vm_push(&vm, r);
|
|
2761
|
+
break;
|
|
2762
|
+
}
|
|
2763
|
+
|
|
2764
|
+
case XPATH_BC_FUNC_STRING: {
|
|
2765
|
+
struct leptris_xpath_result* arg = vm_pop(&vm);
|
|
2766
|
+
if (!arg) { vm.error = 1; break; }
|
|
2767
|
+
char* s = xpath_to_string(arg);
|
|
2768
|
+
xpath_result_free(arg);
|
|
2769
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_STRING);
|
|
2770
|
+
if (!r) { free(s); vm.error = 1; break; }
|
|
2771
|
+
r->value.string_value = s ? s : leptris_strdup("");
|
|
2772
|
+
if (!r->value.string_value) {
|
|
2773
|
+
free(s);
|
|
2774
|
+
xpath_result_free(r);
|
|
2775
|
+
vm.error = 1;
|
|
2776
|
+
break;
|
|
2777
|
+
}
|
|
2778
|
+
vm_push(&vm, r);
|
|
2779
|
+
break;
|
|
2780
|
+
}
|
|
2781
|
+
|
|
2782
|
+
case XPATH_BC_FUNC_NAME:
|
|
2783
|
+
case XPATH_BC_FUNC_LOCAL_NAME:
|
|
2784
|
+
case XPATH_BC_FUNC_NAMESPACE_URI: {
|
|
2785
|
+
struct leptris_xpath_result* arg = vm_pop(&vm);
|
|
2786
|
+
if (!arg) { vm.error = 1; break; }
|
|
2787
|
+
|
|
2788
|
+
const char* str = NULL;
|
|
2789
|
+
int free_str = 0;
|
|
2790
|
+
if (arg->type == XPATH_RESULT_NODESET &&
|
|
2791
|
+
arg->value.nodeset_value &&
|
|
2792
|
+
arg->value.nodeset_value->count > 0) {
|
|
2793
|
+
void* first = arg->value.nodeset_value->nodes[0];
|
|
2794
|
+
LeptrisNodeType nt = *(LeptrisNodeType*)first;
|
|
2795
|
+
if (nt == LEPTRIS_NODE_ATTRIBUTE) {
|
|
2796
|
+
LeptrisAttributeNode* an = (LeptrisAttributeNode*)first;
|
|
2797
|
+
if (op == XPATH_BC_FUNC_NAME) str = an->name;
|
|
2798
|
+
else if (op == XPATH_BC_FUNC_LOCAL_NAME) {
|
|
2799
|
+
/* Strip prefix from "prefix:local". */
|
|
2800
|
+
const char* colon = an->name ? strchr(an->name, ':') : NULL;
|
|
2801
|
+
str = colon ? colon + 1 : an->name;
|
|
2802
|
+
} else {
|
|
2803
|
+
str = an->namespace_uri; /* may be NULL */
|
|
2804
|
+
}
|
|
2805
|
+
} else if (nt == LEPTRIS_NODE_ELEMENT) {
|
|
2806
|
+
/* Element. */
|
|
2807
|
+
LeptrisElement e = (LeptrisElement)first;
|
|
2808
|
+
if (op == XPATH_BC_FUNC_NAME) {
|
|
2809
|
+
str = leptris_element_get_name(e);
|
|
2810
|
+
} else if (op == XPATH_BC_FUNC_LOCAL_NAME) {
|
|
2811
|
+
str = leptris_element_get_name(e);
|
|
2812
|
+
} else {
|
|
2813
|
+
str = leptris_element_get_namespace_uri(e);
|
|
2814
|
+
}
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2817
|
+
|
|
2818
|
+
xpath_result_free(arg);
|
|
2819
|
+
|
|
2820
|
+
struct leptris_xpath_result* r = xpath_result_new(XPATH_RESULT_STRING);
|
|
2821
|
+
if (!r) { vm.error = 1; break; }
|
|
2822
|
+
r->value.string_value = leptris_strdup(str ? str : "");
|
|
2823
|
+
if (!r->value.string_value) {
|
|
2824
|
+
xpath_result_free(r);
|
|
2825
|
+
vm.error = 1;
|
|
2826
|
+
break;
|
|
2827
|
+
}
|
|
2828
|
+
vm_push(&vm, r);
|
|
2829
|
+
(void)free_str;
|
|
2830
|
+
break;
|
|
2831
|
+
}
|
|
2832
|
+
|
|
2833
|
+
case XPATH_BC_FALLBACK_EVAL: {
|
|
2834
|
+
uint16_t idx = read_u16(&pc);
|
|
2835
|
+
if (idx >= bc->const_count ||
|
|
2836
|
+
bc->constants[idx].type != XPATH_CONST_AST_NODE) {
|
|
2837
|
+
vm.error = 1;
|
|
2838
|
+
break;
|
|
2839
|
+
}
|
|
2840
|
+
XPathASTNode* ast_node = bc->constants[idx].v.ast;
|
|
2841
|
+
struct leptris_xpath_result* r = evaluate_expr(ctx, ast_node);
|
|
2842
|
+
if (!r) { vm.error = 1; break; }
|
|
2843
|
+
vm_push(&vm, r);
|
|
2844
|
+
break;
|
|
2845
|
+
}
|
|
2846
|
+
|
|
2847
|
+
case XPATH_BC_RETURN:
|
|
2848
|
+
goto done;
|
|
2849
|
+
|
|
2850
|
+
default:
|
|
2851
|
+
vm.error = 1;
|
|
2852
|
+
goto done;
|
|
2853
|
+
}
|
|
2854
|
+
}
|
|
2855
|
+
|
|
2856
|
+
done:
|
|
2857
|
+
if (vm.error || vm.sp == 0) {
|
|
2858
|
+
while (vm.sp > 0) {
|
|
2859
|
+
struct leptris_xpath_result* r = vm_pop(&vm);
|
|
2860
|
+
if (r) xpath_result_free(r);
|
|
2861
|
+
}
|
|
2862
|
+
free(vm.stack);
|
|
2863
|
+
return NULL;
|
|
2864
|
+
}
|
|
2865
|
+
|
|
2866
|
+
struct leptris_xpath_result* result = vm_pop(&vm);
|
|
2867
|
+
|
|
2868
|
+
while (vm.sp > 0) {
|
|
2869
|
+
struct leptris_xpath_result* extra = vm_pop(&vm);
|
|
2870
|
+
if (extra) xpath_result_free(extra);
|
|
2871
|
+
}
|
|
2872
|
+
free(vm.stack);
|
|
2873
|
+
return result;
|
|
2874
|
+
}
|
|
2875
|
+
|
|
2876
|
+
/* Public entry: compile AST → run VM. Returns NULL on failure.
|
|
2877
|
+
* Caller frees the result via leptris_xpath_result_free.
|
|
2878
|
+
*
|
|
2879
|
+
* Callers should prefer the cached path
|
|
2880
|
+
* (xpath_expr_cache_get_or_compile_bc + vm_run_with_bc) so the
|
|
2881
|
+
* compile cost is amortized across many evals of the same
|
|
2882
|
+
* expression. This entry point is retained for tests and for
|
|
2883
|
+
* one-off evals that bypass the cache. */
|
|
2884
|
+
struct leptris_xpath_result* leptris_xpath_vm_eval(XPathASTNode* ast,
|
|
2885
|
+
XPathContext* ctx) {
|
|
2886
|
+
if (!ast || !ctx) return NULL;
|
|
2887
|
+
|
|
2888
|
+
LeptrisXPathBytecode* bc = leptris_xpath_compile_ast(ast);
|
|
2889
|
+
if (!bc) return NULL;
|
|
2890
|
+
|
|
2891
|
+
struct leptris_xpath_result* result = vm_run(bc, ctx);
|
|
2892
|
+
|
|
2893
|
+
leptris_xpath_bytecode_free(bc);
|
|
2894
|
+
return result;
|
|
2895
|
+
}
|
|
2896
|
+
|
|
2897
|
+
/* Cached entry: run an already-compiled bytecode. Used by
|
|
2898
|
+
* leptris_xpath_eval when the expression cache has a compiled bc. */
|
|
2899
|
+
struct leptris_xpath_result* leptris_xpath_vm_run_bc(LeptrisXPathBytecode* bc,
|
|
2900
|
+
XPathContext* ctx) {
|
|
2901
|
+
if (!bc || !ctx) return NULL;
|
|
2902
|
+
return vm_run(bc, ctx);
|
|
2903
|
+
}
|